Sub-pixel font smoothing works with Core Text now

db4
Slava Pestov 2009-01-29 22:07:51 -06:00
parent fc360f5ced
commit cadaf71372
4 changed files with 100 additions and 51 deletions

View File

@ -1,7 +1,7 @@
! Copyright (C) 2009 Slava Pestov. ! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: alien.c-types alien.destructors alien.syntax USING: alien.c-types alien.destructors alien.syntax
destructors fry kernel math sequences libc colors destructors fry kernel math math.bitwise sequences libc colors
core-graphics.types core-foundation.utilities ; core-graphics.types core-foundation.utilities ;
IN: core-graphics IN: core-graphics
@ -25,6 +25,16 @@ kCGImageAlphaNoneSkipFirst ;
: kCGBitmapByteOrder16Big ( -- n ) 3 12 shift ; inline : kCGBitmapByteOrder16Big ( -- n ) 3 12 shift ; inline
: kCGBitmapByteOrder32Big ( -- n ) 4 12 shift ; inline : kCGBitmapByteOrder32Big ( -- n ) 4 12 shift ; inline
: kCGBitmapByteOrder16Host ( -- n )
little-endian?
kCGBitmapByteOrder16Little
kCGBitmapByteOrder16Big ? ; foldable
: kCGBitmapByteOrder32Host ( -- n )
little-endian?
kCGBitmapByteOrder32Little
kCGBitmapByteOrder32Big ? ; foldable
FUNCTION: CGColorRef CGColorCreateGenericRGB ( FUNCTION: CGColorRef CGColorCreateGenericRGB (
CGFloat red, CGFloat red,
CGFloat green, CGFloat green,
@ -79,21 +89,41 @@ FUNCTION: void CGContextSetTextPosition (
CGFloat y CGFloat y
) ; ) ;
FUNCTION: void CGContextFillRect (
CGContextRef c,
CGRect rect
) ;
FUNCTION: void CGContextSetShouldSmoothFonts (
CGContextRef c,
bool shouldSmoothFonts
) ;
FUNCTION: CGLError CGLSetParameter ( CGLContextObj ctx, CGLContextParameter pname, GLint* params ) ; FUNCTION: CGLError CGLSetParameter ( CGLContextObj ctx, CGLContextParameter pname, GLint* params ) ;
FUNCTION: void* CGBitmapContextGetData ( CGContextRef c ) ; FUNCTION: void* CGBitmapContextGetData ( CGContextRef c ) ;
<PRIVATE <PRIVATE
: bitmap-flags ( -- flags )
{ kCGImageAlphaPremultipliedFirst kCGBitmapByteOrder32Host } flags ;
: bitmap-size ( dim -- n )
product "uint" heap-size * ;
: malloc-bitmap-data ( dim -- alien )
bitmap-size malloc &free ;
: bitmap-color-space ( -- color-space )
CGColorSpaceCreateDeviceRGB &CGColorSpaceRelease ;
: <CGBitmapContext> ( dim -- context ) : <CGBitmapContext> ( dim -- context )
[ product "uint" malloc-array &free ] [ first2 8 ] [ first 4 * ] tri [ malloc-bitmap-data ] [ first2 8 ] [ first 4 * ] tri
CGColorSpaceCreateDeviceRGB &CGColorSpaceRelease bitmap-color-space bitmap-flags CGBitmapContextCreate
kCGImageAlphaPremultipliedLast CGBitmapContextCreate
[ "CGBitmapContextCreate failed" throw ] unless* ; [ "CGBitmapContextCreate failed" throw ] unless* ;
: bitmap-data ( bitmap dim -- data ) : bitmap-data ( bitmap dim -- data )
[ CGBitmapContextGetData ] [ CGBitmapContextGetData ] [ bitmap-size ] bi*
[ product "uint" heap-size * ] bi*
memory>byte-array ; memory>byte-array ;
PRIVATE> PRIVATE>

View File

@ -3,9 +3,9 @@
USING: arrays alien alien.c-types alien.syntax kernel USING: arrays alien alien.c-types alien.syntax kernel
destructors words parser accessors fry words hashtables destructors words parser accessors fry words hashtables
sequences memoize assocs math math.functions locals init sequences memoize assocs math math.functions locals init
namespaces colors core-foundation core-foundation.strings namespaces combinators colors core-foundation
core-foundation.attributed-strings core-foundation.utilities core-foundation.strings core-foundation.attributed-strings
core-graphics core-graphics.types ; core-foundation.utilities core-graphics core-graphics.types ;
IN: core-text IN: core-text
TYPEDEF: void* CTLineRef TYPEDEF: void* CTLineRef
@ -107,6 +107,8 @@ FUNCTION: CTFontRef CTFontCreateCopyWithSymbolicTraits (
CTLineCreateWithAttributedString CTLineCreateWithAttributedString
] with-destructors ; ] with-destructors ;
TUPLE: line font line bounds dim bitmap age refs disposed ;
TUPLE: typographic-bounds width ascent descent leading ; TUPLE: typographic-bounds width ascent descent leading ;
: line-typographic-bounds ( line -- typographic-bounds ) : line-typographic-bounds ( line -- typographic-bounds )
@ -114,27 +116,31 @@ TUPLE: typographic-bounds width ascent descent leading ;
[ CTLineGetTypographicBounds ] 3keep [ *CGFloat ] tri@ [ CTLineGetTypographicBounds ] 3keep [ *CGFloat ] tri@
typographic-bounds boa ; typographic-bounds boa ;
TUPLE: line string font line bounds dim bitmap age refs disposed ;
: bounds>dim ( bounds -- dim ) : bounds>dim ( bounds -- dim )
[ width>> ] [ [ ascent>> ] [ descent>> ] bi + ] bi [ width>> ] [ [ ascent>> ] [ descent>> ] bi + ] bi
[ ceiling >fixnum ] [ ceiling >fixnum ]
bi@ 2array ; bi@ 2array ;
:: draw-line ( line bounds context -- ) :: <line> ( string font foreground background -- line )
context 0.0 bounds descent>> CGContextSetTextPosition
line context CTLineDraw ;
: <line> ( string font -- line )
[ [
CFRetain |CFRelease [let* | font [ font CFRetain |CFRelease ]
2dup white <CTLine> |CFRelease line [ string font foreground <CTLine> |CFRelease ]
dup line-typographic-bounds bounds [ line line-typographic-bounds ]
dup bounds>dim 3dup [ draw-line ] with-bitmap-context dim [ bounds bounds>dim ] |
0 0 f line boa dim [
{
[ background >rgba-components CGContextSetRGBFillColor ]
[ 0 0 dim first2 <CGRect> CGContextFillRect ]
[ 0 bounds descent>> CGContextSetTextPosition ]
[ line swap CTLineDraw ]
} cleave
] with-bitmap-context
[ font line bounds dim ] dip 0 0 f
]
line boa
] with-destructors ; ] with-destructors ;
M: line dispose* line>> CFRelease ; M: line dispose* [ font>> CFRelease ] [ line>> CFRelease ] bi ;
: ref/unref-line ( line n -- ) : ref/unref-line ( line n -- )
'[ _ + ] change-refs 0 >>age drop ; '[ _ + ] change-refs 0 >>age drop ;
@ -145,9 +151,9 @@ M: line dispose* line>> CFRelease ;
SYMBOL: cached-lines SYMBOL: cached-lines
: cached-line ( string font -- line ) : cached-line ( string font -- line )
cached-lines get [ <line> ] 2cache ; black white 4array cached-lines get [ first4 <line> ] cache ;
CONSTANT: max-line-age 5 CONSTANT: max-line-age 10
: age ( obj -- ? ) : age ( obj -- ? )
[ 1+ ] change-age age>> max-line-age >= ; [ 1+ ] change-age age>> max-line-age >= ;

View File

@ -3,7 +3,7 @@
USING: assocs accessors alien core-graphics.types core-text kernel USING: assocs accessors alien core-graphics.types core-text kernel
hashtables namespaces sequences ui.gadgets.worlds ui.text hashtables namespaces sequences ui.gadgets.worlds ui.text
ui.text.private opengl opengl.gl destructors combinators core-foundation ui.text.private opengl opengl.gl destructors combinators core-foundation
core-foundation.strings memoize math math.vectors init ; core-foundation.strings memoize math math.vectors init colors ;
IN: ui.text.core-text IN: ui.text.core-text
SINGLETON: core-text-renderer SINGLETON: core-text-renderer
@ -48,42 +48,54 @@ M: core-text-renderer open-font
M: core-text-renderer string-dim M: core-text-renderer string-dim
[ " " string-dim { 0 1 } v* ] [ swap cached-line dim>> ] if-empty ; [ " " string-dim { 0 1 } v* ] [ swap cached-line dim>> ] if-empty ;
TUPLE: line-texture line texture age disposed ; TUPLE: rendered-line line texture display-list age disposed ;
: <line-texture> ( line -- texture ) : make-line-display-list ( rendered-line texture -- dlist )
#! Note: we only ref-line if make-texture succeeds GL_COMPILE [
GL_TEXTURE_2D [
GL_TEXTURE_BIT [
GL_TEXTURE_COORD_ARRAY [
white gl-color
GL_TEXTURE_2D swap glBindTexture
init-texture rect-texture-coords
dim>> fill-rect-vertices (gl-fill-rect)
GL_TEXTURE_2D 0 glBindTexture
] do-enabled-client-state
] do-attribs
] do-enabled
] make-dlist ;
: make-core-graphics-texture ( dim bitmap -- texture )
GL_BGRA_EXT GL_UNSIGNED_INT_8_8_8_8_REV make-texture ;
: <rendered-line> ( line -- texture )
#! Note: we only ref-line if make-texture and make-line-display-list
#! succeed
[ [
dup [ dim>> ] [ bitmap>> ] bi GL_RGBA make-texture dup [ dim>> ] [ bitmap>> ] bi make-core-graphics-texture
0 f \ line-texture boa 2dup make-line-display-list
0 f \ rendered-line boa
] keep ref-line ; ] keep ref-line ;
M: line-texture dispose* M: rendered-line dispose*
[ line>> unref-line ] [ line>> unref-line ]
[ texture>> delete-texture ] bi ; [ texture>> delete-texture ]
[ display-list>> delete-dlist ] tri ;
: line-texture ( string open-font -- texture ) : rendered-line ( string open-font -- line-display-list )
world get fonts>> [ cached-line <line-texture> ] 2cache 0 >>age ; world get fonts>> [ cached-line <rendered-line> ] 2cache 0 >>age ;
: age-line-textures ( world -- ) : age-rendered-lines ( world -- )
[ [ age ] age-assoc ] change-fonts drop ; [ [ age ] age-assoc ] change-fonts drop ;
M: core-text-renderer finish-text-rendering M: core-text-renderer finish-text-rendering
age-line-textures age-lines ; age-rendered-lines age-lines ;
: draw-line-texture ( line-texture -- )
GL_TEXTURE_2D [
GL_TEXTURE_BIT [
GL_TEXTURE_COORD_ARRAY [
GL_TEXTURE_2D over texture>> glBindTexture
init-texture rect-texture-coords
line>> dim>> fill-rect-vertices (gl-fill-rect)
GL_TEXTURE_2D 0 glBindTexture
] do-enabled-client-state
] do-attribs
] do-enabled ;
M: core-text-renderer draw-string ( font string loc -- ) M: core-text-renderer draw-string ( font string loc -- )
[ swap open-font line-texture draw-line-texture ] with-translation ; [
swap open-font rendered-line
display-list>> glCallList
] with-translation ;
M: core-text-renderer x>offset ( x font string -- n ) M: core-text-renderer x>offset ( x font string -- n )
[ 2drop 0 ] [ [ 2drop 0 ] [
@ -92,7 +104,8 @@ M: core-text-renderer x>offset ( x font string -- n )
] if-empty ; ] if-empty ;
M: core-text-renderer offset>x ( n font string -- x ) M: core-text-renderer offset>x ( n font string -- x )
swap open-font cached-line line>> swap f CTLineGetOffsetForStringIndex ; swap open-font cached-line line>> swap f
CTLineGetOffsetForStringIndex ;
M: core-text-renderer free-fonts ( fonts -- ) M: core-text-renderer free-fonts ( fonts -- )
values dispose-each ; values dispose-each ;

View File

@ -168,7 +168,7 @@ M: freetype-renderer string-height ( open-font string -- h )
: bitmap>texture ( glyph sprite -- id ) : bitmap>texture ( glyph sprite -- id )
tuck dim2>> product 2 * <byte-array> tuck dim2>> product 2 * <byte-array>
[ copy-bitmap ] keep [ dim2>> ] dip [ copy-bitmap ] keep [ dim2>> ] dip
GL_LUMINANCE_ALPHA make-texture ; GL_LUMINANCE_ALPHA GL_UNSIGNED_BYTE make-texture ;
: glyph-texture-loc ( glyph font -- loc ) : glyph-texture-loc ( glyph font -- loc )
[ drop glyph-hori-bearing-x ft-floor ] [ drop glyph-hori-bearing-x ft-floor ]