1use color::Color;
8use draw::{BlendMode, Context, Drawable, DrawableMut, Drawer, IDENTITY};
9use font::{CharInfo, Font};
10use nalgebra::Scalar;
11use shader;
12use std::cell::RefCell;
13use std::{error::Error, rc::Rc};
14use texture::Texture;
36use transform::*;
37use vertex::Vertex;
38use vertex_buffer::VertexBuffer;
39use {Point, Vector};
40
41extern crate freetype as ft;
42
43#[derive(Debug)]
44pub struct Text {
49 font: Rc<RefCell<Font>>,
50 content: String,
51 actual_size: u32,
52 vertex_buffer: VertexBuffer,
53 need_update: bool,
54 pos: Vector<f32>,
55}
56
57impl Text {
58 pub fn dump_texture(&mut self) -> Result<(), Box<Error>> {
60 let font_ref = self.font.try_borrow().unwrap();
62 let texture = font_ref.texture(self.actual_size).unwrap();
63
64 texture.to_file("font_dump.png")?;
65 Ok(())
66 }
67
68 pub fn new(font: &Rc<RefCell<Font>>) -> Text {
70 Text {
71 font: Rc::clone(font),
72 content: String::new(),
73 actual_size: 14,
74 vertex_buffer: VertexBuffer::default(),
75 need_update: true,
76 pos: Vector::new(0.0, 0.0),
77 }
78 }
79
80 pub fn from_str(font: &Rc<RefCell<Font>>, content: &str) -> Text {
82 Text {
83 font: Rc::clone(font),
84 content: String::from(content),
85 actual_size: 14,
86 vertex_buffer: VertexBuffer::default(),
87 need_update: true,
88 pos: Vector::new(0.0, 0.0),
89 }
90 }
91
92 pub fn set_content(&mut self, content: &str) {
94 self.content = String::from(content);
95 self.need_update = true;
96 }
97
98 pub fn content(&self) -> &String {
100 &self.content
101 }
102
103 pub fn content_mut(&mut self) -> &mut String {
105 self.need_update = true;
106 &mut self.content
107 }
108
109 pub fn set_size(&mut self, size: u32) {
111 self.actual_size = size;
112 self.need_update = true;
113 }
114
115 pub fn size(&self) -> u32 {
117 self.actual_size
118 }
119
120 fn set_texture(&mut self, _texture: &Rc<Texture>) {
121 unimplemented!();
122 }
123}
124
125impl Transformable for Text {
126 fn contain<T>(&self, _point: Point<T>) -> bool
127 where
128 T: Scalar + Into<f32>,
129 {
130 true
131 }
132
133 fn set_origin<T>(&mut self, _origin: Vector<T>)
134 where
135 T: Scalar + Into<f32>,
136 {
137 unimplemented!();
138 }
139
140 fn get_origin(&self) -> Vector<f32> {
141 Vector::new(0.0, 0.0)
142 }
143}
144
145impl Scalable for Text {
146 fn scale<T>(&mut self, _factor: Vector<T>)
147 where
148 T: Scalar + Into<f32>,
149 {
150 unimplemented!();
151 }
152
153 fn set_scale<T>(&mut self, _vec: Vector<T>)
154 where
155 T: Scalar + Into<f32>,
156 {
157 unimplemented!();
158 }
159
160 fn get_scale(&self) -> Vector<f32> {
161 unimplemented!();
162 }
163}
164
165impl Rotable for Text {
166 fn rotate<T>(&mut self, _angle: T)
167 where
168 T: Scalar + Into<f32>,
169 {
170 unimplemented!();
171 }
172
173 fn set_rotation<T>(&mut self, _angle: T)
174 where
175 T: Scalar + Into<f32>,
176 {
177 unimplemented!();
178 }
179
180 fn get_rotation(&self) -> f32 {
181 0.0
182 }
183}
184
185impl Movable for Text {
186 fn translate<T>(&mut self, offset: Vector<T>)
187 where
188 T: Scalar + Into<f32>,
189 {
190 self.pos.x += offset.x.into();
191 self.pos.y += offset.y.into();
192 self.need_update = true;
193 }
194
195 fn set_position<T>(&mut self, pos: Vector<T>)
196 where
197 T: Scalar + Into<f32>,
198 {
199 self.pos.x = pos.x.into();
200 self.pos.y = pos.y.into();
201 self.need_update = true;
202 }
203
204 fn get_position(&self) -> Vector<f32> {
205 self.pos
206 }
207}
208
209impl DrawableMut for Text {
210 fn draw_mut<T: Drawer>(&mut self, target: &mut T) {
211 self.update();
212 self.draw(target);
213 }
214
215 fn draw_with_context_mut(&mut self, context: &mut Context) {
216 self.update();
217 self.draw_with_context(context);
218 }
219}
220
221impl Drawable for Text {
222 fn update(&mut self) {
223 if !self.need_update {
225 return;
226 }
227
228 let mut pos = self.pos;
230 let mut offset = 0.0;
231
232 let mut font_ref = self.font.try_borrow_mut().unwrap();
234
235 let whitespace;
237 let height;
238 {
239 let space_glyph = font_ref.glyph(self.actual_size, 0x20_u32);
240 whitespace = space_glyph.advance;
241 }
242 {
243 let a_glyph = font_ref.glyph(self.actual_size, 0x41_u32);
244 height = a_glyph.rect.height + a_glyph.rect.height / 5.0;
245 }
246
247 let padding = 0.0;
249
250 self.vertex_buffer.clear();
252
253 for charr in self.content.as_str().chars() {
255 match charr {
257 '\n' => {
258 pos.y += height;
259 offset = 0.0;
260 continue;
261 }
262 '\r' => continue,
263 '\t' => {
264 offset += 4.0 * whitespace;
265 continue;
266 }
267 ' ' => {
268 offset += whitespace;
269 continue;
270 }
271 _ => {}
272 };
273
274 let char_info = font_ref.glyph(self.actual_size, charr as u32);
276
277 let vertices = get_vertice_letter(&char_info, pos, padding, offset);
279
280 self.vertex_buffer.append(&vertices);
282
283 offset += char_info.advance as f32;
285 }
286 self.vertex_buffer.update();
288
289 self.need_update = false;
291 }
292
293 fn draw<T: Drawer>(&self, target: &mut T) {
294 if self.content.is_empty() {
296 return;
297 }
298
299 let font_ref = self.font.try_borrow().unwrap();
301 let texture = font_ref.texture(self.actual_size).unwrap();
302
303 let mut context = Context::new(
305 Some(texture),
306 &*shader::DEFAULT_SHADER,
307 vec![
308 ("transform".to_string(), &*IDENTITY),
309 ("projection".to_string(), target.projection()),
310 ],
311 BlendMode::Alpha,
312 );
313
314 self.vertex_buffer.draw_with_context(&mut context);
316 }
317
318 fn draw_with_context(&self, context: &mut Context) {
319 self.vertex_buffer.draw_with_context(context);
320 }
321}
322
323fn get_vertice_letter(
325 char_info: &CharInfo,
326 pos: Vector<f32>,
327 padding: f32,
328 offset: f32,
329) -> [Vertex; 6] {
330 let x = pos.x + offset;
331 let y = pos.y;
332
333 let left = char_info.rect.left - padding;
335 let top = char_info.rect.top - padding;
336 let right = char_info.rect.left + char_info.rect.width + padding;
337 let bottom = char_info.rect.top + char_info.rect.height + padding;
338
339 let u1 = ((char_info.tex_coord.left - padding as u32) as f32) / 128.0;
341 let v1 = ((char_info.tex_coord.top - padding as u32) as f32) / 128.0;
342 let u2 =
343 ((char_info.tex_coord.left + char_info.tex_coord.width + padding as u32) as f32) / 128.0;
344 let v2 =
345 ((char_info.tex_coord.top + char_info.tex_coord.height + padding as u32) as f32) / 128.0;
346
347 [
348 Vertex::new(
349 Vector::new(x + left, y + top),
350 Vector::new(u1, v1),
351 Color::white(),
352 ),
353 Vertex::new(
354 Vector::new(x + left, y + bottom),
355 Vector::new(u1, v2),
356 Color::white(),
357 ),
358 Vertex::new(
359 Vector::new(x + right, y + bottom),
360 Vector::new(u2, v2),
361 Color::white(),
362 ),
363 Vertex::new(
364 Vector::new(x + left, y + top),
365 Vector::new(u1, v1),
366 Color::white(),
367 ),
368 Vertex::new(
369 Vector::new(x + right, y + bottom),
370 Vector::new(u2, v2),
371 Color::white(),
372 ),
373 Vertex::new(
374 Vector::new(x + right, y + top),
375 Vector::new(u2, v1),
376 Color::white(),
377 ),
378 ]
379}