next: finish harfbuzz ffi

main
Matthew Butterick 6 years ago
parent eeb2331003
commit 4a00297dae

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -202,7 +202,7 @@
(define _FT_Face _FT_FaceRec-pointer)
(provide (struct-out FT_FaceRec)
_FT_FaceRec _FT_FaceRec-pointer)
_FT_FaceRec _FT_FaceRec-pointer _FT_Face)
(define _FT_Sfnt_Tag _FT_ULong)
@ -376,7 +376,7 @@
(module+ test
(require rackunit)
(define ft-library (FT_Init_FreeType))
(define face (FT_New_Face ft-library "../pitfall/test/assets/Charter.ttf" 0))
(define face (FT_New_Face ft-library "charter.ttf" 0))
(check-equal? (FT_Get_Postscript_Name face) "Charter")
(check-equal? (FT_FaceRec-units_per_EM face) 1000)
(check-true (FT_Load_Sfnt_Table face (tag->int #"cmap") 0 0 0))

@ -0,0 +1,124 @@
#lang racket/base
(require ffi/unsafe
ffi/unsafe/define
racket/draw/private/libs
"harfbuzz-helper.rkt")
(define-runtime-lib harfbuzz-lib
[(unix) (ffi-lib "libharfbuzz" '("1" ""))]
[(macosx) (ffi-lib "libharfbuzz.0.dylib")]
[(windows) (ffi-lib "libharfbuzz-0.dll")])
(define-ffi-definer define-harfbuzz harfbuzz-lib #:provide provide)
;; simple example
;; https://harfbuzz.github.io/ch03s03.html
;; types
(define _void-pointer (_cpointer 'void-pointer))
(define _char _byte)
(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 _hb_language_t _hb_language_impl_t-pointer)
(define-harfbuzz hb_buffer_create (_fun -> _hb_buffer_t))
(define-harfbuzz hb_buffer_add_utf8 (_fun _hb_buffer_t _string/utf-8 _int _uint _int -> _void))
(define _hb_direction_t (_enum hb-direction-values))
(define-harfbuzz hb_buffer_set_direction (_fun _hb_buffer_t _hb_direction_t -> _void))
(define-harfbuzz hb_buffer_get_direction (_fun _hb_buffer_t -> _hb_direction_t))
(define _hb_script_t (_enum hb-script-values))
(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_buffer_set_language (_fun _hb_buffer_t _hb_language_t -> _void))
(define-harfbuzz hb_buffer_get_language (_fun _hb_buffer_t -> _hb_language_t))
(require "freetype-ffi.rkt")
(define _hb_font_t _pointer)
(define _hb_destroy_func_t (_or-null _pointer))
(define-harfbuzz hb_ft_font_create (_fun _FT_Face _hb_destroy_func_t -> _hb_font_t))
(define _hb_tag_t _uint32)
(define-cstruct _hb_feature_t
([_tag _hb_tag_t]
[value _uint32]
[start _uint]
[end _uint]))
(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
(define-cstruct _hb_glyph_info_t
([codepoint _hb_codepoint_t]
[mask _hb_mask_t]
[cluster _uint32]
[var1 _hb_var_int_t]
[var2 _hb_var_int_t]))
(define-harfbuzz hb_buffer_get_glyph_infos (_fun _hb_buffer_t
(length : (_ptr o _uint))
-> (res : _hb_glyph_info_t-pointer)
-> (ptr-ref res (_array/list _hb_glyph_info_t length) 0)))
(define _hb_position_t _int32)
(define-cstruct _hb_glyph_position_t
([x_advance _hb_position_t]
[y_advance _hb_position_t]
[x_offset _hb_position_t]
[y_offset _hb_position_t]
[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)))
(define-harfbuzz hb_buffer_destroy (_fun _hb_buffer_t -> _void))
(define-harfbuzz hb_font_destroy (_fun _hb_font_t -> _void))
(module+ test
(require rackunit)
;; Create a buffer and put your text in it.
(define buf (hb_buffer_create))
(define text "Hello World")
(hb_buffer_add_utf8 buf text -1 0 -1)
;; Guess the script, language and direction of the buffer.
(hb_buffer_set_direction buf 'HB_DIRECTION_LTR)
(hb_buffer_set_script buf 'HB_SCRIPT_LATIN)
(hb_buffer_set_language buf (hb_language_from_string "en" -1))
;; 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 font (hb_ft_font_create face #f))
;; Shape!
(hb_shape font buf #f 0)
;; 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
;; Tidy up.
(hb_buffer_destroy buf)
(hb_font_destroy font)
)

@ -0,0 +1,163 @@
#lang racket/base
(provide (all-defined-out))
(define hb-direction-values
'(HB_DIRECTION_INVALID
HB_DIRECTION_LTR
HB_DIRECTION_RTL
HB_DIRECTION_TTB
HB_DIRECTION_BTT))
(define hb-script-values
'(HB_SCRIPT_COMMON
HB_SCRIPT_INHERITED
HB_SCRIPT_UNKNOWN
HB_SCRIPT_ARABIC
HB_SCRIPT_ARMENIAN
HB_SCRIPT_BENGALI
HB_SCRIPT_CYRILLIC
HB_SCRIPT_DEVANAGARI
HB_SCRIPT_GEORGIAN
HB_SCRIPT_GREEK
HB_SCRIPT_GUJARATI
HB_SCRIPT_GURMUKHI
HB_SCRIPT_HANGUL
HB_SCRIPT_HAN
HB_SCRIPT_HEBREW
HB_SCRIPT_HIRAGANA
HB_SCRIPT_KANNADA
HB_SCRIPT_KATAKANA
HB_SCRIPT_LAO
HB_SCRIPT_LATIN
HB_SCRIPT_MALAYALAM
HB_SCRIPT_ORIYA
HB_SCRIPT_TAMIL
HB_SCRIPT_TELUGU
HB_SCRIPT_THAI
HB_SCRIPT_TIBETAN
HB_SCRIPT_BOPOMOFO
HB_SCRIPT_BRAILLE
HB_SCRIPT_CANADIAN_SYLLABICS
HB_SCRIPT_CHEROKEE
HB_SCRIPT_ETHIOPIC
HB_SCRIPT_KHMER
HB_SCRIPT_MONGOLIAN
HB_SCRIPT_MYANMAR
HB_SCRIPT_OGHAM
HB_SCRIPT_RUNIC
HB_SCRIPT_SINHALA
HB_SCRIPT_SYRIAC
HB_SCRIPT_THAANA
HB_SCRIPT_YI
HB_SCRIPT_DESERET
HB_SCRIPT_GOTHIC
HB_SCRIPT_OLD_ITALIC
HB_SCRIPT_BUHID
HB_SCRIPT_HANUNOO
HB_SCRIPT_TAGALOG
HB_SCRIPT_TAGBANWA
HB_SCRIPT_CYPRIOT
HB_SCRIPT_LIMBU
HB_SCRIPT_LINEAR_B
HB_SCRIPT_OSMANYA
HB_SCRIPT_SHAVIAN
HB_SCRIPT_TAI_LE
HB_SCRIPT_UGARITIC
HB_SCRIPT_BUGINESE
HB_SCRIPT_COPTIC
HB_SCRIPT_GLAGOLITIC
HB_SCRIPT_KHAROSHTHI
HB_SCRIPT_NEW_TAI_LUE
HB_SCRIPT_OLD_PERSIAN
HB_SCRIPT_SYLOTI_NAGRI
HB_SCRIPT_TIFINAGH
HB_SCRIPT_BALINESE
HB_SCRIPT_CUNEIFORM
HB_SCRIPT_NKO
HB_SCRIPT_PHAGS_PA
HB_SCRIPT_PHOENICIAN
HB_SCRIPT_CARIAN
HB_SCRIPT_CHAM
HB_SCRIPT_KAYAH_LI
HB_SCRIPT_LEPCHA
HB_SCRIPT_LYCIAN
HB_SCRIPT_LYDIAN
HB_SCRIPT_OL_CHIKI
HB_SCRIPT_REJANG
HB_SCRIPT_SAURASHTRA
HB_SCRIPT_SUNDANESE
HB_SCRIPT_VAI
HB_SCRIPT_AVESTAN
HB_SCRIPT_BAMUM
HB_SCRIPT_EGYPTIAN_HIEROGLYPHS
HB_SCRIPT_IMPERIAL_ARAMAIC
HB_SCRIPT_INSCRIPTIONAL_PAHLAVI
HB_SCRIPT_INSCRIPTIONAL_PARTHIAN
HB_SCRIPT_JAVANESE
HB_SCRIPT_KAITHI
HB_SCRIPT_LISU
HB_SCRIPT_MEETEI_MAYEK
HB_SCRIPT_OLD_SOUTH_ARABIAN
HB_SCRIPT_OLD_TURKIC
HB_SCRIPT_SAMARITAN
HB_SCRIPT_TAI_THAM
HB_SCRIPT_TAI_VIET
HB_SCRIPT_BATAK
HB_SCRIPT_BRAHMI
HB_SCRIPT_MANDAIC
HB_SCRIPT_CHAKMA
HB_SCRIPT_MEROITIC_CURSIVE
HB_SCRIPT_MEROITIC_HIEROGLYPHS
HB_SCRIPT_MIAO
HB_SCRIPT_SHARADA
HB_SCRIPT_SORA_SOMPENG
HB_SCRIPT_TAKRI
HB_SCRIPT_BASSA_VAH
HB_SCRIPT_CAUCASIAN_ALBANIAN
HB_SCRIPT_DUPLOYAN
HB_SCRIPT_ELBASAN
HB_SCRIPT_GRANTHA
HB_SCRIPT_KHOJKI
HB_SCRIPT_KHUDAWADI
HB_SCRIPT_LINEAR_A
HB_SCRIPT_MAHAJANI
HB_SCRIPT_MANICHAEAN
HB_SCRIPT_MENDE_KIKAKUI
HB_SCRIPT_MODI
HB_SCRIPT_MRO
HB_SCRIPT_NABATAEAN
HB_SCRIPT_OLD_NORTH_ARABIAN
HB_SCRIPT_OLD_PERMIC
HB_SCRIPT_PAHAWH_HMONG
HB_SCRIPT_PALMYRENE
HB_SCRIPT_PAU_CIN_HAU
HB_SCRIPT_PSALTER_PAHLAVI
HB_SCRIPT_SIDDHAM
HB_SCRIPT_TIRHUTA
HB_SCRIPT_WARANG_CITI
HB_SCRIPT_AHOM
HB_SCRIPT_ANATOLIAN_HIEROGLYPHS
HB_SCRIPT_HATRAN
HB_SCRIPT_MULTANI
HB_SCRIPT_OLD_HUNGARIAN
HB_SCRIPT_SIGNWRITING
HB_SCRIPT_ADLAM
HB_SCRIPT_BHAIKSUKI
HB_SCRIPT_MARCHEN
HB_SCRIPT_OSAGE
HB_SCRIPT_TANGUT
HB_SCRIPT_NEWA
HB_SCRIPT_MASARAM_GONDI
HB_SCRIPT_NUSHU
HB_SCRIPT_SOYOMBO
HB_SCRIPT_ZANABAZAR_SQUARE
HB_SCRIPT_DOGRA
HB_SCRIPT_GUNJALA_GONDI
HB_SCRIPT_HANIFI_ROHINGYA
HB_SCRIPT_MAKASAR
HB_SCRIPT_MEDEFAIDRIN
HB_SCRIPT_OLD_SOGDIAN
HB_SCRIPT_SOGDIAN
HB_SCRIPT_INVALID
_HB_SCRIPT_MAX_VALUE
_HB_SCRIPT_MAX_VALUE_SIGNED))
Loading…
Cancel
Save