/ld27

To get this branch, use:
bzr branch http://9ix.org/bzr/ld27
1 by Josh C
zoetrope 1.4
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
35 by Josh C
cluke009 zoetrope + my spritebatch changes
169
			local origX = self.origin.x or (self.width / 2)
170
			local origY = self.origin.y or (self.height / 2)
171
1 by Josh C
zoetrope 1.4
172
			love.graphics.push()
35 by Josh C
cluke009 zoetrope + my spritebatch changes
173
			love.graphics.translate(x + origX, y + origY)
1 by Josh C
zoetrope 1.4
174
			love.graphics.scale(scaleX, scaleY)
175
			love.graphics.rotate(self.rotation)
35 by Josh C
cluke009 zoetrope + my spritebatch changes
176
			love.graphics.translate(- (x + origX), - (y + origY))
1 by Josh C
zoetrope 1.4
177
		end
178
179
		-- set color if needed
180
181
		local colored = self.alpha ~= 1 or self.tint[1] ~= 1 or self.tint[2] ~= 1 or self.tint[3] ~= 1
182
183
		if colored then
184
			love.graphics.setColor(self.tint[1] * 255, self.tint[2] * 255, self.tint[3] * 255, self.alpha * 255)
185
		end
186
		
187
		love.graphics.setFont(self._fontObj)
188
189
		if self.wordWrap then
190
			love.graphics.printf(self.text, x, y, self.width, self.align)
191
		else
192
			love.graphics.print(self.text, x, y)
193
		end
194
195
		-- reset color and rotation
196
	
197
		if colored then love.graphics.setColor(255, 255, 255, 255) end
198
199
		if scaleX ~= 1 or scaleY ~= 1 or self.rotation ~= 0 then
200
			love.graphics.pop()
201
		end
202
	end,
203
204
	__tostring = function (self)
35 by Josh C
cluke009 zoetrope + my spritebatch changes
205
		local result = 'Text (x: ' .. tostring(self.x) .. ', y: ' .. tostring(self.y) ..
206
					   ', w: ' .. tostring(self.width) .. ', h: ' .. tostring(self.height) .. ', '
1 by Josh C
zoetrope 1.4
207
208
		result = result .. 'font ' .. dump(self.font) .. ', ' .. string.len(self.text) .. ' chars, '
209
210
		if self.active then
211
			result = result .. 'active, '
212
		else
213
			result = result .. 'inactive, '
214
		end
215
216
		if self.visible then
217
			result = result .. 'visible, '
218
		else
219
			result = result .. 'invisible, '
220
		end
221
222
		if self.solid then
223
			result = result .. 'solid'
224
		else
225
			result = result .. 'not solid'
226
		end
227
228
		return result .. ')'
229
	end
230
}