]> gitweb.factorcode.org Git - factor.git/blob - basis/core-text/core-text.factor
Updating code to use with-out-parameters
[factor.git] / basis / core-text / core-text.factor
1 ! Copyright (C) 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays alien alien.c-types alien.data alien.syntax kernel
4 destructors accessors fry words hashtables strings sequences
5 memoize assocs math math.order math.vectors math.rectangles
6 math.functions locals init namespaces combinators fonts colors
7 cache core-foundation core-foundation.strings
8 core-foundation.attributed-strings core-foundation.utilities
9 core-graphics core-graphics.types core-text.fonts ;
10 IN: core-text
11
12 TYPEDEF: void* CTLineRef
13
14 C-GLOBAL: CFStringRef kCTFontAttributeName
15 C-GLOBAL: CFStringRef kCTKernAttributeName
16 C-GLOBAL: CFStringRef kCTLigatureAttributeName
17 C-GLOBAL: CFStringRef kCTForegroundColorAttributeName
18 C-GLOBAL: CFStringRef kCTParagraphStyleAttributeName
19 C-GLOBAL: CFStringRef kCTUnderlineStyleAttributeName
20 C-GLOBAL: CFStringRef kCTVerticalFormsAttributeName
21 C-GLOBAL: CFStringRef kCTGlyphInfoAttributeName
22
23 FUNCTION: CTLineRef CTLineCreateWithAttributedString ( CFAttributedStringRef string ) ;
24
25 FUNCTION: void CTLineDraw ( CTLineRef line, CGContextRef context ) ;
26
27 FUNCTION: CGFloat CTLineGetOffsetForStringIndex ( CTLineRef line, CFIndex charIndex, CGFloat* secondaryOffset ) ;
28
29 FUNCTION: CFIndex CTLineGetStringIndexForPosition ( CTLineRef line, CGPoint position ) ;
30
31 FUNCTION: double CTLineGetTypographicBounds ( CTLineRef line, CGFloat* ascent, CGFloat* descent, CGFloat* leading ) ;
32
33 FUNCTION: CGRect CTLineGetImageBounds ( CTLineRef line, CGContextRef context ) ;
34
35 ERROR: not-a-string object ;
36
37 : <CTLine> ( string open-font color -- line )
38     [
39         [
40             dup selection? [ string>> ] when
41             dup string? [ not-a-string ] unless
42         ] 2dip
43         [
44             kCTForegroundColorAttributeName set
45             kCTFontAttributeName set
46         ] H{ } make-assoc <CFAttributedString> &CFRelease
47         CTLineCreateWithAttributedString
48     ] with-destructors ;
49
50 TUPLE: line < disposable line metrics image loc dim ;
51
52 : typographic-bounds ( line -- width ascent descent leading )
53     { CGFloat CGFloat CGFloat }
54     [ CTLineGetTypographicBounds ] [ ] with-out-parameters ; inline
55
56 : store-typographic-bounds ( metrics width ascent descent leading -- metrics )
57     {
58         [ >>width ]
59         [ >>ascent ]
60         [ >>descent ]
61         [ >>leading ]
62     } spread ; inline
63
64 : compute-font-metrics ( metrics font -- metrics )
65     [ CTFontGetCapHeight >>cap-height ]
66     [ CTFontGetXHeight >>x-height ]
67     bi ; inline
68
69 : compute-line-metrics ( open-font line -- line-metrics )
70     [ metrics new ] 2dip
71     [ compute-font-metrics ]
72     [ typographic-bounds store-typographic-bounds ] bi*
73     compute-height ;
74
75 : metrics>dim ( bounds -- dim )
76     [ width>> ] [ [ ascent>> ] [ descent>> ] bi + ] bi
77     [ ceiling >integer ]
78     bi@ 2array ;
79
80 : fill-background ( context font dim -- )
81     [ background>> >rgba-components CGContextSetRGBFillColor ]
82     [ [ 0 0 ] dip first2 <CGRect> CGContextFillRect ]
83     bi-curry* bi ;
84
85 : selection-rect ( dim line selection -- rect )
86     [ start>> ] [ end>> ] bi
87     [ f CTLineGetOffsetForStringIndex round ] bi-curry@ bi
88     [ drop nip 0 ] [ swap - swap second ] 3bi <CGRect> ;
89
90 : CGRect-translate-x ( CGRect x -- CGRect' )
91     [ dup CGRect-x ] dip - over set-CGRect-x ;
92
93 :: fill-selection-background ( context loc dim line string -- )
94     string selection? [
95         context string color>> >rgba-components CGContextSetRGBFillColor
96         context dim line string selection-rect
97         loc first CGRect-translate-x
98         CGContextFillRect
99     ] when ;
100
101 : line-rect ( line -- rect )
102     dummy-context CTLineGetImageBounds ;
103
104 : set-text-position ( context loc -- )
105     first2 [ neg ] bi@ CGContextSetTextPosition ;
106
107 :: line-loc ( metrics loc dim -- loc )
108     loc first
109     metrics ascent>> ceiling dim second loc second + - 2array ;
110
111 :: <line> ( font string -- line )
112     [
113         line new-disposable
114
115         font cache-font :> open-font
116         string open-font font foreground>> <CTLine> |CFRelease :> line
117
118         line line-rect :> rect
119         rect origin>> CGPoint>loc :> (loc)
120         rect size>> CGSize>dim :> (dim)
121         (loc) (dim) v+ :> (ext)
122         (loc) [ floor ] map :> loc
123         (loc) (dim) [ + ceiling ] 2map :> ext
124         ext loc [ - >integer 1 max ] 2map :> dim
125         open-font line compute-line-metrics :> metrics
126
127         line >>line
128
129         metrics >>metrics
130
131         dim [
132             {
133                 [ font dim fill-background ]
134                 [ loc dim line string fill-selection-background ]
135                 [ loc set-text-position ]
136                 [ [ line ] dip CTLineDraw ]
137             } cleave
138         ] make-bitmap-image >>image
139
140         metrics loc dim line-loc >>loc
141
142         metrics metrics>dim >>dim
143     ] with-destructors ;
144
145 M: line dispose* line>> CFRelease ;
146
147 SYMBOL: cached-lines
148
149 : cached-line ( font string -- line )
150     cached-lines get [ <line> ] 2cache ;
151
152 [ <cache-assoc> cached-lines set-global ] "core-text" add-startup-hook