aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/text.f.glsl23
-rw-r--r--src/grid.rs8
-rw-r--r--src/main.rs45
-rw-r--r--src/renderer/mod.rs18
-rw-r--r--src/text.rs21
5 files changed, 93 insertions, 22 deletions
diff --git a/res/text.f.glsl b/res/text.f.glsl
index ce9dd41e..7e80a11c 100644
--- a/res/text.f.glsl
+++ b/res/text.f.glsl
@@ -3,9 +3,28 @@ in vec2 TexCoords;
uniform sampler2D mask;
uniform vec3 textColor;
+uniform vec3 bgColor;
+
+// SRC = SRC_ALPHA; DST = 1 - SRC_ALPHA
+void MyBlend(in vec3 srcValue,
+ in vec3 dstValue,
+ in vec3 srcAlpha,
+ out vec3 blended)
+{
+ vec3 dstAlpha = vec3(1.0, 1.0, 1.0) - srcAlpha;
+ vec3 preBlended = (srcValue * srcAlpha + dstValue * dstAlpha);
+
+ blended = vec3(min(1.0, preBlended.x),
+ min(1.0, preBlended.y),
+ min(1.0, preBlended.z));
+}
void main()
{
- vec4 sampled = vec4(1.0, 1.0, 1.0, texture(mask, TexCoords).r);
- gl_FragColor = vec4(textColor, 1.0) * sampled;
+ // vec4 red = vec4(sampled.rgb, sampled.r * sampled.g * sampled.b);
+ // vec4 sampled = vec4(1.0, 1.0, 1.0, texture(mask, TexCoords));
+ vec3 blended = vec3(1.0, 1.0, 1.0);
+ MyBlend(textColor, bgColor, texture(mask, TexCoords).rgb, blended);
+
+ gl_FragColor = vec4(blended, 1.0);
}
diff --git a/src/grid.rs b/src/grid.rs
index 93d9cd28..0418ed53 100644
--- a/src/grid.rs
+++ b/src/grid.rs
@@ -26,7 +26,7 @@ pub struct Grid {
raw: Vec<Row>,
/// Number of columns
- _cols: usize,
+ cols: usize,
/// Number of rows.
///
@@ -43,7 +43,7 @@ impl Grid {
Grid {
raw: raw,
- _cols: cols,
+ cols: cols,
rows: rows,
}
}
@@ -51,6 +51,10 @@ impl Grid {
pub fn rows(&self) -> usize {
self.rows
}
+
+ pub fn cols(&self) -> usize {
+ self.cols
+ }
}
impl Index<usize> for Grid {
diff --git a/src/main.rs b/src/main.rs
index 1845bb94..48aaf11b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -20,7 +20,7 @@ use grid::Grid;
static INIT_LIST: &'static str = "abcdefghijklmnopqrstuvwxyz\
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
01234567890\
- ~`!@#$%^&*()[]{}-_=+\\|\"/?.,<>";
+ ~`!@#$%^&*()[]{}-_=+\\|\"/?.,<>;:";
fn main() {
let window = glutin::Window::new().unwrap();
@@ -37,12 +37,12 @@ fn main() {
let (dpi_x, dpi_y) = window.get_dpi().unwrap();
let dpr = window.hidpi_factor();
- let font_size = 12.0;
+ let font_size = 11.0;
let sep_x = 2;
- let sep_y = 2;
+ let sep_y = 5;
- let desc = FontDesc::new("Ubuntu Mono", "Regular");
+ let desc = FontDesc::new("DejaVu Sans Mono", "Book");
let mut rasterizer = text::Rasterizer::new(dpi_x, dpi_y, dpr);
let (cell_width, cell_height) = rasterizer.box_size_for_font(&desc, font_size);
@@ -54,10 +54,35 @@ fn main() {
let mut grid = Grid::new(num_rows as usize, num_cols as usize);
- grid[0][0] = grid::Cell::new(Some(String::from("R")));
- grid[0][1] = grid::Cell::new(Some(String::from("u")));
- grid[0][2] = grid::Cell::new(Some(String::from("s")));
- grid[0][3] = grid::Cell::new(Some(String::from("t")));
+ // let contents = [
+ // "for (row, line) in contents.iter().enumerate() {",
+ // " for (i, c) in line.chars().enumerate() {",
+ // " grid[row][i] = grid::Cell::new(Some(c.escape_default().collect()));",
+ // " }",
+ // "}"];
+
+ let contents = include_str!("grid.rs");
+ let mut row = 0usize;
+ let mut col = 0;
+
+ for (i, c) in contents.chars().enumerate() {
+ if c == '\n' {
+ row += 1;
+ col = 0;
+ continue;
+ }
+
+ if row >= (num_rows as usize) {
+ break;
+ }
+
+ if col >= grid.cols() {
+ continue;
+ }
+
+ grid[row][col] = grid::Cell::new(Some(c.escape_default().collect()));
+ col += 1;
+ }
let mut glyph_cache = HashMap::new();
for c in INIT_LIST.chars() {
@@ -67,8 +92,8 @@ fn main() {
}
unsafe {
- gl::Enable(gl::BLEND);
- gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
+ // gl::Enable(gl::BLEND);
+ // gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
gl::Enable(gl::MULTISAMPLE);
}
diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs
index b84ed1ee..001cb40f 100644
--- a/src/renderer/mod.rs
+++ b/src/renderer/mod.rs
@@ -97,6 +97,7 @@ impl QuadRenderer {
unsafe {
// set color
gl::Uniform3f(self.program.u_color, 1., 1., 0.5);
+ gl::Uniform3f(self.program.u_bg_color, 0.08, 0.08, 0.08);
}
let rect = get_rect(glyph, x, y);
@@ -134,7 +135,7 @@ impl QuadRenderer {
fn get_rect(glyph: &Glyph, x: f32, y: f32) -> Rect<f32> {
Rect::new(
- Point2D::new(x, y),
+ Point2D::new(x + glyph.left as f32, y - (glyph.height - glyph.top) as f32),
Size2D::new(glyph.width as f32, glyph.height as f32)
)
}
@@ -152,6 +153,8 @@ pub struct ShaderProgram {
u_projection: GLint,
/// color uniform
u_color: GLint,
+ /// background color uniform
+ u_bg_color: GLint,
}
impl ShaderProgram {
@@ -180,11 +183,13 @@ impl ShaderProgram {
// get uniform locations
let projection_str = CString::new("projection").unwrap();
let color_str = CString::new("textColor").unwrap();
+ let bg_color_str = CString::new("bgColor").unwrap();
- let (projection, color) = unsafe {
+ let (projection, color, bg_color) = unsafe {
(
gl::GetUniformLocation(program, projection_str.as_ptr()),
- gl::GetUniformLocation(program, color_str.as_ptr())
+ gl::GetUniformLocation(program, color_str.as_ptr()),
+ gl::GetUniformLocation(program, bg_color_str.as_ptr()),
)
};
@@ -192,11 +197,14 @@ impl ShaderProgram {
assert!(projection != gl::INVALID_OPERATION as i32);
assert!(color != gl::INVALID_VALUE as i32);
assert!(color != gl::INVALID_OPERATION as i32);
+ assert!(bg_color != gl::INVALID_VALUE as i32);
+ assert!(bg_color != gl::INVALID_OPERATION as i32);
let shader = ShaderProgram {
id: program,
u_projection: projection,
u_color: color,
+ u_bg_color: bg_color,
};
// set projection uniform
@@ -287,11 +295,11 @@ impl Glyph {
gl::TexImage2D(
gl::TEXTURE_2D,
0,
- gl::RED as i32,
+ gl::RGB as i32,
rasterized.width as i32,
rasterized.height as i32,
0,
- gl::RED,
+ gl::RGB,
gl::UNSIGNED_BYTE,
rasterized.buf.as_ptr() as *const _
);
diff --git a/src/text.rs b/src/text.rs
index ea0df76a..ca414342 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -87,15 +87,30 @@ impl Rasterizer {
pub fn get_glyph(&mut self, desc: &FontDesc, size: f32, c: char) -> RasterizedGlyph {
let face = self.get_face(desc).expect("TODO handle get_face error");
face.set_char_size(to_freetype_26_6(size * self.dpr), 0, self.dpi_x, self.dpi_y).unwrap();
- face.load_char(c as usize, freetype::face::RENDER).unwrap();
+ face.load_char(c as usize, freetype::face::TARGET_LIGHT).unwrap();
let glyph = face.glyph();
+ glyph.render_glyph(freetype::render_mode::RenderMode::Lcd).unwrap();
+
+ // FIXME need LCD filtering to reduce color fringes with subpixel rendering. The freetype
+ // bindings don't currently expose this!
+
+ let bitmap = glyph.bitmap();
+ let buf = bitmap.buffer();
+ let pitch = bitmap.pitch() as usize;
+
+ let mut packed = Vec::with_capacity((bitmap.rows() * bitmap.width()) as usize);
+ for i in 0..bitmap.rows() {
+ let start = (i as usize) * pitch;
+ let stop = start + bitmap.width() as usize;
+ packed.extend_from_slice(&buf[start..stop]);
+ }
RasterizedGlyph {
top: glyph.bitmap_top() as usize,
left: glyph.bitmap_left() as usize,
- width: glyph.bitmap().width() as usize,
+ width: glyph.bitmap().width() as usize / 3,
height: glyph.bitmap().rows() as usize,
- buf: glyph.bitmap().buffer().to_vec(),
+ buf: packed,
}
}
}