~alcinnz/fontconfig-pure

67bb6d072c5754ffde9298cbd262273eb7fd4051 — Adrian Cochrane 2 years ago 0b9da36
Parse unicode-range property for @font-face.
2 files changed, 31 insertions(+), 3 deletions(-)

M Graphics/Text/Font/Choose/CharSet.hs
M Graphics/Text/Font/Choose/FontSet.hs
M Graphics/Text/Font/Choose/CharSet.hs => Graphics/Text/Font/Choose/CharSet.hs +25 -2
@@ 1,6 1,6 @@
module Graphics.Text.Font.Choose.CharSet where

import Data.Set (Set)
import Data.Set (Set, union)
import qualified Data.Set as Set
import Graphics.Text.Font.Choose.Result (throwNull, throwFalse)



@@ 10,10 10,33 @@ import Control.Exception (bracket)
import Control.Monad (forM)
import Foreign.Marshal.Alloc (alloca, allocaBytes)
import GHC.Base (unsafeChr)
import Data.Char (ord)
import Data.Char (ord, isHexDigit)
import Numeric (readHex)

type CharSet = Set Char

parseChar :: String -> Char
parseChar str | ((x, _):_) <- readHex str = toEnum x
replaceWild ch ('?':rest) = ch:replaceWild ch rest
replaceWild ch (c:cs) = c:replaceWild ch cs
replaceWild _ "" = ""
parseWild ch str = parseChar $ replaceWild ch str
parseCharSet ('U':rest) = parseCharSet ('u':rest) -- lowercase initial "u"
parseCharSet ('u':'+':cs)
    | (start@(_:_), '-':ends) <- span isHexDigit cs,
        (end@(_:_), rest) <- span isHexDigit ends, Just set <- parseCharSet' rest =
            Just $ Set.union set $ Set.fromList [parseChar start..parseChar end]
    | (codepoint@(_:_), rest) <- span isHexDigit cs, Just set <- parseCharSet' rest =
        Just $ flip Set.insert set $ parseChar codepoint
    | (codepoint@(_:_), rest) <- span (\c -> isHexDigit c || c == '?') cs,
        Just set <- parseCharSet' rest =
            Just $ Set.union set $ Set.fromList [
                parseWild '0' codepoint..parseWild 'f' codepoint]
parseCharSet _ = Nothing
parseCharSet' (',':rest) = parseCharSet rest
parseCharSet' "" = Just Set.empty
parseCharSet' _ = Nothing

------
--- Low-level
------

M Graphics/Text/Font/Choose/FontSet.hs => Graphics/Text/Font/Choose/FontSet.hs +6 -1
@@ 13,9 13,10 @@ import Control.Exception (bracket)

-- For CSS bindings
import Stylist.Parse (StyleSheet(..), parseProperties)
import Data.CSS.Syntax.Tokens (Token(..))
import Data.CSS.Syntax.Tokens (Token(..), serialize)
import Data.Text (unpack, Text)
import Graphics.Text.Font.Choose.Range (iRange)
import Graphics.Text.Font.Choose.CharSet (parseCharSet)
import Data.List (intercalate)

type FontSet = [Pattern]


@@ 97,6 98,10 @@ properties2font (("font-variation-settings", toks):props)
    | (_, True, []) <- parseFontVars toks =
        setValue "variable" Strong True $ properties2font props

properties2font (("unicode-range", toks):props)
    | Just chars <- parseCharSet $ unpack $ serialize toks =
        setValue "charset" Strong chars $ properties2font props

properties2font (_:props) = properties2font props
properties2font [] = []