Add built-in font sizes (8, 12, 16) to terminal

This commit is contained in:
Norman Feske 2012-10-09 15:02:20 +02:00
parent fb452ce6ba
commit 6fba73ee1d
7 changed files with 105 additions and 55 deletions

View File

@ -1,8 +1,3 @@
if {[have_spec linux]} {
puts "\nLinux not supported because of missing UART driver\n"
exit 0
}
build { build {
core init drivers/timer core init drivers/timer
server/terminal test/terminal_echo server/terminal test/terminal_echo
@ -72,6 +67,10 @@ append config {
<start name="terminal"> <start name="terminal">
<resource name="RAM" quantum="2M"/> <resource name="RAM" quantum="2M"/>
<provides><service name="Terminal"/></provides> <provides><service name="Terminal"/></provides>
<config>
<!-- supported built-in font sizes are 8, 12, and 16 -->
<font size="12" />
</config>
</start> </start>
<start name="test-terminal_echo"> <start name="test-terminal_echo">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>

View File

@ -97,22 +97,34 @@ inline Pixel_rgb565 mix(Pixel_rgb565 p1, Pixel_rgb565 p2, int alpha)
return res; return res;
} }
/*
* Font initialization
*/
extern char _binary_mono_tff_start;
static Font mono_font (&_binary_mono_tff_start);
static Font *fonts[4] = { &mono_font, &mono_font,
&mono_font, &mono_font };
enum Font_face { FONT_REGULAR, FONT_ITALIC, FONT_BOLD, FONT_BOLD_ITALIC };
static Color color_palette[2*8]; static Color color_palette[2*8];
class Font_family
{
private:
Font const &_regular;
public:
enum Face { REGULAR, ITALIC, BOLD, BOLD_ITALIC };
Font_family(Font const &regular /* ...to be extended */ )
: _regular(regular) { }
/**
* Return font for specified face
*
* For now, we do not support font faces other than regular.
*/
Font const *font(Face) const { return &_regular; }
unsigned cell_width() const { return _regular.str_w("m"); }
unsigned cell_height() const { return _regular.str_h("m"); }
};
struct Char_cell struct Char_cell
{ {
unsigned char attr; unsigned char attr;
@ -125,7 +137,8 @@ struct Char_cell
Char_cell() : attr(0), ascii(0) { } Char_cell() : attr(0), ascii(0) { }
Char_cell(unsigned char c, Font_face f, int colidx, bool inv, bool highlight) Char_cell(unsigned char c, Font_family::Face f,
int colidx, bool inv, bool highlight)
: :
attr(f | (colidx & ATTR_COLIDX_MASK) attr(f | (colidx & ATTR_COLIDX_MASK)
| (inv ? ATTR_INVERSE : 0) | (inv ? ATTR_INVERSE : 0)
@ -133,7 +146,7 @@ struct Char_cell
ascii(c) ascii(c)
{ } { }
Font_face font_face() const { return (Font_face)(attr & 0x3); } Font_family::Face font_face() const { return (Font_family::Face)(attr & 0x3); }
int colidx() const { return attr & ATTR_COLIDX_MASK; } int colidx() const { return attr & ATTR_COLIDX_MASK; }
bool inverse() const { return attr & ATTR_INVERSE; } bool inverse() const { return attr & ATTR_INVERSE; }
@ -380,7 +393,7 @@ class Char_cell_array_character_screen : public Terminal::Character_screen
if (c.ascii() > 0x10) { if (c.ascii() > 0x10) {
Cursor_guard guard(*this); Cursor_guard guard(*this);
_char_cell_array.set_cell(_cursor_pos.x, _cursor_pos.y, _char_cell_array.set_cell(_cursor_pos.x, _cursor_pos.y,
Char_cell(c.ascii(), FONT_REGULAR, Char_cell(c.ascii(), Font_family::REGULAR,
_color_index, _inverse, _highlight)); _color_index, _inverse, _highlight));
_cursor_pos.x++; _cursor_pos.x++;
} }
@ -502,7 +515,7 @@ class Char_cell_array_character_screen : public Terminal::Character_screen
for (int i = 0; i < v; i++, _cursor_pos.x++) for (int i = 0; i < v; i++, _cursor_pos.x++)
_char_cell_array.set_cell(_cursor_pos.x, _cursor_pos.y, _char_cell_array.set_cell(_cursor_pos.x, _cursor_pos.y,
Char_cell(' ', FONT_REGULAR, Char_cell(' ', Font_family::REGULAR,
_color_index, _inverse, _highlight)); _color_index, _inverse, _highlight));
} }
@ -728,10 +741,12 @@ template <typename PT>
static void convert_char_array_to_pixels(Char_cell_array *cell_array, static void convert_char_array_to_pixels(Char_cell_array *cell_array,
PT *fb_base, PT *fb_base,
unsigned fb_width, unsigned fb_width,
unsigned fb_height) unsigned fb_height,
Font_family const &font_family)
{ {
unsigned glyph_height = mono_font.img_h, Font const &regular_font = *font_family.font(Font_family::REGULAR);
glyph_step_x = mono_font.wtab['m']; unsigned glyph_height = regular_font.img_h,
glyph_step_x = regular_font.wtab['m'];
unsigned y = 0; unsigned y = 0;
for (unsigned line = 0; line < cell_array->num_lines(); line++) { for (unsigned line = 0; line < cell_array->num_lines(); line++) {
@ -745,15 +760,15 @@ static void convert_char_array_to_pixels(Char_cell_array *cell_array,
for (unsigned column = 0; column < cell_array->num_cols(); column++) { for (unsigned column = 0; column < cell_array->num_cols(); column++) {
Char_cell cell = cell_array->get_cell(column, line); Char_cell cell = cell_array->get_cell(column, line);
Font *font = fonts[cell.font_face()]; Font const *font = font_family.font(cell.font_face());
unsigned char ascii = cell.ascii; unsigned char ascii = cell.ascii;
if (ascii == 0) if (ascii == 0)
ascii = ' '; ascii = ' ';
unsigned char *glyph_base = font->img + font->otab[ascii]; unsigned char const *glyph_base = font->img + font->otab[ascii];
unsigned glyph_width = mono_font.wtab[ascii]; unsigned glyph_width = regular_font.wtab[ascii];
if (x + glyph_width >= fb_width) break; if (x + glyph_width >= fb_width) break;
@ -847,6 +862,8 @@ namespace Terminal {
Terminal::Position _last_cursor_pos; Terminal::Position _last_cursor_pos;
Font_family const *_font_family;
/** /**
* Initialize framebuffer-related attributes * Initialize framebuffer-related attributes
*/ */
@ -868,7 +885,8 @@ namespace Terminal {
Session_component(Read_buffer *read_buffer, Session_component(Read_buffer *read_buffer,
Framebuffer::Session *framebuffer, Framebuffer::Session *framebuffer,
Genode::size_t io_buffer_size, Genode::size_t io_buffer_size,
Flush_callback_registry &flush_callback_registry) Flush_callback_registry &flush_callback_registry,
Font_family const &font_family)
: :
_read_buffer(read_buffer), _framebuffer(framebuffer), _read_buffer(read_buffer), _framebuffer(framebuffer),
_flush_callback_registry(flush_callback_registry), _flush_callback_registry(flush_callback_registry),
@ -877,8 +895,8 @@ namespace Terminal {
_fb_ds_cap(_init_fb()), _fb_ds_cap(_init_fb()),
/* take size of space character as character cell size */ /* take size of space character as character cell size */
_char_width(mono_font.str_w("m")), _char_width(font_family.cell_width()),
_char_height(mono_font.str_h("m")), _char_height(font_family.cell_height()),
/* compute number of characters fitting on the framebuffer */ /* compute number of characters fitting on the framebuffer */
_columns(_fb_mode.width()/_char_width), _columns(_fb_mode.width()/_char_width),
@ -887,7 +905,9 @@ namespace Terminal {
_fb_addr(Genode::env()->rm_session()->attach(_fb_ds_cap)), _fb_addr(Genode::env()->rm_session()->attach(_fb_ds_cap)),
_char_cell_array(_columns, _lines, Genode::env()->heap()), _char_cell_array(_columns, _lines, Genode::env()->heap()),
_char_cell_array_character_screen(_char_cell_array), _char_cell_array_character_screen(_char_cell_array),
_decoder(_char_cell_array_character_screen) _decoder(_char_cell_array_character_screen),
_font_family(&font_family)
{ {
using namespace Genode; using namespace Genode;
@ -913,7 +933,8 @@ namespace Terminal {
convert_char_array_to_pixels<Pixel_rgb565>(&_char_cell_array, convert_char_array_to_pixels<Pixel_rgb565>(&_char_cell_array,
(Pixel_rgb565 *)_fb_addr, (Pixel_rgb565 *)_fb_addr,
_fb_mode.width(), _fb_mode.width(),
_fb_mode.height()); _fb_mode.height(),
*_font_family);
int first_dirty_line = 10000, int first_dirty_line = 10000,
@ -1003,6 +1024,7 @@ namespace Terminal {
Read_buffer *_read_buffer; Read_buffer *_read_buffer;
Framebuffer::Session *_framebuffer; Framebuffer::Session *_framebuffer;
Flush_callback_registry &_flush_callback_registry; Flush_callback_registry &_flush_callback_registry;
Font_family const &_font_family;
protected: protected:
@ -1019,7 +1041,8 @@ namespace Terminal {
new (md_alloc()) Session_component(_read_buffer, new (md_alloc()) Session_component(_read_buffer,
_framebuffer, _framebuffer,
io_buffer_size, io_buffer_size,
_flush_callback_registry); _flush_callback_registry,
_font_family);
return session; return session;
} }
@ -1032,11 +1055,13 @@ namespace Terminal {
Genode::Allocator *md_alloc, Genode::Allocator *md_alloc,
Read_buffer *read_buffer, Read_buffer *read_buffer,
Framebuffer::Session *framebuffer, Framebuffer::Session *framebuffer,
Flush_callback_registry &flush_callback_registry) Flush_callback_registry &flush_callback_registry,
Font_family const &font_family)
: :
Genode::Root_component<Session_component>(ep, md_alloc), Genode::Root_component<Session_component>(ep, md_alloc),
_read_buffer(read_buffer), _framebuffer(framebuffer), _read_buffer(read_buffer), _framebuffer(framebuffer),
_flush_callback_registry(flush_callback_registry) _flush_callback_registry(flush_callback_registry),
_font_family(font_family)
{ } { }
}; };
} }
@ -1370,12 +1395,39 @@ int main(int, char **)
color_palette[i + 8] = col; color_palette[i + 8] = col;
} }
/* built-in fonts */
extern char _binary_notix_8_tff_start;
extern char _binary_terminus_12_tff_start;
extern char _binary_terminus_16_tff_start;
/* pick font according to config file */
char const *font_data = &_binary_terminus_16_tff_start;
try {
size_t font_size = 16;
config()->xml_node().sub_node("font")
.attribute("size").value(&font_size);
switch (font_size) {
case 8: font_data = &_binary_notix_8_tff_start; break;
case 12: font_data = &_binary_terminus_12_tff_start; break;
case 16: font_data = &_binary_terminus_16_tff_start; break;
default: break;
}
} catch (...) { }
static Font font(font_data);
static Font_family font_family(font);
printf("cell size is %dx%d\n", (int)font_family.cell_width(),
(int)font_family.cell_height());
static Terminal::Flush_callback_registry flush_callback_registry; static Terminal::Flush_callback_registry flush_callback_registry;
/* create root interface for service */ /* create root interface for service */
static Terminal::Root_component root(&ep, &sliced_heap, static Terminal::Root_component root(&ep, &sliced_heap,
&read_buffer, &framebuffer, &read_buffer, &framebuffer,
flush_callback_registry); flush_callback_registry,
font_family);
/* announce service at our parent */ /* announce service at our parent */
env()->parent()->announce(ep.manage(&root)); env()->parent()->announce(ep.manage(&root));
@ -1393,8 +1445,6 @@ int main(int, char **)
* Read keyboard layout from config file * Read keyboard layout from config file
*/ */
try { try {
using namespace Genode;
if (config()->xml_node().sub_node("keyboard") if (config()->xml_node().sub_node("keyboard")
.attribute("layout").has_value("de")) { .attribute("layout").has_value("de")) {

Binary file not shown.

View File

@ -1,4 +1,4 @@
TARGET = terminal TARGET = terminal
LIBS = cxx env server signal LIBS = cxx env server signal
SRC_CC = main.cc SRC_CC = main.cc
SRC_BIN = mono.tff SRC_BIN = $(notdir $(wildcard $(PRG_DIR)/*.tff))

Binary file not shown.

View File

@ -114,6 +114,7 @@ append config {
<provides><service name="Terminal"/></provides> <provides><service name="Terminal"/></provides>
<config> <config>
<keyboard layout="de"/> <keyboard layout="de"/>
<font size="12" />
</config> </config>
</start> </start>
<start name="ram_fs"> <start name="ram_fs">