font: rewrite font backend
We now properly draw fonts with OpenGL. We now use FreeType2 instead of pango to avoid big dependencies. We also add a DejaVu font so we currently don't have to deal with font selection. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
0b320653d8
commit
5a3801386a
89
COPYING
89
COPYING
@ -87,3 +87,92 @@ The xkb input handling is based on the Xlib xkb handling:
|
||||
shall not be used in advertising or otherwise to promote the sale, use
|
||||
or other dealings in this Software without prior written authorization
|
||||
from the XFree86 Project.
|
||||
|
||||
The DejaVu fonts included in this package are from:
|
||||
|
||||
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.
|
||||
Bitstream Vera is a trademark of Bitstream, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the fonts accompanying this license ("Fonts") and associated
|
||||
documentation files (the "Font Software"), to reproduce and distribute
|
||||
the Font Software, including without limitation the rights to use,
|
||||
copy, merge, publish, distribute, and/or sell copies of the Font
|
||||
Software, and to permit persons to whom the Font Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice
|
||||
shall be included in all copies of one or more of the Font Software
|
||||
typefaces.
|
||||
The Font Software may be modified, altered, or added to, and in
|
||||
particular the designs of glyphs or characters in the Fonts may be
|
||||
modified and additional glyphs or characters may be added to the Fonts,
|
||||
only if the fonts are renamed to names not containing either the words
|
||||
"Bitstream" or the word "Vera".
|
||||
This License becomes null and void to the extent applicable to Fonts or
|
||||
Font Software that has been modified and is distributed under the
|
||||
"Bitstream Vera" names.
|
||||
The Font Software may be sold as part of a larger software package but
|
||||
no copy of one or more of the Font Software typefaces may be sold by
|
||||
itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
|
||||
BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL,
|
||||
OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT
|
||||
SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the names of Gnome, the Gnome
|
||||
Foundation, and Bitstream Inc., shall not be used in advertising or
|
||||
otherwise to promote the sale, use or other dealings in this Font
|
||||
Software without prior written authorization from the Gnome Foundation
|
||||
or Bitstream Inc., respectively. For further information,
|
||||
contact: fonts at gnome dot org.
|
||||
|
||||
|
||||
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the fonts accompanying this license ("Fonts") and
|
||||
associated documentation files (the "Font Software"), to reproduce
|
||||
and distribute the modifications to the Bitstream Vera Font Software,
|
||||
including without limitation the rights to use, copy, merge, publish,
|
||||
distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice
|
||||
shall be included in all copies of one or more of the Font Software
|
||||
typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in
|
||||
particular the designs of glyphs or characters in the Fonts may be
|
||||
modified and additional glyphs or characters may be added to the
|
||||
Fonts, only if the fonts are renamed to names not containing either
|
||||
the words "Tavmjong Bah" or the word "Arev".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts
|
||||
or Font Software that has been modified and is distributed under the
|
||||
"Tavmjong Bah Arev" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but
|
||||
no copy of one or more of the Font Software typefaces may be sold by
|
||||
itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
|
||||
TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Tavmjong Bah shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Font Software without prior written authorization
|
||||
from Tavmjong Bah. For further information, contact: tavmjong@free.fr.
|
||||
|
@ -40,6 +40,7 @@ libkmscon_core_la_SOURCES = \
|
||||
src/console.c src/console.h \
|
||||
src/output.c src/output.h \
|
||||
src/output_context.c \
|
||||
src/output_math.c \
|
||||
src/console_cell.c \
|
||||
src/unicode.c src/unicode.h \
|
||||
src/log.c src/log.h \
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
mkdir -p m4/
|
||||
autoreconf -i
|
||||
./configure --enable-debug --enable-pango --enable-gles2 $*
|
||||
./configure --enable-debug --enable-gles2 $*
|
||||
|
BIN
fonts/DejaVuSansMono.ttf
Normal file
BIN
fonts/DejaVuSansMono.ttf
Normal file
Binary file not shown.
122
src/console.c
122
src/console.c
@ -36,8 +36,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cairo.h>
|
||||
|
||||
#include "console.h"
|
||||
#include "font.h"
|
||||
#include "log.h"
|
||||
@ -50,17 +48,11 @@ struct kmscon_console {
|
||||
struct kmscon_compositor *comp;
|
||||
struct kmscon_context *ctx;
|
||||
|
||||
/* GL texture and font */
|
||||
unsigned int tex;
|
||||
/* font */
|
||||
unsigned int res_x;
|
||||
unsigned int res_y;
|
||||
struct kmscon_font *font;
|
||||
|
||||
/* cairo surface */
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *surf;
|
||||
unsigned char *surf_buf;
|
||||
|
||||
/* console cells */
|
||||
struct kmscon_buffer *cells;
|
||||
unsigned int cells_x;
|
||||
@ -71,69 +63,6 @@ struct kmscon_console {
|
||||
unsigned int cursor_y;
|
||||
};
|
||||
|
||||
static void kmscon_console_free_res(struct kmscon_console *con)
|
||||
{
|
||||
if (con && con->cr) {
|
||||
kmscon_context_free_tex(con->ctx, con->tex);
|
||||
cairo_destroy(con->cr);
|
||||
cairo_surface_destroy(con->surf);
|
||||
free(con->surf_buf);
|
||||
con->tex = 0;
|
||||
con->cr = NULL;
|
||||
con->surf = NULL;
|
||||
con->surf_buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int kmscon_console_new_res(struct kmscon_console *con)
|
||||
{
|
||||
unsigned char *buf;
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *surface;
|
||||
int stride, ret;
|
||||
cairo_format_t format = CAIRO_FORMAT_ARGB32;
|
||||
|
||||
if (!con)
|
||||
return -EINVAL;
|
||||
|
||||
stride = cairo_format_stride_for_width(format, con->res_x);
|
||||
|
||||
buf = malloc(stride * con->res_y);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
surface = cairo_image_surface_create_for_data(buf, format, con->res_x,
|
||||
con->res_y, stride);
|
||||
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
cr = cairo_create(surface);
|
||||
if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) {
|
||||
ret = -EFAULT;
|
||||
goto err_cairo;
|
||||
}
|
||||
|
||||
kmscon_console_free_res(con);
|
||||
|
||||
con->surf_buf = buf;
|
||||
con->surf = surface;
|
||||
con->cr = cr;
|
||||
|
||||
con->tex = kmscon_context_new_tex(con->ctx);
|
||||
|
||||
log_debug("console: new resolution %ux%u\n", con->res_x, con->res_y);
|
||||
return 0;
|
||||
|
||||
err_cairo:
|
||||
cairo_destroy(cr);
|
||||
err_free:
|
||||
cairo_surface_destroy(surface);
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kmscon_console_new(struct kmscon_console **out,
|
||||
struct kmscon_font_factory *ff, struct kmscon_compositor *comp)
|
||||
{
|
||||
@ -192,7 +121,6 @@ void kmscon_console_unref(struct kmscon_console *con)
|
||||
if (--con->ref)
|
||||
return;
|
||||
|
||||
kmscon_console_free_res(con);
|
||||
kmscon_font_unref(con->font);
|
||||
kmscon_buffer_unref(con->cells);
|
||||
kmscon_compositor_unref(con->comp);
|
||||
@ -280,48 +208,11 @@ int kmscon_console_resize(struct kmscon_console *con, unsigned int x,
|
||||
con->font = font;
|
||||
con->res_x = con->cells_x * kmscon_font_get_width(con->font);
|
||||
con->res_y = height;
|
||||
|
||||
ret = kmscon_console_new_res(con);
|
||||
if (ret) {
|
||||
log_err("console: cannot create drawing buffers: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
log_debug("console: new resolution %ux%u\n", con->res_x, con->res_y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This redraws the console. It does not clip/copy the image onto any
|
||||
* framebuffer. You must use kmscon_console_map() to do this.
|
||||
* This allows to draw the console once and then map it onto multiple
|
||||
* framebuffers so it is displayed on multiple monitors with different screen
|
||||
* resolutions.
|
||||
* You must have called kmscon_console_set_res() before.
|
||||
*/
|
||||
void kmscon_console_draw(struct kmscon_console *con)
|
||||
{
|
||||
if (!con || !con->cr)
|
||||
return;
|
||||
|
||||
cairo_save(con->cr);
|
||||
|
||||
cairo_set_operator(con->cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_rgba(con->cr, 0.0, 0.0, 0.0, 0.0);
|
||||
cairo_paint(con->cr);
|
||||
|
||||
cairo_set_operator(con->cr, CAIRO_OPERATOR_OVER);
|
||||
cairo_set_source_rgba(con->cr, 1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
kmscon_buffer_draw(con->cells, con->font, con->cr, con->res_x,
|
||||
con->res_y);
|
||||
|
||||
cairo_restore(con->cr);
|
||||
|
||||
/* refresh GL texture contents */
|
||||
kmscon_context_set_tex(con->ctx, con->tex, con->res_x, con->res_y,
|
||||
con->surf_buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* This maps the console onto the current GL framebuffer. It expects the
|
||||
* framebuffer to have 0/0 in the middle, -1/-1 in the upper left and 1/1 in the
|
||||
@ -334,15 +225,10 @@ void kmscon_console_draw(struct kmscon_console *con)
|
||||
*/
|
||||
void kmscon_console_map(struct kmscon_console *con)
|
||||
{
|
||||
static const float vertices[] = { -1, -1, 1, -1, -1, 1,
|
||||
1, -1, 1, 1, -1, 1 };
|
||||
static const float texpos[] = { 0, 0, 1, 0, 0, 1,
|
||||
1, 0, 1, 1, 0, 1 };
|
||||
|
||||
if (!con || !con->cr)
|
||||
if (!con)
|
||||
return;
|
||||
|
||||
kmscon_context_draw_tex(con->ctx, vertices, texpos, 6, con->tex);
|
||||
kmscon_buffer_draw(con->cells, con->font);
|
||||
}
|
||||
|
||||
void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch)
|
||||
|
@ -53,8 +53,7 @@ void kmscon_buffer_unref(struct kmscon_buffer *buf);
|
||||
|
||||
int kmscon_buffer_resize(struct kmscon_buffer *buf, unsigned int x,
|
||||
unsigned int y);
|
||||
void kmscon_buffer_draw(struct kmscon_buffer *buf, struct kmscon_font *font,
|
||||
void *dcr, unsigned int width, unsigned int height);
|
||||
void kmscon_buffer_draw(struct kmscon_buffer *buf, struct kmscon_font *font);
|
||||
|
||||
unsigned int kmscon_buffer_get_width(struct kmscon_buffer *buf);
|
||||
unsigned int kmscon_buffer_get_height(struct kmscon_buffer *buf);
|
||||
@ -76,7 +75,6 @@ unsigned int kmscon_console_get_height(struct kmscon_console *con);
|
||||
int kmscon_console_resize(struct kmscon_console *con, unsigned int x,
|
||||
unsigned int y, unsigned int height);
|
||||
|
||||
void kmscon_console_draw(struct kmscon_console *con);
|
||||
void kmscon_console_map(struct kmscon_console *con);
|
||||
|
||||
void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch);
|
||||
|
@ -80,8 +80,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cairo.h>
|
||||
|
||||
#include "console.h"
|
||||
#include "log.h"
|
||||
#include "unicode.h"
|
||||
@ -116,6 +114,8 @@ struct kmscon_buffer {
|
||||
unsigned int size_y;
|
||||
unsigned int fill;
|
||||
struct line **current;
|
||||
|
||||
struct kmscon_m4_stack *stack;
|
||||
};
|
||||
|
||||
static void destroy_cell(struct cell *cell)
|
||||
@ -216,13 +216,19 @@ int kmscon_buffer_new(struct kmscon_buffer **out, unsigned int x,
|
||||
|
||||
log_debug("console: new buffer object\n");
|
||||
|
||||
ret = kmscon_buffer_resize(buf, x, y);
|
||||
ret = kmscon_m4_stack_new(&buf->stack);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
ret = kmscon_buffer_resize(buf, x, y);
|
||||
if (ret)
|
||||
goto err_stack;
|
||||
|
||||
*out = buf;
|
||||
return 0;
|
||||
|
||||
err_stack:
|
||||
kmscon_m4_stack_free(buf->stack);
|
||||
err_free:
|
||||
free(buf);
|
||||
return ret;
|
||||
@ -257,6 +263,7 @@ void kmscon_buffer_unref(struct kmscon_buffer *buf)
|
||||
free_line(buf->current[i]);
|
||||
|
||||
free(buf->current);
|
||||
kmscon_m4_stack_free(buf->stack);
|
||||
free(buf);
|
||||
log_debug("console: destroying buffer object\n");
|
||||
}
|
||||
@ -415,32 +422,30 @@ int kmscon_buffer_resize(struct kmscon_buffer *buf, unsigned int x,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kmscon_buffer_draw(struct kmscon_buffer *buf, struct kmscon_font *font,
|
||||
void *dcr, unsigned int width, unsigned int height)
|
||||
void kmscon_buffer_draw(struct kmscon_buffer *buf, struct kmscon_font *font)
|
||||
{
|
||||
cairo_t *cr;
|
||||
double xs, ys, cx, cy;
|
||||
float xs, ys;
|
||||
unsigned int i, j, k, num;
|
||||
struct line *iter, *line;
|
||||
struct cell *cell;
|
||||
float *m;
|
||||
|
||||
if (!buf || !font || !dcr)
|
||||
if (!buf || !font)
|
||||
return;
|
||||
|
||||
cr = dcr;
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||
cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
|
||||
m = kmscon_m4_stack_tip(buf->stack);
|
||||
kmscon_m4_identity(m);
|
||||
|
||||
xs = width / (double)buf->size_x;
|
||||
ys = height / (double)buf->size_y;
|
||||
xs = 1.0 / buf->size_x;
|
||||
ys = 1.0 / buf->size_y;
|
||||
kmscon_m4_scale(m, 2, 2, 1);
|
||||
kmscon_m4_trans(m, -0.5, -0.5, 0);
|
||||
kmscon_m4_scale(m, xs, ys, 1);
|
||||
|
||||
iter = buf->position;
|
||||
k = 0;
|
||||
|
||||
cy = 0;
|
||||
for (i = 0; i < buf->size_y; ++i) {
|
||||
cx = 0;
|
||||
|
||||
if (iter) {
|
||||
line = iter;
|
||||
iter = iter->next;
|
||||
@ -460,11 +465,16 @@ void kmscon_buffer_draw(struct kmscon_buffer *buf, struct kmscon_font *font,
|
||||
for (j = 0; j < num; ++j) {
|
||||
cell = &line->cells[j];
|
||||
|
||||
kmscon_font_draw(font, cell->ch, cr, cx, cy);
|
||||
cx += xs;
|
||||
}
|
||||
m = kmscon_m4_stack_push(buf->stack);
|
||||
if (!m) {
|
||||
log_warning("console: cannot push matrix\n");
|
||||
break;
|
||||
}
|
||||
|
||||
cy += ys;
|
||||
kmscon_m4_trans(m, j, i, 0);
|
||||
kmscon_font_draw(font, cell->ch, m);
|
||||
m = kmscon_m4_stack_pop(buf->stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,6 @@ void kmscon_font_unref(struct kmscon_font *font);
|
||||
|
||||
unsigned int kmscon_font_get_height(struct kmscon_font *font);
|
||||
unsigned int kmscon_font_get_width(struct kmscon_font *font);
|
||||
int kmscon_font_draw(struct kmscon_font *font, kmscon_symbol_t ch,
|
||||
void *dcr, uint32_t x, uint32_t y);
|
||||
int kmscon_font_draw(struct kmscon_font *font, kmscon_symbol_t ch, float *m);
|
||||
|
||||
#endif /* KMSCON_FONT_H */
|
||||
|
@ -32,9 +32,11 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include "font.h"
|
||||
#include "log.h"
|
||||
#include "output.h"
|
||||
@ -58,12 +60,115 @@ struct kmscon_font {
|
||||
FT_Face face;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
GHashTable *glyphs;
|
||||
};
|
||||
|
||||
struct kmscon_glyph {
|
||||
unsigned long ref;
|
||||
struct kmscon_context *ctx;
|
||||
bool valid;
|
||||
unsigned int tex;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
int left;
|
||||
int top;
|
||||
unsigned int advance;
|
||||
};
|
||||
|
||||
static int kmscon_glyph_new(struct kmscon_glyph **out, kmscon_symbol_t key,
|
||||
struct kmscon_font *font)
|
||||
{
|
||||
struct kmscon_glyph *glyph;
|
||||
FT_Error err;
|
||||
FT_UInt idx;
|
||||
FT_Bitmap *bmap;
|
||||
int ret;
|
||||
const uint32_t *val;
|
||||
size_t len;
|
||||
unsigned char *data, d;
|
||||
unsigned int i, j;
|
||||
|
||||
if (!out)
|
||||
return -EINVAL;
|
||||
|
||||
glyph = malloc(sizeof(*glyph));
|
||||
if (!glyph)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(glyph, 0, sizeof(*glyph));
|
||||
glyph->ctx = font->ff->ctx;
|
||||
|
||||
val = kmscon_symbol_get(font->ff->st, &key, &len);
|
||||
|
||||
if (!val[0])
|
||||
goto ready;
|
||||
|
||||
/* TODO: Add support for combining characters */
|
||||
idx = FT_Get_Char_Index(font->face, val[0]);
|
||||
err = FT_Load_Glyph(font->face, idx, FT_LOAD_DEFAULT);
|
||||
if (err) {
|
||||
ret = -EFAULT;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
err = FT_Render_Glyph(font->face->glyph, FT_RENDER_MODE_NORMAL);
|
||||
if (err) {
|
||||
ret = -EFAULT;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
bmap = &font->face->glyph->bitmap;
|
||||
if (!bmap->width || !bmap->rows)
|
||||
goto ready;
|
||||
|
||||
glyph->tex = kmscon_context_new_tex(glyph->ctx);
|
||||
data = malloc(sizeof(unsigned char) * bmap->width * bmap->rows * 4);
|
||||
if (!data) {
|
||||
ret = -ENOMEM;
|
||||
goto err_tex;
|
||||
}
|
||||
|
||||
for (j = 0; j < bmap->rows; ++j) {
|
||||
for (i = 0; i < bmap->width; ++i) {
|
||||
d = bmap->buffer[i + bmap->width * j];
|
||||
data[4 * (i + j * bmap->width)] = d;
|
||||
data[4 * (i + j * bmap->width) + 1] = d;
|
||||
data[4 * (i + j * bmap->width) + 2] = d;
|
||||
data[4 * (i + j * bmap->width) + 3] = d;
|
||||
}
|
||||
}
|
||||
|
||||
kmscon_context_set_tex(glyph->ctx, glyph->tex, bmap->width,
|
||||
bmap->rows, data);
|
||||
free(data);
|
||||
|
||||
glyph->width = bmap->width;
|
||||
glyph->height = bmap->rows;
|
||||
glyph->left = font->face->glyph->bitmap_left;
|
||||
glyph->top = font->face->glyph->bitmap_top;
|
||||
glyph->advance = font->face->glyph->advance.x >> 6;
|
||||
glyph->valid = true;
|
||||
|
||||
ready:
|
||||
*out = glyph;
|
||||
return 0;
|
||||
|
||||
err_tex:
|
||||
kmscon_context_free_tex(glyph->ctx, glyph->tex);
|
||||
err_free:
|
||||
free(glyph);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void kmscon_glyph_destroy(struct kmscon_glyph *glyph)
|
||||
{
|
||||
if (!glyph)
|
||||
return;
|
||||
|
||||
if (glyph->valid)
|
||||
kmscon_context_free_tex(glyph->ctx, glyph->tex);
|
||||
free(glyph);
|
||||
}
|
||||
|
||||
int kmscon_font_factory_new(struct kmscon_font_factory **out,
|
||||
struct kmscon_symbol_table *st, struct kmscon_compositor *comp)
|
||||
{
|
||||
@ -137,9 +242,12 @@ int kmscon_font_factory_load(struct kmscon_font_factory *ff,
|
||||
const char *estr = "unknown error";
|
||||
int ret;
|
||||
|
||||
if (!ff || !out)
|
||||
if (!ff || !out || !height)
|
||||
return -EINVAL;
|
||||
|
||||
if (!width)
|
||||
width = height;
|
||||
|
||||
font = malloc(sizeof(*font));
|
||||
if (!font)
|
||||
return -ENOMEM;
|
||||
@ -149,7 +257,8 @@ int kmscon_font_factory_load(struct kmscon_font_factory *ff,
|
||||
font->width = width;
|
||||
font->height = height;
|
||||
|
||||
err = FT_New_Face(ff->lib, "/usr/share/fonts/TTF/DejaVuSansMono.ttf",
|
||||
/* TODO: Use fontconfig to get font paths */
|
||||
err = FT_New_Face(ff->lib, "./fonts/DejaVuSansMono.ttf",
|
||||
0, &font->face);
|
||||
if (err) {
|
||||
if (err == FT_Err_Unknown_File_Format)
|
||||
@ -173,6 +282,13 @@ int kmscon_font_factory_load(struct kmscon_font_factory *ff,
|
||||
goto err_face;
|
||||
}
|
||||
|
||||
font->glyphs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
|
||||
NULL, (GDestroyNotify) kmscon_glyph_destroy);
|
||||
if (!font->glyphs) {
|
||||
ret = -ENOMEM;
|
||||
goto err_face;
|
||||
}
|
||||
|
||||
kmscon_font_factory_ref(ff);
|
||||
font->ff = ff;
|
||||
*out = font;
|
||||
@ -202,6 +318,7 @@ void kmscon_font_unref(struct kmscon_font *font)
|
||||
if (--font->ref)
|
||||
return;
|
||||
|
||||
g_hash_table_unref(font->glyphs);
|
||||
FT_Done_Face(font->face);
|
||||
kmscon_font_factory_unref(font->ff);
|
||||
free(font);
|
||||
@ -223,13 +340,49 @@ unsigned int kmscon_font_get_width(struct kmscon_font *font)
|
||||
return font->width;
|
||||
}
|
||||
|
||||
int kmscon_font_draw(struct kmscon_font *font, kmscon_symbol_t ch,
|
||||
void *dcr, uint32_t x, uint32_t y)
|
||||
static int kmscon_font_lookup(struct kmscon_font *font,
|
||||
kmscon_symbol_t key, struct kmscon_glyph **out)
|
||||
{
|
||||
struct kmscon_glyph *glyph;
|
||||
int ret;
|
||||
|
||||
if (!font || !out)
|
||||
return -EINVAL;
|
||||
|
||||
glyph = g_hash_table_lookup(font->glyphs, GUINT_TO_POINTER(key));
|
||||
if (!glyph) {
|
||||
ret = kmscon_glyph_new(&glyph, key, font);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
g_hash_table_insert(font->glyphs, GUINT_TO_POINTER(key), glyph);
|
||||
}
|
||||
|
||||
*out = glyph;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kmscon_font_draw(struct kmscon_font *font, kmscon_symbol_t ch, float *m)
|
||||
{
|
||||
int ret;
|
||||
struct kmscon_glyph *glyph;
|
||||
static const float val[] = { 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1 };
|
||||
|
||||
if (!font)
|
||||
return -EINVAL;
|
||||
|
||||
/* still TODO */
|
||||
ret = kmscon_font_lookup(font, ch, &glyph);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!glyph->valid)
|
||||
return 0;
|
||||
|
||||
kmscon_m4_scale(m, 1.0 / glyph->advance, 1.0 / font->height, 1);
|
||||
kmscon_m4_trans(m, glyph->left, font->height - glyph->top, 0);
|
||||
kmscon_m4_scale(m, glyph->width, glyph->height, 1);
|
||||
|
||||
kmscon_context_draw_tex(font->ff->ctx, val, val, 6, glyph->tex, m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
485
src/font_pango.c
485
src/font_pango.c
@ -44,488 +44,9 @@
|
||||
#include "output.h"
|
||||
#include "unicode.h"
|
||||
|
||||
enum glyph_type {
|
||||
GLYPH_NONE,
|
||||
GLYPH_LAYOUT,
|
||||
GLYPH_STR,
|
||||
};
|
||||
|
||||
struct kmscon_glyph {
|
||||
size_t ref;
|
||||
kmscon_symbol_t ch;
|
||||
unsigned int width;
|
||||
|
||||
int type;
|
||||
|
||||
union {
|
||||
struct layout {
|
||||
PangoLayout *layout;
|
||||
} layout;
|
||||
struct str {
|
||||
PangoFont *font;
|
||||
PangoGlyphString *str;
|
||||
uint32_t ascent;
|
||||
} str;
|
||||
} src;
|
||||
};
|
||||
|
||||
struct kmscon_font_factory {
|
||||
unsigned long ref;
|
||||
struct kmscon_symbol_table *st;
|
||||
struct kmscon_compositor *comp;
|
||||
struct kmscon_context *ctx;
|
||||
};
|
||||
|
||||
struct kmscon_font {
|
||||
size_t ref;
|
||||
struct kmscon_symbol_table *st;
|
||||
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
GHashTable *glyphs;
|
||||
PangoContext *ctx;
|
||||
};
|
||||
|
||||
static int kmscon_font_lookup(struct kmscon_font *font,
|
||||
kmscon_symbol_t key, struct kmscon_glyph **out);
|
||||
|
||||
/*
|
||||
* Glyphs
|
||||
* Glyphs are for internal use only! The outside world uses kmscon_char
|
||||
* objects in combination with kmscon_font to draw characters. Internally, we
|
||||
* cache a kmscon_glyph for every character that is drawn.
|
||||
* This allows us to speed up the drawing operations because most characters are
|
||||
* already cached.
|
||||
*
|
||||
* Glyphs are cached in a hash-table by each font. If a character is drawn, we
|
||||
* look it up in the hash-table (or create a new one if none is found) and draw
|
||||
* it to the framebuffer.
|
||||
* A glyph may use several ways to cache the glyph description:
|
||||
* GLYPH_NONE:
|
||||
* No information is currently attached so the glyph cannot be drawn.
|
||||
* GLYPH_LAYOUT:
|
||||
* The most basic drawing operation. This is the slowest of all but can draw
|
||||
* any text you want. It uses a PangoLayout internally and recalculates the
|
||||
* character sizes each time we draw them.
|
||||
*/
|
||||
static int kmscon_glyph_new(struct kmscon_glyph **out, kmscon_symbol_t ch)
|
||||
{
|
||||
struct kmscon_glyph *glyph;
|
||||
|
||||
if (!out)
|
||||
return -EINVAL;
|
||||
|
||||
glyph = malloc(sizeof(*glyph));
|
||||
if (!glyph)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(glyph, 0, sizeof(*glyph));
|
||||
glyph->ref = 1;
|
||||
glyph->type = GLYPH_NONE;
|
||||
glyph->ch = ch;
|
||||
|
||||
*out = glyph;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset internal glyph description. You must use kmscon_glyph_set() again to
|
||||
* attach new glyph descriptions.
|
||||
*/
|
||||
static void kmscon_glyph_reset(struct kmscon_glyph *glyph)
|
||||
{
|
||||
if (!glyph)
|
||||
return;
|
||||
|
||||
switch (glyph->type) {
|
||||
case GLYPH_LAYOUT:
|
||||
g_object_unref(glyph->src.layout.layout);
|
||||
break;
|
||||
case GLYPH_STR:
|
||||
g_object_unref(glyph->src.str.font);
|
||||
pango_glyph_string_free(glyph->src.str.str);
|
||||
break;
|
||||
}
|
||||
|
||||
glyph->type = GLYPH_NONE;
|
||||
glyph->width = 0;
|
||||
}
|
||||
|
||||
static void kmscon_glyph_ref(struct kmscon_glyph *glyph)
|
||||
{
|
||||
if (!glyph)
|
||||
return;
|
||||
|
||||
++glyph->ref;
|
||||
}
|
||||
|
||||
static void kmscon_glyph_unref(struct kmscon_glyph *glyph)
|
||||
{
|
||||
if (!glyph || !glyph->ref)
|
||||
return;
|
||||
|
||||
if (--glyph->ref)
|
||||
return;
|
||||
|
||||
kmscon_glyph_reset(glyph);
|
||||
free(glyph);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate glyph description.
|
||||
* This connects the glyph with the given font an generates the fastest glyph
|
||||
* description.
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
static int kmscon_glyph_set(struct kmscon_glyph *glyph,
|
||||
struct kmscon_font *font)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
PangoLayoutLine *line;
|
||||
PangoGlyphItem *tmp;
|
||||
PangoGlyphString *str;
|
||||
PangoRectangle rec;
|
||||
size_t len;
|
||||
const char *val;
|
||||
|
||||
if (!glyph || !font)
|
||||
return -EINVAL;
|
||||
|
||||
layout = pango_layout_new(font->ctx);
|
||||
if (!layout)
|
||||
return -EINVAL;
|
||||
|
||||
val = kmscon_symbol_get_u8(font->st, glyph->ch, &len);
|
||||
pango_layout_set_text(layout, val, len);
|
||||
kmscon_symbol_free_u8(val);
|
||||
|
||||
pango_layout_get_extents(layout, NULL, &rec);
|
||||
line = pango_layout_get_line_readonly(layout, 0);
|
||||
|
||||
if (!line || !line->runs || line->runs->next) {
|
||||
kmscon_glyph_reset(glyph);
|
||||
glyph->type = GLYPH_LAYOUT;
|
||||
glyph->src.layout.layout = layout;
|
||||
} else {
|
||||
tmp = line->runs->data;
|
||||
str = pango_glyph_string_copy(tmp->glyphs);
|
||||
if (!str) {
|
||||
g_object_unref(layout);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
kmscon_glyph_reset(glyph);
|
||||
glyph->type = GLYPH_STR;
|
||||
|
||||
glyph->src.str.str = str;
|
||||
glyph->src.str.font =
|
||||
g_object_ref(tmp->item->analysis.font);
|
||||
glyph->src.str.ascent =
|
||||
PANGO_PIXELS_CEIL(pango_layout_get_baseline(layout));
|
||||
|
||||
g_object_unref(layout);
|
||||
}
|
||||
|
||||
glyph->width = PANGO_PIXELS(rec.width);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kmscon_font_factory_new(struct kmscon_font_factory **out,
|
||||
struct kmscon_symbol_table *st, struct kmscon_compositor *comp)
|
||||
{
|
||||
struct kmscon_font_factory *ff;
|
||||
|
||||
if (!out || !st || !comp)
|
||||
return -EINVAL;
|
||||
|
||||
ff = malloc(sizeof(*ff));
|
||||
if (!ff)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(ff, 0, sizeof(*ff));
|
||||
ff->ref = 1;
|
||||
ff->st = st;
|
||||
ff->comp = comp;
|
||||
ff->ctx = kmscon_compositor_get_context(comp);
|
||||
|
||||
kmscon_compositor_ref(ff->comp);
|
||||
kmscon_symbol_table_ref(ff->st);
|
||||
*out = ff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kmscon_font_factory_ref(struct kmscon_font_factory *ff)
|
||||
{
|
||||
if (!ff)
|
||||
return;
|
||||
|
||||
++ff->ref;
|
||||
}
|
||||
|
||||
void kmscon_font_factory_unref(struct kmscon_font_factory *ff)
|
||||
{
|
||||
if (!ff || !ff->ref)
|
||||
return;
|
||||
|
||||
if (--ff->ref)
|
||||
return;
|
||||
|
||||
kmscon_compositor_unref(ff->comp);
|
||||
kmscon_symbol_table_unref(ff->st);
|
||||
free(ff);
|
||||
}
|
||||
|
||||
/*
|
||||
* Measure font width
|
||||
* We simply draw all ASCII characters and use the average width as default
|
||||
* character width.
|
||||
* This has the side effect that all ASCII characters are already cached and the
|
||||
* console will speed up.
|
||||
*/
|
||||
static int measure_width(struct kmscon_font *font)
|
||||
{
|
||||
unsigned int i, num, width;
|
||||
int ret;
|
||||
kmscon_symbol_t ch;
|
||||
struct kmscon_glyph *glyph;
|
||||
|
||||
if (!font)
|
||||
return -EINVAL;
|
||||
|
||||
width = 0;
|
||||
num = 0;
|
||||
for (i = 0; i < 127; ++i) {
|
||||
ch = kmscon_symbol_make(i);
|
||||
|
||||
ret = kmscon_font_lookup(font, ch, &glyph);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
if (glyph->width > 0) {
|
||||
width += glyph->width;
|
||||
num++;
|
||||
}
|
||||
|
||||
kmscon_glyph_unref(glyph);
|
||||
}
|
||||
|
||||
if (!num)
|
||||
return -EFAULT;
|
||||
|
||||
font->width = width / num;
|
||||
log_debug("font: width is %u\n", font->width);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a new font
|
||||
* \height is the height in pixel that we have for each character.
|
||||
* Returns 0 on success and stores the new font in \out.
|
||||
* This backend is currently no longer available. See git-history for old pango
|
||||
* backends. Use FreeType instead.
|
||||
*/
|
||||
|
||||
int kmscon_font_factory_load(struct kmscon_font_factory *ff,
|
||||
struct kmscon_font **out, unsigned int width, unsigned int height)
|
||||
{
|
||||
struct kmscon_font *font;
|
||||
int ret;
|
||||
PangoFontDescription *desc;
|
||||
PangoFontMap *map;
|
||||
PangoLanguage *lang;
|
||||
cairo_font_options_t *opt;
|
||||
|
||||
if (!ff || !out || !height)
|
||||
return -EINVAL;
|
||||
|
||||
log_debug("font: new font (height %u)\n", height);
|
||||
|
||||
font = malloc(sizeof(*font));
|
||||
if (!font)
|
||||
return -ENOMEM;
|
||||
font->ref = 1;
|
||||
font->height = height;
|
||||
font->st = ff->st;
|
||||
|
||||
map = pango_cairo_font_map_get_default();
|
||||
if (!map) {
|
||||
ret = -EFAULT;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
font->ctx = pango_font_map_create_context(map);
|
||||
if (!font->ctx) {
|
||||
ret = -EFAULT;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
pango_context_set_base_dir(font->ctx, PANGO_DIRECTION_LTR);
|
||||
|
||||
desc = pango_font_description_from_string("monospace");
|
||||
if (!desc) {
|
||||
ret = -EFAULT;
|
||||
goto err_ctx;
|
||||
}
|
||||
|
||||
pango_font_description_set_absolute_size(desc, PANGO_SCALE * height);
|
||||
pango_context_set_font_description(font->ctx, desc);
|
||||
pango_font_description_free(desc);
|
||||
|
||||
lang = pango_language_get_default();
|
||||
if (!lang) {
|
||||
ret = -EFAULT;
|
||||
goto err_ctx;
|
||||
}
|
||||
|
||||
pango_context_set_language(font->ctx, lang);
|
||||
|
||||
if (!pango_cairo_context_get_font_options(font->ctx)) {
|
||||
opt = cairo_font_options_create();
|
||||
if (!opt) {
|
||||
ret = -EFAULT;
|
||||
goto err_ctx;
|
||||
}
|
||||
|
||||
pango_cairo_context_set_font_options(font->ctx, opt);
|
||||
cairo_font_options_destroy(opt);
|
||||
}
|
||||
|
||||
font->glyphs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
|
||||
NULL, (GDestroyNotify) kmscon_glyph_unref);
|
||||
if (!font->glyphs) {
|
||||
ret = -ENOMEM;
|
||||
goto err_ctx;
|
||||
}
|
||||
|
||||
ret = measure_width(font);
|
||||
if (ret)
|
||||
goto err_hash;
|
||||
|
||||
kmscon_symbol_table_ref(font->st);
|
||||
*out = font;
|
||||
|
||||
return 0;
|
||||
|
||||
err_hash:
|
||||
g_hash_table_unref(font->glyphs);
|
||||
err_ctx:
|
||||
g_object_unref(font->ctx);
|
||||
err_free:
|
||||
free(font);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void kmscon_font_ref(struct kmscon_font *font)
|
||||
{
|
||||
if (!font)
|
||||
return;
|
||||
|
||||
++font->ref;
|
||||
}
|
||||
|
||||
void kmscon_font_unref(struct kmscon_font *font)
|
||||
{
|
||||
if (!font || !font->ref)
|
||||
return;
|
||||
|
||||
if (--font->ref)
|
||||
return;
|
||||
|
||||
g_hash_table_unref(font->glyphs);
|
||||
g_object_unref(font->ctx);
|
||||
kmscon_symbol_table_unref(font->st);
|
||||
free(font);
|
||||
log_debug("font: destroying font\n");
|
||||
}
|
||||
|
||||
unsigned int kmscon_font_get_width(struct kmscon_font *font)
|
||||
{
|
||||
if (!font)
|
||||
return 0;
|
||||
|
||||
return font->width;
|
||||
}
|
||||
|
||||
unsigned int kmscon_font_get_height(struct kmscon_font *font)
|
||||
{
|
||||
if (!font)
|
||||
return 0;
|
||||
|
||||
return font->height;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get glyph for given key. If no glyph can be found in the hash-table, then a
|
||||
* new glyph is created and added to the hash-table.
|
||||
* Returns 0 on success and stores the glyph with a new reference in \out.
|
||||
*/
|
||||
static int kmscon_font_lookup(struct kmscon_font *font,
|
||||
kmscon_symbol_t key, struct kmscon_glyph **out)
|
||||
{
|
||||
struct kmscon_glyph *glyph;
|
||||
int ret;
|
||||
|
||||
if (!font || !out)
|
||||
return -EINVAL;
|
||||
|
||||
glyph = g_hash_table_lookup(font->glyphs, GUINT_TO_POINTER(key));
|
||||
if (!glyph) {
|
||||
ret = kmscon_glyph_new(&glyph, key);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = kmscon_glyph_set(glyph, font);
|
||||
if (ret)
|
||||
goto err_glyph;
|
||||
|
||||
g_hash_table_insert(font->glyphs, GUINT_TO_POINTER(key), glyph);
|
||||
}
|
||||
|
||||
kmscon_glyph_ref(glyph);
|
||||
*out = glyph;
|
||||
return 0;
|
||||
|
||||
err_glyph:
|
||||
kmscon_glyph_unref(glyph);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This draws a glyph for characters \ch into the given cairo context \cr.
|
||||
* The glyph will be drawn with the upper-left corner at x/y.
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int kmscon_font_draw(struct kmscon_font *font, kmscon_symbol_t ch, void *dcr,
|
||||
uint32_t x, uint32_t y)
|
||||
{
|
||||
struct kmscon_glyph *glyph;
|
||||
int ret;
|
||||
cairo_t *cr = dcr;
|
||||
|
||||
if (!font || !ch || !cr)
|
||||
return -EINVAL;
|
||||
|
||||
ret = kmscon_font_lookup(font, ch, &glyph);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (glyph->type) {
|
||||
case GLYPH_LAYOUT:
|
||||
cairo_move_to(cr, x, y);
|
||||
pango_cairo_update_layout(cr, glyph->src.layout.layout);
|
||||
pango_cairo_show_layout(cr, glyph->src.layout.layout);
|
||||
break;
|
||||
case GLYPH_STR:
|
||||
cairo_move_to(cr, x, y + glyph->src.str.ascent);
|
||||
pango_cairo_show_glyph_string(cr, glyph->src.str.font,
|
||||
glyph->src.str.str);
|
||||
break;
|
||||
default:
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
kmscon_glyph_unref(glyph);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#error "Pango backend is currently not supported"
|
||||
|
@ -140,7 +140,7 @@ void kmscon_context_clear(struct kmscon_context *ctx);
|
||||
void kmscon_context_draw_def(struct kmscon_context *ctx, float *vertices,
|
||||
float *colors, size_t num);
|
||||
void kmscon_context_draw_tex(struct kmscon_context *ctx, const float *vertices,
|
||||
const float *texcoords, size_t num, unsigned int tex);
|
||||
const float *texcoords, size_t num, unsigned int tex, const float *m);
|
||||
unsigned int kmscon_context_new_tex(struct kmscon_context *ctx);
|
||||
void kmscon_context_free_tex(struct kmscon_context *ctx, unsigned int tex);
|
||||
void kmscon_context_set_tex(struct kmscon_context *ctx, unsigned int tex,
|
||||
|
@ -183,7 +183,15 @@ static void clear_gl_error()
|
||||
/* return true if there is a pending GL error */
|
||||
static bool has_gl_error()
|
||||
{
|
||||
return glGetError() != GL_NO_ERROR;
|
||||
GLenum err;
|
||||
|
||||
err = glGetError();
|
||||
if (err != GL_NO_ERROR) {
|
||||
log_err("context: GL error %d\n", err);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* external shader sources; generated during build */
|
||||
@ -643,21 +651,19 @@ void kmscon_context_draw_def(struct kmscon_context *ctx, float *vertices,
|
||||
}
|
||||
|
||||
void kmscon_context_draw_tex(struct kmscon_context *ctx, const float *vertices,
|
||||
const float *texcoords, size_t num, unsigned int tex)
|
||||
const float *texcoords, size_t num, unsigned int tex, const float *m)
|
||||
{
|
||||
static const float m[16] = { 1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1 };
|
||||
float mat[16];
|
||||
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
kmscon_m4_transp_dest(mat, m);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
|
||||
ctx->proc_use_program(ctx->tex_program);
|
||||
ctx->proc_uniform_matrix_4fv(ctx->tex_uni_projection, 1, GL_FALSE, m);
|
||||
ctx->proc_uniform_matrix_4fv(ctx->tex_uni_projection, 1, GL_FALSE, mat);
|
||||
ctx->proc_uniform_1i(ctx->tex_uni_texture, 0);
|
||||
|
||||
ctx->proc_vertex_attrib_pointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
|
@ -71,7 +71,6 @@ static void draw_all(struct kmscon_idle *idle, void *data)
|
||||
|
||||
ctx = kmscon_compositor_get_context(term->comp);
|
||||
kmscon_eloop_rm_idle(idle);
|
||||
kmscon_console_draw(term->console);
|
||||
|
||||
iter = term->outputs;
|
||||
for (; iter; iter = iter->next) {
|
||||
|
@ -118,7 +118,6 @@ static void map_outputs(struct console *con)
|
||||
if (kmscon_compositor_is_asleep(con->comp))
|
||||
return;
|
||||
|
||||
kmscon_console_draw(con->con);
|
||||
ctx = kmscon_compositor_get_context(con->comp);
|
||||
|
||||
iter = kmscon_compositor_get_outputs(con->comp);
|
||||
|
Loading…
x
Reference in New Issue
Block a user