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 [] = []