You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
59 lines
2.0 KiB
Racket
59 lines
2.0 KiB
Racket
#lang debug racket
|
|
(require sugar/unstable/dict
|
|
(for-syntax racket/syntax))
|
|
(provide (all-defined-out))
|
|
|
|
#|
|
|
approximates
|
|
https://github.com/mbutterick/fontkit/blob/master/src/glyph/Path.js
|
|
|#
|
|
|
|
#|
|
|
/**
|
|
* Path objects are returned by glyphs and represent the actual
|
|
* vector outlines for each glyph in the font. Paths can be converted
|
|
* to SVG path data strings, or to functions that can be applied to
|
|
* render the path to a graphics context.
|
|
*/
|
|
|#
|
|
|
|
(struct Path$ (commands _bbox _cbox) #:transparent #:mutable)
|
|
|
|
(define (Path [commands null] [_bbox #false] [_cbox #false])
|
|
(Path$ commands _bbox _cbox))
|
|
|
|
(define SVG_COMMANDS (hasheq 'moveTo "M"
|
|
'lineTo "L"
|
|
'quadraticCurveTo "Q"
|
|
'bezierCurveTo "C"
|
|
'closePath "Z"))
|
|
|
|
(define (toSVG this)
|
|
(define cmds (for/list ([c (in-list (Path$-commands this))])
|
|
(define args (for/list ([arg (in-list (dict-ref c 'args))])
|
|
(round (/ (* arg 100) 100))))
|
|
(format "~a~a" (hash-ref SVG_COMMANDS (dict-ref c 'command))
|
|
(string-join (map ~a args) " "))))
|
|
(string-join cmds ""))
|
|
|
|
(define-syntax (define-command stx)
|
|
(syntax-case stx ()
|
|
[(_ COMMAND)
|
|
(with-syntax [(ID (format-id #'COMMAND (format "path-~a" (syntax-e #'COMMAND))))]
|
|
#'(define (ID this . args)
|
|
(set-Path$-_bbox! this #false)
|
|
(set-Path$-_cbox! this #false)
|
|
(set-Path$-commands! this
|
|
(append
|
|
(Path$-commands this)
|
|
(list
|
|
(dictify
|
|
'command 'COMMAND
|
|
'args args))))
|
|
this))]))
|
|
|
|
(define-command moveTo)
|
|
(define-command lineTo)
|
|
(define-command quadraticCurveTo)
|
|
(define-command bezierCurveTo)
|
|
(define-command closePath) |