/traderous

To get this branch, use:
bzr branch http://9ix.org/bzr/traderous

« back to all changes in this revision

Viewing changes to zoetrope/sprites/text.lua

  • Committer: Josh C
  • Date: 2013-05-04 20:45:17 UTC
  • Revision ID: josh@9ix.org-20130504204517-1rfp92svud12kg42
zoetrope 1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
-- Class: Text
 
2
-- Shows text onscreen using an outline (e.g. TrueType) or bitmap font. 
 
3
-- You can control the width of the text but the height is ignored for
 
4
-- display purposes; it will always draw the entirety of its text property.
 
5
-- If you do not specify a height and width, the sprite will size itself
 
6
-- so that it fits its entire text as a single line.
 
7
--
 
8
-- By default, an outline font will display as white. To change its color,
 
9
-- change its <Sprite.tint> property.
 
10
--
 
11
-- Extends:
 
12
--              <Sprite>
 
13
 
 
14
Text = Sprite:extend{
 
15
        -- Property: text
 
16
        -- Text string to draw.
 
17
        text = '',
 
18
 
 
19
        -- Property: font
 
20
        -- Font to use to draw. See <Cached.font> for possible values here; if
 
21
        -- you need more than one value, use table notation. Some example values:
 
22
        --              * 12 (default font, size 12)
 
23
        --              * 'fonts/bitmapfont.png' (bitmap font, default character order)
 
24
        --              * { 'fonts/outlinefont.ttf', 12 } (outline font, font size)
 
25
        --              * { 'fonts/bitmapfont.ttf', 'ABCDEF' } (bitmap font, custom character order)
 
26
        font = 12,
 
27
 
 
28
        -- Property: align
 
29
        -- Horizontal alignment, see http://love2d.org/wiki/AlignMode.
 
30
        -- This affects how lines wrap relative to each other, not how
 
31
        -- a single line will wrap relative to the sprite's width and height.
 
32
        -- If <wordWrap> is set to false, then this has no effect. 
 
33
        align = 'left',
 
34
 
 
35
        -- Property: wordWrap
 
36
        -- Wrap lines to the width of the sprite?
 
37
        wordWrap = true,
 
38
 
 
39
        -- private property: used to check whether our font has changed
 
40
        _set = { font = {} },
 
41
 
 
42
        new = function (self, obj)
 
43
                obj = obj or {}
 
44
                self:extend(obj)
 
45
                obj:updateFont()
 
46
                if obj.onNew then obj:onNew() end
 
47
                return obj
 
48
        end,
 
49
 
 
50
        -- Method: getSize
 
51
        -- Returns the width and height of the text onscreen as line-wrapped
 
52
        -- to the sprite's boundaries. This disregards the sprite's height property.
 
53
        --
 
54
        -- Arguments:
 
55
        --              none
 
56
        -- 
 
57
        -- Returns:
 
58
        --              width, height in pixels
 
59
        
 
60
        getSize = function (self)
 
61
                if self.text == '' then return 0, 0 end
 
62
 
 
63
                -- did our font change on us?
 
64
 
 
65
                if type(self.font) == 'table' then
 
66
                        for key, value in pairs(self.font) do
 
67
                                if self._set.font[key] ~= self.font[key] then
 
68
                                        self:updateFont()
 
69
                                        break
 
70
                                end
 
71
                        end
 
72
                else
 
73
                        if self.font ~= self._set.font then
 
74
                                self:updateFont()
 
75
                        end
 
76
                end
 
77
 
 
78
                local _, lines = self._fontObj:getWrap(self.text, self.width)
 
79
                local lineHeight = self._fontObj:getHeight()
 
80
 
 
81
                return self.width, lines * lineHeight
 
82
        end,
 
83
 
 
84
        -- Method: centerAround
 
85
        -- Centers the text around a position onscreen.
 
86
        --
 
87
        -- Arguments:
 
88
        --              x - center's x coordinate
 
89
        --              y - center's y coordinate
 
90
        --              centering - can be either 'horizontal', 'vertical', or 'both';
 
91
        --                                      default 'both'
 
92
        
 
93
        centerAround = function (self, x, y, centering)
 
94
                centering = centering or 'both'
 
95
                local width, height = self:getSize()
 
96
 
 
97
                if width == 0 then return end
 
98
 
 
99
                if centering == 'both' or centering == 'horizontal' then
 
100
                        self.x = x - width / 2
 
101
                end
 
102
 
 
103
                if centering == 'both' or centering == 'vertical' then
 
104
                        self.y = y - height / 2
 
105
                end
 
106
        end,
 
107
 
 
108
        -- private method: updateFont
 
109
        -- Updates the _fontObj property based on self.font.
 
110
        --
 
111
        -- Arguments:
 
112
        --              none
 
113
        --
 
114
        -- Returns:
 
115
        --              nothing
 
116
 
 
117
        updateFont = function (self)
 
118
                if self.font then
 
119
                        if type(self.font) == 'table' then
 
120
                                self._fontObj = Cached:font(unpack(self.font))
 
121
                        else
 
122
                                self._fontObj = Cached:font(self.font)
 
123
                        end
 
124
 
 
125
                        if not self.height then self.height = self._fontObj:getHeight() end
 
126
                        if not self.width and self.text then self.width = self._fontObj:getWidth(self.text) end
 
127
                end
 
128
        end,
 
129
 
 
130
        draw = function (self, x, y)
 
131
                if not self.visible or self.alpha <= 0 or not self.text or not self.font then return end
 
132
 
 
133
                x = math.floor(x or self.x)
 
134
                y = math.floor(y or self.y)
 
135
 
 
136
                if STRICT then
 
137
                        assert(type(x) == 'number', 'visible text sprite does not have a numeric x property')
 
138
                        assert(type(y) == 'number', 'visible text sprite does not have a numeric y property')
 
139
                        assert(type(self.width) == 'number', 'visible text sprite does not have a numeric width property')
 
140
                        assert(type(self.height) == 'number', 'visible text sprite does not have a numeric height property')
 
141
                        if not self.text then error('visible text sprite has no text property') end
 
142
                        if not self.font then error('visible text sprite has no font property') end
 
143
                end
 
144
 
 
145
                -- did our font change on us?
 
146
 
 
147
                if type(self.font) == 'table' then
 
148
                        for key, value in pairs(self.font) do
 
149
                                if self._set.font[key] ~= self.font[key] then
 
150
                                        self:updateFont()
 
151
                                        break
 
152
                                end
 
153
                        end
 
154
                else
 
155
                        if self.font ~= self._set.font then
 
156
                                self:updateFont()
 
157
                        end
 
158
                end
 
159
 
 
160
                -- rotate and scale
 
161
 
 
162
                local scaleX = self.scale * self.distort.x
 
163
                local scaleY = self.scale * self.distort.y
 
164
 
 
165
                if self.flipX then scaleX = scaleX * -1 end
 
166
                if self.flipY then scaleY = scaleY * -1 end
 
167
 
 
168
                if scaleX ~= 1 or scaleY ~= 1 or self.rotation ~= 0 then
 
169
                        love.graphics.push()
 
170
                        love.graphics.translate(x + self.width / 2, y + self.height / 2)
 
171
                        love.graphics.scale(scaleX, scaleY)
 
172
                        love.graphics.rotate(self.rotation)
 
173
                        love.graphics.translate(- (x + self.width / 2), - (y + self.height / 2))
 
174
                end
 
175
 
 
176
                -- set color if needed
 
177
 
 
178
                local colored = self.alpha ~= 1 or self.tint[1] ~= 1 or self.tint[2] ~= 1 or self.tint[3] ~= 1
 
179
 
 
180
                if colored then
 
181
                        love.graphics.setColor(self.tint[1] * 255, self.tint[2] * 255, self.tint[3] * 255, self.alpha * 255)
 
182
                end
 
183
                
 
184
                love.graphics.setFont(self._fontObj)
 
185
 
 
186
                if self.wordWrap then
 
187
                        love.graphics.printf(self.text, x, y, self.width, self.align)
 
188
                else
 
189
                        love.graphics.print(self.text, x, y)
 
190
                end
 
191
 
 
192
                -- reset color and rotation
 
193
        
 
194
                if colored then love.graphics.setColor(255, 255, 255, 255) end
 
195
 
 
196
                if scaleX ~= 1 or scaleY ~= 1 or self.rotation ~= 0 then
 
197
                        love.graphics.pop()
 
198
                end
 
199
        end,
 
200
 
 
201
        __tostring = function (self)
 
202
                local result = 'Text (x: ' .. self.x .. ', y: ' .. self.y ..
 
203
                                           ', w: ' .. self.width .. ', h: ' .. self.height .. ', '
 
204
 
 
205
                result = result .. 'font ' .. dump(self.font) .. ', ' .. string.len(self.text) .. ' chars, '
 
206
 
 
207
                if self.active then
 
208
                        result = result .. 'active, '
 
209
                else
 
210
                        result = result .. 'inactive, '
 
211
                end
 
212
 
 
213
                if self.visible then
 
214
                        result = result .. 'visible, '
 
215
                else
 
216
                        result = result .. 'invisible, '
 
217
                end
 
218
 
 
219
                if self.solid then
 
220
                        result = result .. 'solid'
 
221
                else
 
222
                        result = result .. 'not solid'
 
223
                end
 
224
 
 
225
                return result .. ')'
 
226
        end
 
227
}