Initial commit
This commit is contained in:
commit
ad67ab3f84
|
@ -0,0 +1,2 @@
|
||||||
|
/.envrc
|
||||||
|
/.direnv
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Package
|
||||||
|
|
||||||
|
version = "20230326"
|
||||||
|
author = "Emery Hemingway"
|
||||||
|
description = "Syndicate actor for asserting Fontconfig information"
|
||||||
|
license = "Unlicense"
|
||||||
|
srcDir = "src"
|
||||||
|
bin = @["fontconfig_actor"]
|
||||||
|
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
requires "nim >= 1.6.10"
|
|
@ -0,0 +1,3 @@
|
||||||
|
version 1 .
|
||||||
|
Serve = <serve @cap #!any> .
|
||||||
|
FontAssertion = <fontconfig @properties {symbol: any ...:...} @file string @index int> .
|
|
@ -0,0 +1,3 @@
|
||||||
|
include_rules
|
||||||
|
: foreach ../*.prs |> !preserves_schema_nim |> {schema}
|
||||||
|
: fontconfig_actor.nim | {schema} $(SYNDICATE_PROTOCOL) |> !nim_bin |>
|
|
@ -0,0 +1,112 @@
|
||||||
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
|
import std/[asyncdispatch, os, osproc, strutils]
|
||||||
|
import preserves, syndicate, syndicate/[patterns]
|
||||||
|
import ./protocol
|
||||||
|
|
||||||
|
{.passC: staticExec("pkg-config --cflags fontconfig").}
|
||||||
|
{.passL: staticExec("pkg-config --libs fontconfig").}
|
||||||
|
|
||||||
|
{.pragma: fcHeader, header: "<fontconfig/fontconfig.h>".}
|
||||||
|
{.pragma: importFc, fcHeader, importc: "Fc$1".}
|
||||||
|
|
||||||
|
const
|
||||||
|
FcFalse = cint 0
|
||||||
|
|
||||||
|
FC_FAMILY = "family"
|
||||||
|
FC_STYLE = "style"
|
||||||
|
FC_WEIGHT = "weight"
|
||||||
|
FC_SIZE = "size"
|
||||||
|
FC_FILE = "file"
|
||||||
|
|
||||||
|
type
|
||||||
|
FcChar8* = uint8
|
||||||
|
FcBool* = cint
|
||||||
|
|
||||||
|
FcResult {.importc.} = enum
|
||||||
|
FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId,
|
||||||
|
FcResultOutOfMemory
|
||||||
|
|
||||||
|
FcPattern = distinct pointer
|
||||||
|
|
||||||
|
FcConfig = distinct pointer
|
||||||
|
|
||||||
|
proc Init(): FcBool {.importFc.} ## Initialize fontconfig library
|
||||||
|
proc Fini() {.importFc.} ## Finalize fontconfig library.
|
||||||
|
|
||||||
|
proc PatternCreate(): FcPattern {.importFc.}
|
||||||
|
proc PatternDestroy(p: FcPattern) {.importFc.}
|
||||||
|
|
||||||
|
proc PatternAddInteger(p: FcPattern; obj: cstring; i: cint): FcBool {.importFc.}
|
||||||
|
proc PatternAddDouble(p: FcPattern; obj: cstring; d: cdouble): FcBool {.importFc.}
|
||||||
|
proc PatternAddString(p: FcPattern; obj, s: cstring): FcBool {.importFc.}
|
||||||
|
proc DefaultSubstitute(p: FcPattern) {.importFc.}
|
||||||
|
proc PatternPrint(p: FcPattern) {.importFc.}
|
||||||
|
|
||||||
|
proc FontMatch(cfg: FcConfig; p: FcPattern; r: var FcResult): FcPattern {.importFc.}
|
||||||
|
|
||||||
|
proc PatternGetString(p: FcPattern; obj: cstring; n: cint;
|
||||||
|
s: ptr cstring): FcResult {.importFc.}
|
||||||
|
|
||||||
|
proc findSystemTypeface*(family = ""; style = ""; weight = 0; size = 0.0): string =
|
||||||
|
## Find a path to an appropriate system typeface for the given parameters.
|
||||||
|
## This proc always returns a path to a typeface file, results may vary.
|
||||||
|
# TODO: only return font in supported formats
|
||||||
|
if Init() == FcFalse:
|
||||||
|
raise newException(IOError, "Failed to initialize FontConfig")
|
||||||
|
|
||||||
|
var pat = PatternCreate()
|
||||||
|
DefaultSubstitute(pat)
|
||||||
|
if family != "":
|
||||||
|
discard PatternAddString(pat, FC_FAMILY, family);
|
||||||
|
if style != "":
|
||||||
|
discard PatternAddString(pat, FC_STYLE, style);
|
||||||
|
if weight != 0:
|
||||||
|
discard PatternAddInteger(pat, FC_WEIGHT, cint weight);
|
||||||
|
if size != 0.0:
|
||||||
|
discard PatternAddDouble(pat, FC_SIZE, size);
|
||||||
|
|
||||||
|
var
|
||||||
|
res = FcResultNoMatch
|
||||||
|
font = FontMatch(nil, pat, res)
|
||||||
|
if res == FcResultMatch:
|
||||||
|
# PatternPrint(font);
|
||||||
|
var path: cstring
|
||||||
|
if PatternGetString(font, FC_FILE, 0, addr path) == FcResultMatch:
|
||||||
|
result = $path
|
||||||
|
PatternDestroy(font)
|
||||||
|
|
||||||
|
PatternDestroy(pat)
|
||||||
|
Fini()
|
||||||
|
if result == "":
|
||||||
|
raise newException(IOError, "Failed to find a system typeface")
|
||||||
|
|
||||||
|
proc serve(ds: Ref; turn: var Turn) =
|
||||||
|
let observation = ?Observe(pattern: !FontAssertion) ?? {0: grabDict()}
|
||||||
|
during(turn, ds, observation) do (properties: Assertion):
|
||||||
|
stderr.writeLine "looking for ", properties
|
||||||
|
|
||||||
|
#[
|
||||||
|
let propPat = { toSymbol("family", Ref) : ?"Foo" }.dictionaryPattern
|
||||||
|
let testPat = FontAssertion ? { 0: propPat, 1: grab(), 2: grab() }
|
||||||
|
|
||||||
|
onPublish(turn, ds, testPat) do (file: string, index: int):
|
||||||
|
stderr.writeLine "found file ", file, " with index ", index
|
||||||
|
|
||||||
|
during(turn, ds, Observe ? { 0: grab() }) do (pat: Assertion):
|
||||||
|
stderr.writeLine "observed request for ", pat
|
||||||
|
|
||||||
|
during(turn, ds, Observe ? { 0: ?(FontAssertion ? { 0: drop()}) }) do:
|
||||||
|
stderr.writeLine "fontconfig observe found! "
|
||||||
|
]#
|
||||||
|
|
||||||
|
|
||||||
|
bootDataspace("main") do (root: Ref; turn: var Turn):
|
||||||
|
connectStdio(root, turn)
|
||||||
|
if Init() == FcFalse:
|
||||||
|
quit"Failed to initialize FontConfig"
|
||||||
|
during(turn, root, ?Serve) do (ds: Ref):
|
||||||
|
serve(ds, turn)
|
||||||
|
|
||||||
|
runForever()
|
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
import
|
||||||
|
std/typetraits, preserves, std/tables
|
||||||
|
|
||||||
|
type
|
||||||
|
Serve* {.preservesRecord: "serve".} = object
|
||||||
|
`cap`* {.preservesEmbedded.}: Preserve[void]
|
||||||
|
|
||||||
|
FontAssertion* {.preservesRecord: "fontconfig".} = object
|
||||||
|
`properties`*: Table[Symbol, Preserve[void]]
|
||||||
|
`file`*: string
|
||||||
|
`index`*: BiggestInt
|
||||||
|
|
||||||
|
proc `$`*(x: Serve | FontAssertion): string =
|
||||||
|
`$`(toPreserve(x))
|
||||||
|
|
||||||
|
proc encode*(x: Serve | FontAssertion): seq[byte] =
|
||||||
|
encode(toPreserve(x))
|
Loading…
Reference in New Issue