Fix text rendering for fonts where the image bounds exceed the metric bounds, such as Zapfino and Arabic fonts

db4
Slava Pestov 2009-02-20 20:53:51 -06:00
parent af0b6ef4c8
commit fa79803856
10 changed files with 98 additions and 47 deletions

View File

@ -3,4 +3,6 @@
USING: tools.test core-graphics kernel images ; USING: tools.test core-graphics kernel images ;
IN: core-graphics.tests IN: core-graphics.tests
[ t ] [ { 100 200 } [ drop ] make-bitmap-image image? ] unit-test [ t ] [ { 100 200 } [ drop ] make-bitmap-image image? ] unit-test
[ ] [ dummy-context drop ] unit-test

View File

@ -1,6 +1,6 @@
! 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 accessors USING: alien alien.c-types alien.destructors alien.syntax accessors
destructors fry kernel math math.bitwise sequences libc colors destructors fry kernel math math.bitwise sequences libc colors
images core-graphics.types core-foundation.utilities ; images core-graphics.types core-foundation.utilities ;
IN: core-graphics IN: core-graphics
@ -117,8 +117,8 @@ FUNCTION: void* CGBitmapContextGetData ( CGContextRef c ) ;
: bitmap-color-space ( -- color-space ) : bitmap-color-space ( -- color-space )
CGColorSpaceCreateDeviceRGB &CGColorSpaceRelease ; CGColorSpaceCreateDeviceRGB &CGColorSpaceRelease ;
: <CGBitmapContext> ( dim -- context ) : <CGBitmapContext> ( data dim -- context )
[ malloc-bitmap-data ] [ first2 8 ] [ first 4 * ] tri [ first2 8 ] [ first 4 * ] bi
bitmap-color-space bitmap-flags CGBitmapContextCreate bitmap-color-space bitmap-flags CGBitmapContextCreate
[ "CGBitmapContextCreate failed" throw ] unless* ; [ "CGBitmapContextCreate failed" throw ] unless* ;
@ -134,8 +134,13 @@ FUNCTION: void* CGBitmapContextGetData ( CGContextRef c ) ;
PRIVATE> PRIVATE>
: dummy-context ( -- context )
\ dummy-context [
[ 4 malloc { 1 1 } <CGBitmapContext> ] with-destructors
] initialize-alien ;
: make-bitmap-image ( dim quot -- image ) : make-bitmap-image ( dim quot -- image )
[ [
[ [ <CGBitmapContext> &CGContextRelease ] keep ] dip [ [ [ malloc-bitmap-data ] keep <CGBitmapContext> &CGContextRelease ] keep ] dip
[ nip call ] [ drop [ bitmap-data ] keep <bitmap-image> ] 3bi [ nip call ] [ drop [ bitmap-data ] keep <bitmap-image> ] 3bi
] with-destructors ; inline ] with-destructors ; inline

View File

@ -1,6 +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.syntax kernel layouts math ; USING: alien.c-types alien.syntax kernel layouts
math math.rectangles arrays ;
IN: core-graphics.types IN: core-graphics.types
<< cell 4 = "float" "double" ? "CGFloat" typedef >> << cell 4 = "float" "double" ? "CGFloat" typedef >>
@ -33,6 +34,17 @@ C-STRUCT: CGRect
{ "CGPoint" "origin" } { "CGPoint" "origin" }
{ "CGSize" "size" } ; { "CGSize" "size" } ;
: CGPoint>loc ( CGPoint -- loc )
[ CGPoint-x ] [ CGPoint-y ] bi 2array ;
: CGSize>dim ( CGSize -- dim )
[ CGSize-w ] [ CGSize-h ] bi 2array ;
: CGRect>rect ( CGRect -- rect )
[ CGRect-origin CGPoint>loc ]
[ CGRect-size CGSize>dim ]
bi <rect> ; inline
: CGRect-x ( CGRect -- x ) : CGRect-x ( CGRect -- x )
CGRect-origin CGPoint-x ; inline CGRect-origin CGPoint-x ; inline
: CGRect-y ( CGRect -- y ) : CGRect-y ( CGRect -- y )

View File

@ -2,10 +2,10 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: arrays alien alien.c-types alien.syntax kernel destructors USING: arrays alien alien.c-types alien.syntax kernel destructors
accessors fry words hashtables strings sequences memoize assocs math accessors fry words hashtables strings sequences memoize assocs math
math.functions locals init namespaces combinators fonts colors cache math.vectors math.rectangles math.functions locals init namespaces
core-foundation core-foundation.strings core-foundation.attributed-strings combinators fonts colors cache core-foundation core-foundation.strings
core-foundation.utilities core-graphics core-graphics.types core-foundation.attributed-strings core-foundation.utilities
core-text.fonts core-text.utilities ; core-graphics core-graphics.types core-text.fonts core-text.utilities ;
IN: core-text IN: core-text
TYPEDEF: void* CTLineRef TYPEDEF: void* CTLineRef
@ -46,7 +46,7 @@ ERROR: not-a-string object ;
CTLineCreateWithAttributedString CTLineCreateWithAttributedString
] with-destructors ; ] with-destructors ;
TUPLE: line font line metrics image disposed ; TUPLE: line font line metrics image loc dim disposed ;
: compute-line-metrics ( open-font line -- line-metrics ) : compute-line-metrics ( open-font line -- line-metrics )
[ [
@ -65,7 +65,7 @@ TUPLE: line font line metrics image disposed ;
} spread } spread
dup compute-height ; dup compute-height ;
: bounds>dim ( bounds -- dim ) : metrics>dim ( bounds -- dim )
[ width>> ] [ [ ascent>> ] [ descent>> ] bi + ] bi [ width>> ] [ [ ascent>> ] [ descent>> ] bi + ] bi
[ ceiling >integer ] [ ceiling >integer ]
bi@ 2array ; bi@ 2array ;
@ -80,30 +80,48 @@ TUPLE: line font line metrics image disposed ;
[ f CTLineGetOffsetForStringIndex round ] bi-curry@ bi [ f CTLineGetOffsetForStringIndex round ] bi-curry@ bi
[ drop nip 0 ] [ swap - swap second ] 3bi <CGRect> ; [ drop nip 0 ] [ swap - swap second ] 3bi <CGRect> ;
:: fill-selection-background ( context dim line string -- ) :: fill-selection-background ( context loc dim line string -- )
string selection? [ string selection? [
context string color>> >rgba-components CGContextSetRGBFillColor context string color>> >rgba-components CGContextSetRGBFillColor
context dim line string selection-rect CGContextFillRect context dim line string selection-rect
dup CGRect-x loc first - over set-CGRect-x
CGContextFillRect
] when ; ] when ;
: set-text-position ( context metrics -- ) : line-rect ( line -- rect )
[ 0 ] dip descent>> ceiling CGContextSetTextPosition ; dummy-context CTLineGetImageBounds ;
: set-text-position ( context loc -- )
first2 [ neg ] bi@ CGContextSetTextPosition ;
:: line-loc ( metrics loc dim -- loc )
loc first
metrics ascent>> ceiling dim second loc second + - 2array ;
:: <line> ( font string -- line ) :: <line> ( font string -- line )
[ [
[let* | open-font [ font cache-font CFRetain |CFRelease ] [let* | open-font [ font cache-font CFRetain |CFRelease ]
line [ string open-font font foreground>> <CTLine> |CFRelease ] line [ string open-font font foreground>> <CTLine> |CFRelease ]
metrics [ open-font line compute-line-metrics ]
dim [ metrics bounds>dim ] | rect [ line line-rect ]
(loc) [ rect CGRect-origin CGPoint>loc ]
(dim) [ rect CGRect-size CGSize>dim ]
(ext) [ (loc) (dim) v+ ]
loc [ (loc) [ floor ] map ]
ext [ (loc) (dim) [ + ceiling ] 2map ]
dim [ ext loc [ - >integer ] 2map ]
metrics [ open-font line compute-line-metrics ] |
open-font line metrics open-font line metrics
dim [ dim [
{ {
[ font dim fill-background ] [ font dim fill-background ]
[ dim line string fill-selection-background ] [ loc dim line string fill-selection-background ]
[ metrics set-text-position ] [ loc set-text-position ]
[ [ line ] dip CTLineDraw ] [ [ line ] dip CTLineDraw ]
} cleave } cleave
] make-bitmap-image ] make-bitmap-image
metrics loc dim line-loc
metrics metrics>dim
] ]
f line boa f line boa
] with-destructors ; ] with-destructors ;

View File

@ -9,7 +9,7 @@ IN: opengl.textures
: delete-texture ( id -- ) [ glDeleteTextures ] (delete-gl-object) ; : delete-texture ( id -- ) [ glDeleteTextures ] (delete-gl-object) ;
TUPLE: texture texture-coords texture display-list disposed ; TUPLE: texture loc dim texture-coords texture display-list disposed ;
<PRIVATE <PRIVATE
@ -72,10 +72,12 @@ M: BGRA component-order>format drop GL_BGRA_EXT GL_UNSIGNED_INT_8_8_8_8 ;
GL_TEXTURE_BIT [ GL_TEXTURE_BIT [
GL_TEXTURE_COORD_ARRAY [ GL_TEXTURE_COORD_ARRAY [
COLOR: white gl-color COLOR: white gl-color
[ [ GL_TEXTURE_2D ] dip texture>> glBindTexture ] dup loc>> [
[ init-texture texture-coords>> gl-texture-coord-pointer ] bi [ [ GL_TEXTURE_2D ] dip texture>> glBindTexture ]
fill-rect-vertices (gl-fill-rect) [ init-texture texture-coords>> gl-texture-coord-pointer ] bi
GL_TEXTURE_2D 0 glBindTexture fill-rect-vertices (gl-fill-rect)
GL_TEXTURE_2D 0 glBindTexture
] with-translation
] do-enabled-client-state ] do-enabled-client-state
] do-attribs ] do-attribs
] do-enabled ; ] do-enabled ;
@ -85,19 +87,21 @@ M: BGRA component-order>format drop GL_BGRA_EXT GL_UNSIGNED_INT_8_8_8_8 ;
{ { 0 0 } { 1 0 } { 1 1 } { 0 1 } } [ v* ] with map { { 0 0 } { 1 0 } { 1 1 } { 0 1 } } [ v* ] with map
float-array{ } join ; float-array{ } join ;
: make-texture-display-list ( dim texture -- dlist ) : make-texture-display-list ( texture -- dlist )
GL_COMPILE [ draw-textured-rect ] make-dlist ; GL_COMPILE [ [ dim>> ] keep draw-textured-rect ] make-dlist ;
PRIVATE> PRIVATE>
: <texture> ( image -- texture ) : <texture> ( image loc -- texture )
dup dim>> { 0 0 } = [ drop texture new ] [ texture new swap >>loc
[ dim>> ] swap
[ dim>> texture-coords ] [ dim>> >>dim ] keep
[ power-of-2-image make-texture ] tri [ dim>> { 0 0 } = ] keep '[
f f texture boa _
[ nip ] [ make-texture-display-list ] 2bi >>display-list [ dim>> texture-coords >>texture-coords ]
] if ; [ power-of-2-image make-texture >>texture ] bi
dup make-texture-display-list >>display-list
] unless ;
M: texture dispose* M: texture dispose*
[ texture>> [ delete-texture ] when* ] [ texture>> [ delete-texture ] when* ]

View File

@ -169,11 +169,12 @@ TUPLE: selected-line start end first? last? ;
'[ [ _ _ ] keep _ start/end-on-line 2array ] H{ } map>assoc '[ [ _ _ ] keep _ start/end-on-line 2array ] H{ } map>assoc
] [ drop f ] if ; ] [ drop f ] if ;
:: draw-empty-selection ( line pair editor -- ) :: draw-selection ( line pair editor -- )
editor font>> :> font pair [ editor font>> line offset>x ] map :> pair
pair first font line offset>x 0 2array [ pair first 0 2array [
editor selection-color>> gl-color editor selection-color>> gl-color
1 font font-metrics height>> 2array gl-fill-rect pair second pair first - round 1 max
editor line-height 2array gl-fill-rect
] with-translation ; ] with-translation ;
: draw-unselected-line ( line editor -- ) : draw-unselected-line ( line editor -- )
@ -181,10 +182,13 @@ TUPLE: selected-line start end first? last? ;
: draw-selected-line ( line pair editor -- ) : draw-selected-line ( line pair editor -- )
over all-equal? [ over all-equal? [
[ nip draw-unselected-line ] [ draw-empty-selection ] 3bi [ nip draw-unselected-line ] [ draw-selection ] 3bi
] [ ] [
[ [ first2 ] [ selection-color>> ] bi* <selection> ] keep [ draw-selection ]
draw-unselected-line [
[ [ first2 ] [ selection-color>> ] bi* <selection> ] keep
draw-unselected-line
] 3bi
] if ; ] if ;
M: editor draw-line ( line index editor -- ) M: editor draw-line ( line index editor -- )
@ -197,7 +201,8 @@ M: editor draw-gadget*
] with-variable ; ] with-variable ;
M: editor pref-dim* M: editor pref-dim*
[ font>> ] [ control-value ] bi text-dim ; ! Add some space for the caret.
[ font>> ] [ control-value ] bi text-dim { 1 0 } v+ ;
M: editor baseline font>> font-metrics ascent>> ; M: editor baseline font>> font-metrics ascent>> ;

View File

@ -21,7 +21,7 @@ M: line-gadget line-leading font>> font-metrics leading>> ;
GENERIC: line-height ( gadget -- n ) GENERIC: line-height ( gadget -- n )
M: line-gadget line-height font>> font-metrics height>> ; M: line-gadget line-height font>> font-metrics height>> ceiling ;
: y>line ( y gadget -- n ) line-height /i ; : y>line ( y gadget -- n ) line-height /i ;

View File

@ -213,8 +213,12 @@ MEMO: specified-font ( assoc -- font )
: apply-image-style ( style gadget -- style gadget ) : apply-image-style ( style gadget -- style gadget )
image [ nip <image-name> <icon> ] apply-style ; image [ nip <image-name> <icon> ] apply-style ;
: apply-background-style ( style gadget -- style gadget )
background [ <solid> >>interior ] apply-style ;
: style-label ( style gadget -- gadget ) : style-label ( style gadget -- gadget )
apply-font-style apply-font-style
apply-background-style
apply-presentation-style apply-presentation-style
apply-image-style apply-image-style
nip ; inline nip ; inline

View File

@ -19,7 +19,8 @@ MEMO: cached-image ( image-name -- image ) path>> load-image ;
PRIVATE> PRIVATE>
: rendered-image ( path -- texture ) : rendered-image ( path -- texture )
world get image-texture-cache [ cached-image <texture> ] cache ; world get image-texture-cache
[ cached-image { 0 0 } <texture> ] cache ;
: draw-image ( image-name -- ) : draw-image ( image-name -- )
rendered-image draw-texture ; rendered-image draw-texture ;

View File

@ -15,7 +15,7 @@ M: core-text-renderer init-text-rendering
M: core-text-renderer string-dim M: core-text-renderer string-dim
[ " " string-dim { 0 1 } v* ] [ " " string-dim { 0 1 } v* ]
[ cached-line image>> dim>> ] [ cached-line dim>> ]
if-empty ; if-empty ;
M: core-text-renderer finish-text-rendering M: core-text-renderer finish-text-rendering
@ -24,7 +24,7 @@ M: core-text-renderer finish-text-rendering
: rendered-line ( font string -- texture ) : rendered-line ( font string -- texture )
world get text-handle>> world get text-handle>>
[ cached-line image>> <texture> ] [ cached-line [ image>> ] [ loc>> ] bi <texture> ]
2cache ; 2cache ;
M: core-text-renderer draw-string ( font string -- ) M: core-text-renderer draw-string ( font string -- )