]> gitweb.factorcode.org Git - factor.git/blobdiff - basis/core-text/core-text.factor
Updating code to use with-out-parameters
[factor.git] / basis / core-text / core-text.factor
index 86cdf90145a108f4e1ba794e05b73dbab34ed386..4de8b2c06a4fd3ef0df9b1dd5473420134e5b93d 100644 (file)
@@ -1,24 +1,24 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays alien alien.c-types alien.syntax kernel
-destructors accessors fry words hashtables strings
-sequences memoize assocs math math.functions locals init
-namespaces combinators fonts colors core-foundation
-core-foundation.strings core-foundation.attributed-strings
-core-foundation.utilities core-graphics core-graphics.types
-core-text.fonts core-text.utilities ;
+USING: arrays alien alien.c-types alien.data alien.syntax kernel
+destructors accessors fry words hashtables strings sequences
+memoize assocs math math.order math.vectors math.rectangles
+math.functions locals init namespaces combinators fonts colors
+cache core-foundation core-foundation.strings
+core-foundation.attributed-strings core-foundation.utilities
+core-graphics core-graphics.types core-text.fonts ;
 IN: core-text
 
 TYPEDEF: void* CTLineRef
 
-C-GLOBAL: kCTFontAttributeName
-C-GLOBAL: kCTKernAttributeName
-C-GLOBAL: kCTLigatureAttributeName
-C-GLOBAL: kCTForegroundColorAttributeName
-C-GLOBAL: kCTParagraphStyleAttributeName
-C-GLOBAL: kCTUnderlineStyleAttributeName
-C-GLOBAL: kCTVerticalFormsAttributeName
-C-GLOBAL: kCTGlyphInfoAttributeName
+C-GLOBAL: CFStringRef kCTFontAttributeName
+C-GLOBAL: CFStringRef kCTKernAttributeName
+C-GLOBAL: CFStringRef kCTLigatureAttributeName
+C-GLOBAL: CFStringRef kCTForegroundColorAttributeName
+C-GLOBAL: CFStringRef kCTParagraphStyleAttributeName
+C-GLOBAL: CFStringRef kCTUnderlineStyleAttributeName
+C-GLOBAL: CFStringRef kCTVerticalFormsAttributeName
+C-GLOBAL: CFStringRef kCTGlyphInfoAttributeName
 
 FUNCTION: CTLineRef CTLineCreateWithAttributedString ( CFAttributedStringRef string ) ;
 
@@ -47,16 +47,34 @@ ERROR: not-a-string object ;
         CTLineCreateWithAttributedString
     ] with-destructors ;
 
-TUPLE: line font line metrics dim bitmap age refs disposed ;
+TUPLE: line < disposable line metrics image loc dim ;
 
-: compute-line-metrics ( line -- line-metrics )
-    0 <CGFloat> 0 <CGFloat> 0 <CGFloat>
-    [ CTLineGetTypographicBounds ] 3keep [ *CGFloat ] tri@
-    metrics boa ;
+: typographic-bounds ( line -- width ascent descent leading )
+    { CGFloat CGFloat CGFloat }
+    [ CTLineGetTypographicBounds ] [ ] with-out-parameters ; inline
 
-: bounds>dim ( bounds -- dim )
+: store-typographic-bounds ( metrics width ascent descent leading -- metrics )
+    {
+        [ >>width ]
+        [ >>ascent ]
+        [ >>descent ]
+        [ >>leading ]
+    } spread ; inline
+
+: compute-font-metrics ( metrics font -- metrics )
+    [ CTFontGetCapHeight >>cap-height ]
+    [ CTFontGetXHeight >>x-height ]
+    bi ; inline
+
+: compute-line-metrics ( open-font line -- line-metrics )
+    [ metrics new ] 2dip
+    [ compute-font-metrics ]
+    [ typographic-bounds store-typographic-bounds ] bi*
+    compute-height ;
+
+: metrics>dim ( bounds -- dim )
     [ width>> ] [ [ ascent>> ] [ descent>> ] bi + ] bi
-    [ ceiling >fixnum ]
+    [ ceiling >integer ]
     bi@ 2array ;
 
 : fill-background ( context font dim -- )
@@ -66,64 +84,69 @@ TUPLE: line font line metrics dim bitmap age refs disposed ;
 
 : selection-rect ( dim line selection -- rect )
     [ start>> ] [ end>> ] bi
-    [ f CTLineGetOffsetForStringIndex ] bi-curry@ bi
+    [ f CTLineGetOffsetForStringIndex round ] bi-curry@ bi
     [ drop nip 0 ] [ swap - swap second ] 3bi <CGRect> ;
 
-:: fill-selection-background ( context dim line string -- )
+: CGRect-translate-x ( CGRect x -- CGRect' )
+    [ dup CGRect-x ] dip - over set-CGRect-x ;
+
+:: fill-selection-background ( context loc dim line string -- )
     string selection? [
         context string color>> >rgba-components CGContextSetRGBFillColor
-        context dim line string selection-rect CGContextFillRect
+        context dim line string selection-rect
+        loc first CGRect-translate-x
+        CGContextFillRect
     ] when ;
 
-: set-text-position ( context metrics -- )
-    [ 0 ] dip descent>> ceiling CGContextSetTextPosition ;
+: line-rect ( line -- rect )
+    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 )
     [
-        [let* | open-font [ font cache-font CFRetain |CFRelease ]
-                line [ string open-font font foreground>> <CTLine> |CFRelease ]
-                metrics [ line compute-line-metrics ]
-                dim [ metrics bounds>dim ] |
-            dim [
-                {
-                    [ font dim fill-background ]
-                    [ dim line string fill-selection-background ]
-                    [ metrics set-text-position ]
-                    [ [ line ] dip CTLineDraw ]
-                } cleave
-            ] with-bitmap-context
-            [ open-font line metrics dim ] dip 0 0 f
-        ]
-        line boa
-    ] with-destructors ;
+        line new-disposable
 
-M: line dispose* [ font>> CFRelease ] [ line>> CFRelease ] bi ;
+        font cache-font :> open-font
+        string open-font font foreground>> <CTLine> |CFRelease :> line
 
-: ref/unref-line ( line n -- )
-    '[ _ + ] change-refs 0 >>age drop ;
+        line line-rect :> rect
+        rect origin>> CGPoint>loc :> (loc)
+        rect size>> CGSize>dim :> (dim)
+        (loc) (dim) v+ :> (ext)
+        (loc) [ floor ] map :> loc
+        (loc) (dim) [ + ceiling ] 2map :> ext
+        ext loc [ - >integer 1 max ] 2map :> dim
+        open-font line compute-line-metrics :> metrics
 
-: ref-line ( line -- ) 1 ref/unref-line ;
-: unref-line ( line -- ) -1 ref/unref-line ;
+        line >>line
 
-SYMBOL: cached-lines
+        metrics >>metrics
 
-: cached-line ( font string -- line )
-    cached-lines get [ <line> ] 2cache ;
+        dim [
+            {
+                [ font dim fill-background ]
+                [ loc dim line string fill-selection-background ]
+                [ loc set-text-position ]
+                [ [ line ] dip CTLineDraw ]
+            } cleave
+        ] make-bitmap-image >>image
 
-CONSTANT: max-line-age 10
+        metrics loc dim line-loc >>loc
 
-: age ( obj -- ? )
-    [ 1+ ] change-age age>> max-line-age >= ;
+        metrics metrics>dim >>dim
+    ] with-destructors ;
 
-: age-line ( line -- ? )
-    #! Outputs t whether the line is dead.
-    dup refs>> 0 = [ age ] [ drop f ] if ;
+M: line dispose* line>> CFRelease ;
 
-: age-assoc ( assoc quot -- assoc' )
-    '[ nip @ ] assoc-partition
-    [ values dispose-each ] dip ;
+SYMBOL: cached-lines
 
-: age-lines ( -- )
-    cached-lines global [ [ age-line ] age-assoc ] change-at ;
+: cached-line ( font string -- line )
+    cached-lines get [ <line> ] 2cache ;
 
-[ H{ } clone cached-lines set-global ] "core-text" add-init-hook
\ No newline at end of file
+[ <cache-assoc> cached-lines set-global ] "core-text" add-startup-hook