ui.text.freetype: update for ui.text API changes

db4
Slava Pestov 2009-02-09 18:07:33 -06:00
parent 954596c947
commit 6667aa1238
1 changed files with 58 additions and 47 deletions

View File

@ -5,24 +5,17 @@ math math.vectors namespaces opengl opengl.gl opengl.sprites assocs
sequences io.files continuations freetype sequences io.files continuations freetype
ui.gadgets.worlds ui.text ui.text.private ui.backend ui.gadgets.worlds ui.text ui.text.private ui.backend
byte-arrays accessors locals specialized-arrays.direct.uchar byte-arrays accessors locals specialized-arrays.direct.uchar
combinators.smart ; combinators.smart fonts memoize ;
IN: ui.text.freetype IN: ui.text.freetype
SINGLETON: freetype-renderer SINGLETON: freetype-renderer
SYMBOL: open-fonts M: freetype-renderer finish-text-rendering drop ;
: freetype-error ( n -- ) : freetype-error ( n -- )
zero? [ "FreeType error" throw ] unless ; 0 = [ "FreeType error" throw ] unless ;
DEFER: freetype DEFER: init-freetype
: init-freetype ( -- )
global [
f <void*> dup FT_Init_FreeType freetype-error
*void* \ freetype set
H{ } clone open-fonts set
] bind ;
: freetype ( -- alien ) : freetype ( -- alien )
\ freetype get-global expired? [ init-freetype ] when \ freetype get-global expired? [ init-freetype ] when
@ -33,16 +26,8 @@ ascent descent height handle widths ;
M: freetype-font hashcode* drop freetype-font hashcode* ; M: freetype-font hashcode* drop freetype-font hashcode* ;
: close-font ( font -- ) handle>> FT_Done_Face ;
: close-freetype ( -- )
global [
open-fonts [ [ drop close-font ] assoc-each f ] change
freetype [ FT_Done_FreeType f ] change
] bind ;
M: freetype-renderer free-fonts ( world -- ) M: freetype-renderer free-fonts ( world -- )
values [ second free-sprites ] each ; values [ free-sprites ] each ;
: ttf-name ( font -- name ) : ttf-name ( font -- name )
[ [ name>> ] [ bold?>> ] [ italic?>> ] tri ] output>array H{ [ [ name>> ] [ bold?>> ] [ italic?>> ] tri ] output>array H{
@ -58,21 +43,20 @@ M: freetype-renderer free-fonts ( world -- )
{ { "serif" t f } "VeraSeBd" } { { "serif" t f } "VeraSeBd" }
{ { "serif" t t } "VeraBI" } { { "serif" t t } "VeraBI" }
{ { "serif" f t } "VeraIt" } { { "serif" f t } "VeraIt" }
} at ; } at [ "No such font" throw ] unless* ;
: ttf-path ( name -- string ) : ttf-path ( name -- string )
"resource:fonts/" ".ttf" surround ; "resource:fonts/" ".ttf" surround ;
: (open-face) ( path length -- face ) MEMO: ttf-font ( font -- contents length )
ttf-name ttf-path malloc-file-contents ;
: open-face ( font -- face )
#! We use FT_New_Memory_Face, not FT_New_Face, since #! We use FT_New_Memory_Face, not FT_New_Face, since
#! FT_New_Face only takes an ASCII path name and causes #! FT_New_Face only takes an ASCII path name and causes
#! problems on localized versions of Windows #! problems on localized versions of Windows
[ freetype ] 2dip 0 f <void*> [ [ freetype ] dip ttf-font 0 f <void*>
FT_New_Memory_Face freetype-error [ FT_New_Memory_Face freetype-error ] keep *void* ;
] keep *void* ;
: open-face ( font -- face )
ttf-name ttf-path malloc-file-contents (open-face) ;
SYMBOL: dpi SYMBOL: dpi
@ -100,24 +84,25 @@ SYMBOL: dpi
[ dup handle>> 0 ] dip [ dup handle>> 0 ] dip
6 shift dpi get-global dup FT_Set_Char_Size freetype-error ; 6 shift dpi get-global dup FT_Set_Char_Size freetype-error ;
: <freetype-font> ( font -- open-font ) MEMO: (open-font) ( font -- open-font )
freetype-font new freetype-font new
H{ } clone >>widths H{ } clone >>widths
over open-face >>handle over open-face >>handle
swap size>> set-char-size swap size>> set-char-size
init-font ; init-font ;
: open-font ( font -- open-font ) GENERIC: open-font ( font -- open-font )
freetype drop open-fonts get [ <freetype-font> ] cache ;
M: font open-font
clone f >>background f >>foreground (open-font) ;
: load-glyph ( font char -- glyph ) : load-glyph ( font char -- glyph )
[ handle>> dup ] dip 0 FT_Load_Char [ handle>> dup ] dip 0 FT_Load_Char
freetype-error face-glyph ; freetype-error face-glyph ;
: char-width ( open-font char -- w ) : char-width ( open-font char -- w )
over widths>> [ swap [ widths>> ] keep
dupd load-glyph glyph-hori-advance ft-ceil [ swap load-glyph glyph-hori-advance ft-ceil ] curry cache ;
] cache nip ;
M: freetype-renderer string-width ( font string -- w ) M: freetype-renderer string-width ( font string -- w )
[ [ 0 ] dip open-font ] dip [ char-width + ] with each ; [ [ 0 ] dip open-font ] dip [ char-width + ] with each ;
@ -195,26 +180,39 @@ M: freetype-renderer string-height ( font string -- h )
: char-widths ( open-font string -- widths ) : char-widths ( open-font string -- widths )
[ char-width ] with { } map-as ; [ char-width ] with { } map-as ;
: scan-sums ( seq -- seq' ) : sums ( seq -- seq )
0 [ + ] accumulate nip ; 0 [ + ] accumulate nip ;
:: (draw-string) ( open-font sprites string loc -- ) : font-sprites ( font world -- sprites )
fonts>> [ drop H{ } clone ] cache ;
: draw-background ( widths open-font -- )
[ sum ] [ height>> ] bi* 2array gl-fill-rect ;
:: draw-selection ( widths open-font line -- )
line color>> gl-color
widths line start>> head-slice sum 0 2array [
line [ start>> ] [ end>> ] bi widths <slice> sum
open-font height>> 2array gl-fill-rect
] with-translation ;
M:: freetype-renderer draw-string ( font line loc -- )
line dup selection? [ string>> ] when :> string
font open-font :> open-font
open-font world get font-sprites :> sprites
open-font string char-widths :> widths
GL_TEXTURE_2D [ GL_TEXTURE_2D [
loc [ loc [
string open-font string char-widths scan-sums [ font background>> gl-color
[ open-font sprites ] 2dip draw-char widths open-font draw-background
] 2each line selection? [ widths open-font line draw-selection ] when
font foreground>> gl-color
string widths sums [ [ open-font sprites ] 2dip draw-char ] 2each
] with-translation ] with-translation
] do-enabled ; ] do-enabled ;
: font-sprites ( font world -- open-font sprites )
fonts>> [ open-font H{ } clone 2array ] cache first2 ;
M: freetype-renderer draw-string ( font string loc -- )
[ world get font-sprites ] 2dip (draw-string) ;
: run-char-widths ( open-font string -- widths ) : run-char-widths ( open-font string -- widths )
char-widths [ scan-sums ] [ 2 v/n ] bi v+ ; char-widths [ sums ] [ 2 v/n ] bi v+ ;
M: freetype-renderer x>offset ( x font string -- n ) M: freetype-renderer x>offset ( x font string -- n )
[ open-font ] dip [ open-font ] dip
@ -222,6 +220,19 @@ M: freetype-renderer x>offset ( x font string -- n )
[ ] [ length ] ?if ; [ ] [ length ] ?if ;
M:: freetype-renderer offset>x ( n font string -- x ) M:: freetype-renderer offset>x ( n font string -- x )
font open-font string n head string-width ; font string n head-slice string-width ;
M: freetype-renderer line-metrics ( font string -- metrics )
[ string-width ]
[ drop open-font [ ascent>> ft-ceil ] [ descent>> ft-ceil ] bi 0 ] 2bi
metrics boa ;
: init-freetype ( -- )
global [
f <void*> dup FT_Init_FreeType freetype-error
*void* \ freetype set
\ (open-font) reset-memoized
\ ttf-font reset-memoized
] bind ;
freetype-renderer font-renderer set-global freetype-renderer font-renderer set-global