Matthew Butterick 6 years ago
parent 8cb152742f
commit abbd3b654a

@ -298,10 +298,24 @@
-> (err : _FT_Error)
-> (if (zero? err) ftl (error 'FT_Init_FreeType))))
(define-freetype FT_Set_Char_Size (_fun
_FT_Face
_FT_F26Dot6
_FT_F26Dot6
_FT_UInt
_FT_UInt
-> (err : _FT_Error)))
(define-freetype FT_New_Face (_fun _FT_Library _full-path _FT_Long
(ftf : (_ptr o (_or-null _FT_Face)))
-> (err : _FT_Error)
-> (if (zero? err) ftf (error 'FT_New_Face (format "error ~a" err)))))
-> (cond
[(zero? err)
;; see https://www.freetype.org/freetype2/docs/tutorial/step1.html
(FT_Set_Char_Size ftf 0 1000 0 0)
ftf]
[(error 'FT_New_Face (format "error ~a" err))])))
(define-freetype FT_Done_Face (_fun _FT_Face
-> (err : _FT_Error)

@ -1,13 +1,11 @@
#lang racket/base
#lang racket/base
(require ffi/unsafe
ffi/unsafe/define
racket/draw/private/libs
"harfbuzz-helper.rkt"
racket/string racket/format)
(define harfbuzz-lib (ffi-lib "/usr/local/Cellar/harfbuzz/2.1.3/lib/libharfbuzz"))
#;(define-runtime-lib harfbuzz-lib
(define-runtime-lib harfbuzz-lib
[(unix) (ffi-lib "libharfbuzz" '("1" ""))]
[(macosx) (ffi-lib "libharfbuzz.0.dylib")]
[(windows) (ffi-lib "libharfbuzz-0.dll")])
@ -23,15 +21,16 @@
(define _char-pointer (_cpointer 'char-pointer))
(define _uchar _ubyte)
(define _hb_buffer_t _pointer)
(define _single_char_array (make-array-type _char 1))
(define-cstruct _hb_language_impl_t ([s _single_char_array]))
(define _one-char-array (make-array-type _char 1))
(define-cstruct _hb_language_impl_t
([s _one-char-array]))
(define _hb_language_t _hb_language_impl_t-pointer)
(define-harfbuzz hb_version (_fun (major : (_ptr o _uint))
(minor : (_ptr o _uint))
(micro : (_ptr o _uint))
-> _void
-> (string-join (map ~a (list major minor micro)) ".")))
-> (format "~a.~a.~a" major minor micro)))
(define-harfbuzz hb_buffer_create (_fun -> _hb_buffer_t))
@ -45,7 +44,8 @@
(define-harfbuzz hb_buffer_set_script (_fun _hb_buffer_t _hb_script_t -> _void))
(define-harfbuzz hb_buffer_get_script (_fun _hb_buffer_t -> _hb_script_t))
(define-harfbuzz hb_language_from_string (_fun _string _int -> _hb_language_t))
(define-harfbuzz hb_language_from_string (_fun _bytes _int -> _hb_language_t))
(define-harfbuzz hb_language_to_string (_fun _hb_language_t -> _bytes))
(define-harfbuzz hb_buffer_set_language (_fun _hb_buffer_t _hb_language_t -> _void))
(define-harfbuzz hb_buffer_get_language (_fun _hb_buffer_t -> _hb_language_t))
@ -57,7 +57,7 @@
(define _hb_tag_t _uint32)
(define-cstruct _hb_feature_t
([_tag _hb_tag_t]
([tag_ _hb_tag_t]
[value _uint32]
[start _uint]
[end _uint]))
@ -65,7 +65,6 @@
(define _hb_features_t (_or-null _hb_feature_t-pointer))
(define-harfbuzz hb_shape (_fun _hb_font_t _hb_buffer_t _hb_features_t _uint -> _void))
(define _hb_codepoint_t _uint32)
(define _hb_mask_t _uint32)
(define _hb_var_int_t _uint32) ; todo: union type at https://github.com/harfbuzz/harfbuzz/blob/04981ee05d83ed30c9f818106589a4de9c3e9b7f/src/hb-common.h#L96
@ -92,31 +91,34 @@
[var _hb_var_int_t]))
(define-harfbuzz hb_buffer_get_glyph_positions (_fun _hb_buffer_t
(length : (_ptr o _uint))
-> (res : _hb_glyph_position_t-pointer)
-> (ptr-ref res (_array/list _hb_glyph_position_t length) 0)))
(length : (_ptr o _uint))
-> (res : _hb_glyph_position_t-pointer)
-> (ptr-ref res (_array/list _hb_glyph_position_t length) 0)))
(define-harfbuzz hb_buffer_reset (_fun _hb_buffer_t -> _void))
(define-harfbuzz hb_buffer_destroy (_fun _hb_buffer_t -> _void))
(define-harfbuzz hb_font_destroy (_fun _hb_font_t -> _void))
(define ft-lib (FT_Init_FreeType))
(module+ test
(require rackunit)
;; Create a buffer and put your text in it.
(hb_version)
(define buf (hb_buffer_create))
(define text "Hello World")
(hb_buffer_add_utf8 buf text -1 0 -1)
;; Set the script, language and direction of the buffer.
(hb_buffer_set_direction buf 'HB_DIRECTION_LTR)
(hb_buffer_get_direction buf)
(check-true (eq? 'HB_DIRECTION_LTR (hb_buffer_get_direction buf)))
(hb_buffer_set_script buf 'HB_SCRIPT_LATIN)
(hb_buffer_get_script buf)
(hb_buffer_set_language buf (hb_language_from_string #"en" -1))
(check-true (eq? 'HB_SCRIPT_LATIN (hb_buffer_get_script buf)))
(define buf-lang (hb_language_from_string #"en" -1))
(hb_buffer_set_language buf buf-lang)
(check-equal? #"en" (hb_language_to_string (hb_buffer_get_language buf)))
;; Create a face and a font, using FreeType for now.
(define ft-library (FT_Init_FreeType))
(define face (FT_New_Face ft-library "fira.ttf" 0))
(define face (FT_New_Face ft-lib "fira.ttf" 0))
(define font (hb_ft_font_create face #f))
;; Shape!
@ -124,12 +126,39 @@
;; Get the glyph and position information.
(define glyph_infos (hb_buffer_get_glyph_infos buf))
(map hb_glyph_info_t->list glyph_infos)
(check-equal? (map hb_glyph_info_t-codepoint glyph_infos) '(111 412 514 514 555 3 296 555 609 514 393))
(define glyph_positions (hb_buffer_get_glyph_positions buf))
(map hb_glyph_position_t->list glyph_positions) ; todo: fix glyph positions
(check-equal? (map hb_glyph_position_t-x_advance glyph_positions) '(678 547 291 281 581 268 792 581 383 281 595))
;; Tidy up.
(hb_buffer_destroy buf)
(hb_font_destroy font))
(hb_font_destroy font))
(define (make-font path-string)
(define face (FT_New_Face ft-lib path-string 0))
(hb_ft_font_create face #f))
(define (shape font text)
(define buf (hb_buffer_create))
(hb_buffer_set_direction buf 'HB_DIRECTION_LTR)
(hb_buffer_set_script buf 'HB_SCRIPT_LATIN)
(define buf-lang (hb_language_from_string #"en" -1))
(hb_buffer_set_language buf buf-lang)
(hb_buffer_add_utf8 buf text -1 0 -1)
(hb_shape font buf #f 0)
(begin0
(list (map hb_glyph_info_t-codepoint (hb_buffer_get_glyph_infos buf))
(map hb_glyph_position_t-x_advance (hb_buffer_get_glyph_positions buf)))
(hb_buffer_destroy buf)))
(define (random-string len)
(define chars (map integer->char (range 65 91)))
(list->string (for/list ([i (in-range len)])
(list-ref chars (random (length chars))))))
(define f (make-font "charter.ttf"))
(require sugar/debug racket/list)
(shape f (random-string 10))

Loading…
Cancel
Save