mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
os: reworked nitpicker_gfx/text_painter.h
This patch improves the `Text_painter` utility that is commonly used by native Genode components to render text: - Support for subpixel positioning - Generic interface for accessing font data - Basic UTF-8 support Since the change decouples the font format from the 'Text_painter' and changes the API to use the sub-pixel accurate 'Text_painter::Position' type, all users of the utility require an adaptation. Fixes #2716
This commit is contained in:
parent
4c0f70fbcb
commit
3778558608
@ -102,7 +102,7 @@ class Scout::Canvas : public Canvas_base
|
||||
{
|
||||
char buf[len + 1];
|
||||
Genode::strncpy(buf, str, len + 1);
|
||||
Text_painter::paint(_surface, Point(x, y), *font, color, buf);
|
||||
Text_painter::paint(_surface, Text_painter::Position(x, y), *font, color, buf);
|
||||
}
|
||||
|
||||
void draw_box(int x, int y, int w, int h, Color c)
|
||||
|
@ -168,8 +168,8 @@ class Loadbar : public Scout::Parent_element
|
||||
{
|
||||
if (!_font) return;
|
||||
_txt = txt;
|
||||
_txt_w = _font->str_w(_txt, Scout::strlen(_txt));
|
||||
_txt_h = _font->str_h(_txt, Scout::strlen(_txt));
|
||||
_txt_w = _font->string_width(_txt, Scout::strlen(_txt)).decimal();
|
||||
_txt_h = _font->bounding_box().h();
|
||||
_txt_len = Scout::strlen(_txt);
|
||||
}
|
||||
|
||||
|
@ -36,8 +36,8 @@ class Section : public Scout::Parent_element
|
||||
|
||||
char const *_txt;
|
||||
Scout::Font *_font;
|
||||
int _txt_w = _font->str_w(_txt, Scout::strlen(_txt));
|
||||
int _txt_h = _font->str_h(_txt, Scout::strlen(_txt));
|
||||
int _txt_w = _font->string_width(_txt, Scout::strlen(_txt)).decimal();
|
||||
int _txt_h = _font->bounding_box().h();
|
||||
int _txt_len = Scout::strlen(_txt);
|
||||
int _r_add;
|
||||
|
||||
|
@ -232,8 +232,10 @@ Token::Token(Style *style, const char *str, int len)
|
||||
_flags.takes_focus = 0;
|
||||
|
||||
if (!_style) return;
|
||||
_min_size = Area(_style->font->str_w(str, len) + _style->font->str_w(" ", 1),
|
||||
_style->font->str_h(str, len));
|
||||
|
||||
_min_size = Area(_style->font->string_width(str, len).decimal() +
|
||||
_style->font->string_width(" ").decimal(),
|
||||
_style->font->bounding_box().h());
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,6 +14,10 @@
|
||||
#ifndef _STYLES_H_
|
||||
#define _STYLES_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <nitpicker_gfx/tff_font.h>
|
||||
|
||||
/* local includes */
|
||||
#include "elements.h"
|
||||
|
||||
extern char _binary_mono16_tff_start[];
|
||||
@ -26,29 +30,33 @@ extern char _binary_vera24_tff_start[];
|
||||
|
||||
namespace Scout {
|
||||
|
||||
static Font label_font (&_binary_verabi10_tff_start[0]);
|
||||
static Font default_font (&_binary_vera16_tff_start[0]);
|
||||
static Font italic_font (&_binary_verai16_tff_start[0]);
|
||||
static Font mono_font (&_binary_mono16_tff_start[0]);
|
||||
static Font chapter_font (&_binary_vera24_tff_start[0]);
|
||||
static Font section_font (&_binary_vera20_tff_start[0]);
|
||||
static Font subsection_font (&_binary_vera18_tff_start[0]);
|
||||
|
||||
static Color default_color (0, 0, 0);
|
||||
static Color text_color (20, 20, 20);
|
||||
static Color verbatim_bgcol (0, 0, 0, 26);
|
||||
|
||||
static Style plain_style (&default_font, text_color, 0);
|
||||
static Style bold_style (&default_font, text_color, Style::ATTR_BOLD);
|
||||
static Style mono_style (&mono_font, text_color, 0);
|
||||
static Style italic_style (&italic_font, text_color, 0);
|
||||
|
||||
static Style link_style (&default_font, Color(0, 0, 255), 0);
|
||||
|
||||
static Style chapter_style (&chapter_font, default_color, 0);
|
||||
static Style section_style (§ion_font, default_color, 0);
|
||||
static Style subsection_style (&subsection_font, default_color, 0);
|
||||
static Style navbar_style (&default_font, Color(0, 0, 0, 127), 0);
|
||||
static Tff_font::Static_glyph_buffer<4096> _glyph_buffer { };
|
||||
|
||||
static Tff_font label_font { &_binary_verabi10_tff_start, _glyph_buffer };
|
||||
static Tff_font default_font { &_binary_vera16_tff_start, _glyph_buffer };
|
||||
static Tff_font italic_font { &_binary_verai16_tff_start, _glyph_buffer };
|
||||
static Tff_font mono_font { &_binary_mono16_tff_start, _glyph_buffer };
|
||||
static Tff_font chapter_font { &_binary_vera24_tff_start, _glyph_buffer };
|
||||
static Tff_font section_font { &_binary_vera20_tff_start, _glyph_buffer };
|
||||
static Tff_font subsection_font { &_binary_vera18_tff_start, _glyph_buffer };
|
||||
|
||||
static Tff_font &title_font = subsection_font;
|
||||
|
||||
static Color default_color { 0, 0, 0 };
|
||||
static Color text_color { 20, 20, 20 };
|
||||
static Color verbatim_bgcol { 0, 0, 0, 26 };
|
||||
|
||||
static Style plain_style { &default_font, text_color, 0 };
|
||||
static Style bold_style { &default_font, text_color, Style::ATTR_BOLD };
|
||||
static Style mono_style { &mono_font, text_color, 0 };
|
||||
static Style italic_style { &italic_font, text_color, 0 };
|
||||
|
||||
static Style link_style { &default_font, Color(0, 0, 255), 0 };
|
||||
|
||||
static Style chapter_style { &chapter_font, default_color, 0 };
|
||||
static Style section_style { §ion_font, default_color, 0 };
|
||||
static Style subsection_style { &subsection_font, default_color, 0 };
|
||||
static Style navbar_style { &default_font, Color(0, 0, 0, 127), 0 };
|
||||
}
|
||||
|
||||
#endif /* _STYLES_H_ */
|
||||
|
@ -15,15 +15,11 @@
|
||||
#define _TITLEBAR_H_
|
||||
|
||||
#include "widgets.h"
|
||||
|
||||
#define TITLE_TFF _binary_vera18_tff_start
|
||||
extern char TITLE_TFF[];
|
||||
#include "styles.h"
|
||||
|
||||
namespace Scout { template <typename PT> class Titlebar; }
|
||||
|
||||
|
||||
static Scout::Font title_font(TITLE_TFF);
|
||||
|
||||
template <typename PT>
|
||||
class Scout::Titlebar : public Parent_element
|
||||
{
|
||||
@ -47,8 +43,8 @@ class Scout::Titlebar : public Parent_element
|
||||
void text(const char *txt)
|
||||
{
|
||||
_txt = txt ? txt : "Scout";
|
||||
_txt_w = title_font.str_w(_txt, strlen(_txt));
|
||||
_txt_h = title_font.str_h(_txt, strlen(_txt));
|
||||
_txt_w = title_font.string_width(_txt, strlen(_txt)).decimal();
|
||||
_txt_h = title_font.bounding_box().h();
|
||||
_txt_len = strlen(_txt);
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@
|
||||
/*
|
||||
* Nitpicker's graphics backend
|
||||
*/
|
||||
#include <nitpicker_gfx/text_painter.h>
|
||||
#include <nitpicker_gfx/box_painter.h>
|
||||
#include <nitpicker_gfx/tff_font.h>
|
||||
|
||||
|
||||
enum { LOG_W = 80 }; /* number of visible characters per line */
|
||||
@ -41,10 +41,9 @@ typedef Genode::Color Color;
|
||||
|
||||
|
||||
/*
|
||||
* Font initialization
|
||||
* Builtin font
|
||||
*/
|
||||
extern char _binary_mono_tff_start;
|
||||
Font default_font(&_binary_mono_tff_start);
|
||||
extern char _binary_mono_tff_start[];
|
||||
|
||||
|
||||
namespace Nitlog {
|
||||
@ -89,7 +88,8 @@ class Canvas : public Canvas_base
|
||||
void draw_string(Point p, Font const &font, Color color,
|
||||
char const *sstr)
|
||||
{
|
||||
Text_painter::paint(_surface, p, font, color, sstr);
|
||||
Text_painter::paint(_surface, Text_painter::Position(p.x(), p.y()),
|
||||
font, color, sstr);
|
||||
}
|
||||
|
||||
void draw_box(Rect rect, Color color)
|
||||
@ -145,7 +145,7 @@ class Log_entry
|
||||
* marks a transition of output from one session to another. This
|
||||
* information is used to separate sessions visually.
|
||||
*/
|
||||
void draw(Canvas_base &canvas, int y, int new_section = false)
|
||||
void draw(Canvas_base &canvas, Font const &font, int y, int new_section = false)
|
||||
{
|
||||
Color label_fgcol = Color(Genode::min(255, _color.r + 200),
|
||||
Genode::min(255, _color.g + 200),
|
||||
@ -155,12 +155,12 @@ class Log_entry
|
||||
Color text_bgcol = Color(_color.r / 2, _color.g / 2, _color.b / 2);
|
||||
|
||||
/* calculate label dimensions */
|
||||
int label_w = default_font.str_w(_label);
|
||||
int label_h = default_font.str_h(_label);
|
||||
int label_w = font.string_width(_label).decimal();
|
||||
int label_h = font.bounding_box().h();
|
||||
|
||||
if (new_section) {
|
||||
canvas.draw_box(Rect(Point(1, y), Area(label_w + 2, label_h - 1)), label_bgcol);
|
||||
canvas.draw_string(Point(1, y - 1), default_font, label_fgcol, _label);
|
||||
canvas.draw_string(Point(1, y - 1), font, label_fgcol, _label);
|
||||
canvas.draw_box(Rect(Point(1, y + label_h - 1), Area(label_w + 2, 1)), Color(0, 0, 0));
|
||||
canvas.draw_box(Rect(Point(label_w + 2, y), Area(1, label_h - 1)), _color);
|
||||
canvas.draw_box(Rect(Point(label_w + 3, y), Area(1, label_h - 1)), Color(0, 0, 0));
|
||||
@ -170,7 +170,7 @@ class Log_entry
|
||||
canvas.draw_box(Rect(Point(1, y), Area(1000, label_h)), text_bgcol);
|
||||
|
||||
/* draw log text */
|
||||
canvas.draw_string(Point(label_w + 6, y), default_font, text_fgcol, _text);
|
||||
canvas.draw_string(Point(label_w + 6, y), font, text_fgcol, _text);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,6 +186,7 @@ class Log_window
|
||||
private:
|
||||
|
||||
Canvas_base &_canvas;
|
||||
Font const &_font;
|
||||
Log_entry _entries[LOG_H]; /* log entries */
|
||||
int _dst_entry = 0; /* destination entry for next write */
|
||||
int _view_pos = 0; /* current view port on the entry array */
|
||||
@ -199,7 +200,8 @@ class Log_window
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Log_window(Canvas_base &canvas) : _canvas(canvas) { }
|
||||
Log_window(Canvas_base &canvas, Font const &font)
|
||||
: _canvas(canvas), _font(font) { }
|
||||
|
||||
/**
|
||||
* Write log entry
|
||||
@ -241,12 +243,12 @@ class Log_window
|
||||
_dirty = false;
|
||||
}
|
||||
|
||||
int line_h = default_font.str_h(" ");
|
||||
int line_h = _font.bounding_box().h();
|
||||
int curr_session_id = -1;
|
||||
|
||||
for (int i = 0, y = 0; i < LOG_H; i++, y += line_h) {
|
||||
Log_entry *le = &_entries[(i + _view_pos) % LOG_H];
|
||||
le->draw(_canvas, y, curr_session_id != le->id());
|
||||
le->draw(_canvas, _font, y, curr_session_id != le->id());
|
||||
curr_session_id = le->id();
|
||||
}
|
||||
|
||||
@ -394,9 +396,13 @@ struct Nitlog::Main
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
Tff_font::Static_glyph_buffer<4096> _glyph_buffer { };
|
||||
|
||||
Tff_font _font { _binary_mono_tff_start, _glyph_buffer };
|
||||
|
||||
/* calculate size of log view in pixels */
|
||||
unsigned const _win_w = default_font.str_w(" ") * LOG_W + 2;
|
||||
unsigned const _win_h = default_font.str_h(" ") * LOG_H + 2;
|
||||
unsigned const _win_w = _font.bounding_box().w() * LOG_W + 2;
|
||||
unsigned const _win_h = _font.bounding_box().h() * LOG_H + 2;
|
||||
|
||||
/* init sessions to the required external services */
|
||||
Nitpicker::Connection _nitpicker { _env };
|
||||
@ -418,7 +424,7 @@ struct Nitlog::Main
|
||||
Canvas<Pixel_rgb565> _canvas { _fb_ds.local_addr<Pixel_rgb565>(),
|
||||
::Area(_win_w, _win_h) };
|
||||
|
||||
Log_window _log_window { _canvas };
|
||||
Log_window _log_window { _canvas, _font };
|
||||
|
||||
void _init_canvas()
|
||||
{
|
||||
|
@ -83,7 +83,8 @@ class Decorator::Canvas : public Decorator::Canvas_base
|
||||
void draw_text(Point pos, Font const &font,
|
||||
Color color, char const *string) override
|
||||
{
|
||||
Text_painter::paint(_surface, pos, font, color, string);
|
||||
Text_painter::paint(_surface, Text_painter::Position(pos.x(), pos.y()),
|
||||
font, color, string);
|
||||
}
|
||||
|
||||
void draw_texture(Point pos, Texture_id id)
|
||||
|
@ -11,6 +11,9 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <nitpicker_gfx/tff_font.h>
|
||||
|
||||
/* local includes */
|
||||
#include "canvas.h"
|
||||
|
||||
@ -26,9 +29,10 @@ extern char _binary_droidsansb10_tff_start[];
|
||||
*/
|
||||
Decorator::Font &Decorator::default_font()
|
||||
{
|
||||
static Font font(_binary_droidsansb10_tff_start);
|
||||
static Tff_font::Static_glyph_buffer<4096> glyph_buffer { };
|
||||
|
||||
static Tff_font font { _binary_droidsansb10_tff_start, glyph_buffer };
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -122,8 +122,8 @@ void Decorator::Window::draw(Decorator::Canvas_base &canvas,
|
||||
|
||||
char const * const text = _title.string();
|
||||
|
||||
Area const label_area(default_font().str_w(text),
|
||||
default_font().str_h(text));
|
||||
Area const label_area(default_font().string_width(text).decimal(),
|
||||
default_font().bounding_box().h());
|
||||
|
||||
/*
|
||||
* Position the text in the center of the window.
|
||||
|
@ -44,8 +44,8 @@ struct Menu_view::Label_widget : Widget
|
||||
if (!font)
|
||||
return Area(0, 0);
|
||||
|
||||
return Area(font->str_w(text.string()),
|
||||
font->str_h(text.string()));
|
||||
return Area(font->string_width(text.string()).decimal(),
|
||||
font->bounding_box().h());
|
||||
}
|
||||
|
||||
void draw(Surface<Pixel_rgb888> &pixel_surface,
|
||||
@ -59,13 +59,15 @@ struct Menu_view::Label_widget : Widget
|
||||
int const dx = (int)geometry().w() - text_size.w(),
|
||||
dy = (int)geometry().h() - text_size.h();
|
||||
|
||||
Point const centered = Point(dx/2, dy/2);
|
||||
Point const centered = at + Point(dx/2, dy/2);
|
||||
|
||||
Text_painter::paint(pixel_surface, at + centered, *font,
|
||||
Color(0, 0, 0), text.string());
|
||||
Text_painter::paint(pixel_surface,
|
||||
Text_painter::Position(centered.x(), centered.y()),
|
||||
*font, Color(0, 0, 0), text.string());
|
||||
|
||||
Text_painter::paint(alpha_surface, at + centered, *font,
|
||||
Color(255, 255, 255), text.string());
|
||||
Text_painter::paint(alpha_surface,
|
||||
Text_painter::Position(centered.x(), centered.y()),
|
||||
*font, Color(255, 255, 255), text.string());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -14,6 +14,9 @@
|
||||
#ifndef _STYLE_DATABASE_H_
|
||||
#define _STYLE_DATABASE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <nitpicker_gfx/tff_font.h>
|
||||
|
||||
/* gems includes */
|
||||
#include <gems/file.h>
|
||||
#include <gems/png_image.h>
|
||||
@ -55,8 +58,12 @@ class Menu_view::Style_database
|
||||
struct Font_entry : List<Font_entry>::Element
|
||||
{
|
||||
String<PATH_MAX_LEN> path;
|
||||
File tff_file;
|
||||
Text_painter::Font font;
|
||||
|
||||
File tff_file;
|
||||
|
||||
Tff_font::Allocated_glyph_buffer glyph_buffer;
|
||||
|
||||
Tff_font font;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -67,7 +74,8 @@ class Menu_view::Style_database
|
||||
:
|
||||
path(path),
|
||||
tff_file(path, alloc),
|
||||
font(tff_file.data<char>())
|
||||
glyph_buffer(tff_file.data<char>(), alloc),
|
||||
font(tff_file.data<char>(), glyph_buffer)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/texture_rgb888.h>
|
||||
#include <nitpicker_gfx/text_painter.h>
|
||||
#include <nitpicker_gfx/tff_font.h>
|
||||
#include <util/xml_node.h>
|
||||
#include <decorator/xml_utils.h>
|
||||
|
||||
@ -90,7 +90,8 @@ texture_by_element_type(Genode::Ram_session &ram, Genode::Region_map &rm,
|
||||
static Text_painter::Font const &title_font(Genode::Allocator &alloc)
|
||||
{
|
||||
static File tff_file("theme/font.tff", alloc);
|
||||
static Text_painter::Font font(tff_file.data<char>());
|
||||
static Tff_font::Allocated_glyph_buffer glyph_buffer(tff_file.data<char>(), alloc);
|
||||
static Tff_font font(tff_file.data<char>(), glyph_buffer);
|
||||
|
||||
return font;
|
||||
}
|
||||
@ -267,13 +268,14 @@ void Decorator::Theme::draw_title(Decorator::Pixel_surface &pixel_surface,
|
||||
|
||||
Text_painter::Font const &font = title_font(_alloc);
|
||||
|
||||
Area const label_area(font.str_w(title), font.str_h(title));
|
||||
Area const label_area(font.string_width(title).decimal(),
|
||||
font.bounding_box().h());
|
||||
Rect const surface_rect(Point(0, 0), pixel_surface.size());
|
||||
Rect const title_rect = absolute(title_geometry(), surface_rect);
|
||||
Point const centered_text_pos = title_rect.center(label_area) - Point(0, 1);
|
||||
Point const pos = title_rect.center(label_area) - Point(0, 1);
|
||||
|
||||
Text_painter::paint(pixel_surface, centered_text_pos, font,
|
||||
Genode::Color(0, 0, 0), title);
|
||||
Text_painter::paint(pixel_surface, Text_painter::Position(pos.x(), pos.y()),
|
||||
font, Genode::Color(0, 0, 0), title);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* \brief Function for drawing the glyphs of terminal characters
|
||||
* \author Norman Feske
|
||||
* \date 2018-02-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _DRAW_GLYPH_H_
|
||||
#define _DRAW_GLYPH_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/pixel_rgb565.h>
|
||||
|
||||
template <typename PT>
|
||||
inline void draw_glyph(Genode::Color fg_color,
|
||||
Genode::Color bg_color,
|
||||
const unsigned char *glyph_base,
|
||||
unsigned glyph_width,
|
||||
unsigned glyph_img_width,
|
||||
unsigned glyph_img_height,
|
||||
unsigned cell_width,
|
||||
PT *fb_base,
|
||||
unsigned fb_width)
|
||||
{
|
||||
PT fg_pixel(fg_color.r, fg_color.g, fg_color.b);
|
||||
PT bg_pixel(bg_color.r, bg_color.g, bg_color.b);
|
||||
|
||||
unsigned const horizontal_gap = cell_width
|
||||
- Genode::min(glyph_width, cell_width);
|
||||
|
||||
unsigned const left_gap = horizontal_gap / 2;
|
||||
unsigned const right_gap = horizontal_gap - left_gap;
|
||||
|
||||
/*
|
||||
* Clear gaps to the left and right of the character if the character's
|
||||
* with is smaller than the cell width.
|
||||
*/
|
||||
if (horizontal_gap) {
|
||||
|
||||
PT *line = fb_base;
|
||||
for (unsigned y = 0 ; y < glyph_img_height; y++, line += fb_width) {
|
||||
|
||||
for (unsigned x = 0; x < left_gap; x++)
|
||||
line[x] = bg_pixel;
|
||||
|
||||
for (unsigned x = cell_width - right_gap; x < cell_width; x++)
|
||||
line[x] = bg_pixel;
|
||||
}
|
||||
}
|
||||
|
||||
/* center glyph horizontally within its cell */
|
||||
fb_base += left_gap;
|
||||
|
||||
for (unsigned y = 0 ; y < glyph_img_height; y++) {
|
||||
for (unsigned x = 0; x < glyph_width; x++)
|
||||
fb_base[x] = PT::mix(bg_pixel, fg_pixel, glyph_base[x]);
|
||||
|
||||
fb_base += fb_width;
|
||||
glyph_base += glyph_img_width;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _DRAW_GLYPH_H_ */
|
@ -40,8 +40,8 @@ class Terminal::Font_family
|
||||
*/
|
||||
Font const &font(Font_face) const { return _regular; }
|
||||
|
||||
unsigned cell_width() const { return _regular.str_w("m"); }
|
||||
unsigned cell_height() const { return _regular.str_h("m"); }
|
||||
unsigned cell_width() const { return _regular.bounding_box().w(); }
|
||||
unsigned cell_height() const { return _regular.bounding_box().h(); }
|
||||
};
|
||||
|
||||
#endif /* _FONT_FAMILY_H_ */
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <input/event.h>
|
||||
#include <nitpicker_gfx/tff_font.h>
|
||||
|
||||
/* terminal includes */
|
||||
#include <terminal/decoder.h>
|
||||
@ -52,7 +53,10 @@ struct Terminal::Main : Character_consumer
|
||||
*/
|
||||
static char const *_font_data(Xml_node config);
|
||||
|
||||
Reconstructible<Font> _font { _font_data(_config.xml()) };
|
||||
Tff_font::Static_glyph_buffer<4096> _glyph_buffer { };
|
||||
|
||||
Reconstructible<Tff_font> _font { _font_data(_config.xml()), _glyph_buffer };
|
||||
|
||||
Reconstructible<Font_family> _font_family { *_font };
|
||||
|
||||
unsigned char *_keymap = Terminal::usenglish_keymap;
|
||||
@ -193,7 +197,7 @@ void Terminal::Main::_handle_config()
|
||||
|
||||
Xml_node const config = _config.xml();
|
||||
|
||||
_font.construct(_font_data(config));
|
||||
_font.construct(_font_data(config), _glyph_buffer);
|
||||
_font_family.construct(*_font);
|
||||
|
||||
/*
|
||||
|
@ -22,10 +22,10 @@
|
||||
|
||||
/* nitpicker graphic back end */
|
||||
#include <nitpicker_gfx/text_painter.h>
|
||||
#include <nitpicker_gfx/box_painter.h>
|
||||
|
||||
/* local includes */
|
||||
#include "font_family.h"
|
||||
#include "draw_glyph.h"
|
||||
#include "color_palette.h"
|
||||
#include "framebuffer.h"
|
||||
|
||||
@ -69,14 +69,23 @@ class Terminal::Text_screen_surface
|
||||
{
|
||||
Font const ®ular_font = _font_family.font(Font_face::REGULAR);
|
||||
|
||||
unsigned const glyph_height = regular_font.img_h,
|
||||
glyph_step_x = regular_font.wtab['m'];
|
||||
Area const cell_size = regular_font.bounding_box();
|
||||
|
||||
unsigned const glyph_height = regular_font.bounding_box().h(),
|
||||
glyph_step_x = regular_font.bounding_box().w();
|
||||
|
||||
unsigned const fb_width = _framebuffer.w(),
|
||||
fb_height = _framebuffer.h();
|
||||
|
||||
int const clip_top = 0, clip_bottom = fb_height,
|
||||
clip_left = 0, clip_right = fb_width;
|
||||
|
||||
PT *fb_base = _framebuffer.pixel<PT>();
|
||||
|
||||
Surface<PT> surface(fb_base, Area(_framebuffer.w(), _framebuffer.h()));
|
||||
|
||||
unsigned const fg_alpha = 255;
|
||||
|
||||
unsigned y = 0;
|
||||
for (unsigned line = 0; line < _cell_array.num_lines(); line++) {
|
||||
|
||||
@ -92,41 +101,39 @@ class Terminal::Text_screen_surface
|
||||
if (ascii == 0)
|
||||
ascii = ' ';
|
||||
|
||||
unsigned char const *glyph_base = font.img + font.otab[ascii];
|
||||
Text_painter::Codepoint const c { ascii };
|
||||
|
||||
unsigned glyph_width = regular_font.wtab[ascii];
|
||||
font.apply_glyph(c, [&] (Glyph_painter::Glyph const &glyph) {
|
||||
|
||||
if (x + glyph_width > fb_width)
|
||||
break;
|
||||
Color_palette::Highlighted const highlighted { cell.highlight() };
|
||||
Color_palette::Inverse const inverse { cell.inverse() };
|
||||
|
||||
Color_palette::Highlighted const highlighted { cell.highlight() };
|
||||
Color_palette::Inverse const inverse { cell.inverse() };
|
||||
Color fg_color =
|
||||
_palette.foreground(Color_palette::Index{cell.colidx_fg()},
|
||||
highlighted, inverse);
|
||||
|
||||
Color fg_color =
|
||||
_palette.foreground(Color_palette::Index{cell.colidx_fg()},
|
||||
highlighted, inverse);
|
||||
Color bg_color =
|
||||
_palette.background(Color_palette::Index{cell.colidx_bg()},
|
||||
highlighted, inverse);
|
||||
|
||||
Color bg_color =
|
||||
_palette.background(Color_palette::Index{cell.colidx_bg()},
|
||||
highlighted, inverse);
|
||||
if (cell.has_cursor()) {
|
||||
fg_color = Color( 63, 63, 63);
|
||||
bg_color = Color(255, 255, 255);
|
||||
}
|
||||
|
||||
if (cell.has_cursor()) {
|
||||
fg_color = Color( 63, 63, 63);
|
||||
bg_color = Color(255, 255, 255);
|
||||
}
|
||||
PT const pixel(fg_color.r, fg_color.g, fg_color.b);
|
||||
|
||||
draw_glyph<PT>(fg_color, bg_color,
|
||||
glyph_base, glyph_width,
|
||||
(unsigned)font.img_w, (unsigned)font.img_h,
|
||||
glyph_step_x, fb_base + x, fb_width);
|
||||
Box_painter::paint(surface, Rect(Point(x, y), cell_size), bg_color);
|
||||
|
||||
x += glyph_step_x;
|
||||
Glyph_painter::paint(Glyph_painter::Position((int)x, (int)y),
|
||||
glyph, fb_base, fb_width,
|
||||
clip_top, clip_bottom, clip_left, clip_right,
|
||||
pixel, fg_alpha);
|
||||
x += glyph_step_x;
|
||||
});
|
||||
}
|
||||
}
|
||||
y += glyph_height;
|
||||
fb_base += fb_width*glyph_height;
|
||||
|
||||
if (y + glyph_height > fb_height) break;
|
||||
y += glyph_height;
|
||||
}
|
||||
|
||||
int first_dirty_line = 10000,
|
||||
|
148
repos/os/include/nitpicker_gfx/glyph_painter.h
Normal file
148
repos/os/include/nitpicker_gfx/glyph_painter.h
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* \brief Functor for drawing glyphs
|
||||
* \author Norman Feske
|
||||
* \date 2006-08-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__NITPICKER_GFX__GLYPH_PAINTER_H_
|
||||
#define _INCLUDE__NITPICKER_GFX__GLYPH_PAINTER_H_
|
||||
|
||||
#include <util/noncopyable.h>
|
||||
#include <base/stdint.h>
|
||||
#include <os/surface.h>
|
||||
|
||||
|
||||
struct Glyph_painter
|
||||
{
|
||||
/**
|
||||
* Subpixel positions are represented as fixpoint numbers that use 24 bits
|
||||
* for the decimal and 8 bits for the fractional part.
|
||||
*/
|
||||
struct Fixpoint_number
|
||||
{
|
||||
int value;
|
||||
|
||||
Fixpoint_number(float value) : value(value*256) { };
|
||||
|
||||
Fixpoint_number(int decimal) : value(decimal << 8) { };
|
||||
|
||||
int decimal() const { return value >> 8; }
|
||||
};
|
||||
|
||||
typedef Genode::Point<Fixpoint_number> Position;
|
||||
|
||||
|
||||
struct Glyph
|
||||
{
|
||||
unsigned const width;
|
||||
unsigned const height;
|
||||
unsigned const vpos;
|
||||
|
||||
Fixpoint_number const advance;
|
||||
|
||||
struct Opacity { unsigned char value; };
|
||||
|
||||
/**
|
||||
* Pointer to opacity values (0 = transparent, 255 = opaque)
|
||||
*
|
||||
* The 'values' buffer contains the glyph horizontally scaled by four.
|
||||
* Its size is width*4*height bytes. The first row (four values) of each
|
||||
* line as well as the last line contains padding space, which does not
|
||||
* need to be drawn in order to obtain the complete shape.
|
||||
*/
|
||||
Opacity const * const values;
|
||||
|
||||
unsigned num_values() const { return 4*width*height; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw single glyph on a 'dst' buffer, with clipping applied
|
||||
*
|
||||
* In contrast to most painter functions, which operate on a 'Surface',
|
||||
* this function has a lower-level interface. It is intended as a utility
|
||||
* called by painter implementations, not by applications directly.
|
||||
*/
|
||||
template <typename PT>
|
||||
static inline void paint(Position const position, Glyph const &glyph,
|
||||
PT *dst, unsigned const dst_line_len,
|
||||
int const clip_top, int const clip_bottom,
|
||||
int const clip_left, int const clip_right,
|
||||
PT const color, int const alpha)
|
||||
{
|
||||
Fixpoint_number const x = position.x();
|
||||
int const y = position.y().decimal();
|
||||
|
||||
int const dst_y1 = y + glyph.vpos,
|
||||
dst_y2 = dst_y1 + glyph.height;
|
||||
|
||||
unsigned const clipped_from_top = clip_top > dst_y1
|
||||
? clip_top - dst_y1 : 0;
|
||||
|
||||
unsigned const clipped_from_bottom = dst_y2 > clip_bottom
|
||||
? dst_y2 - clip_bottom : 0;
|
||||
|
||||
if (clipped_from_top + clipped_from_bottom >= glyph.height)
|
||||
return;
|
||||
|
||||
unsigned const num_lines = glyph.height - clipped_from_top
|
||||
- clipped_from_bottom;
|
||||
int const w = glyph.width;
|
||||
int const start = Genode::max(0, clip_left - x.decimal());
|
||||
int const end = Genode::min(w - 1, clip_right - x.decimal());
|
||||
|
||||
int const dst_x = start + ((x.value) >> 8);
|
||||
int const glyph_x = start*4 + 3 - ((x.value & 0xc0) >> 6);
|
||||
|
||||
unsigned const glyph_line_len = 4*glyph.width;
|
||||
|
||||
PT *dst_column = dst + dst_x
|
||||
+ dst_line_len*(dst_y1 + clipped_from_top);
|
||||
|
||||
typedef Glyph::Opacity Opacity;
|
||||
Opacity const *glyph_column = glyph.values + glyph_x
|
||||
+ glyph_line_len*clipped_from_top;
|
||||
|
||||
/* iterate over the visible columns of the glyph */
|
||||
for (int i = start; i < end; i++) {
|
||||
|
||||
/* weights of the two sampled values (horizontal neighbors)*/
|
||||
int const u0 = x.value*4 & 0xff;
|
||||
int const u1 = 0x100 - u0;
|
||||
|
||||
PT *d = dst_column;
|
||||
Opacity const *s = glyph_column;
|
||||
|
||||
/* iterate over one column */
|
||||
for (unsigned j = 0; j < num_lines; j++) {
|
||||
|
||||
/* sample values from glyph image */
|
||||
unsigned const v0 = s->value;
|
||||
unsigned const v1 = (s + 1)->value;
|
||||
|
||||
/* apply weights */
|
||||
int const value = (v0*u0 + v1*u1) >> 8;
|
||||
|
||||
/* transfer pixel */
|
||||
if (value)
|
||||
*d = (value == 255 && alpha == 255)
|
||||
? color : PT::mix(*d, color, (alpha*value) >> 8);
|
||||
|
||||
s += glyph_line_len;
|
||||
d += dst_line_len;
|
||||
}
|
||||
|
||||
dst_column += 1;
|
||||
glyph_column += 4;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NITPICKER_GFX__GLYPH_PAINTER_H_ */
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* \brief Functor for drawing text into a surface
|
||||
* \brief Functor for drawing text on a surface
|
||||
* \author Norman Feske
|
||||
* \date 2006-08-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2017 Genode Labs GmbH
|
||||
* Copyright (C) 2006-2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
@ -14,119 +14,144 @@
|
||||
#ifndef _INCLUDE__NITPICKER_GFX__TEXT_PAINTER_H_
|
||||
#define _INCLUDE__NITPICKER_GFX__TEXT_PAINTER_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
#include <os/surface.h>
|
||||
#include <util/interface.h>
|
||||
#include <util/utf8.h>
|
||||
#include <nitpicker_gfx/glyph_painter.h>
|
||||
|
||||
|
||||
struct Text_painter
|
||||
{
|
||||
class Font
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Genode::int32_t int32_t;
|
||||
typedef Genode::size_t size_t;
|
||||
|
||||
public:
|
||||
|
||||
unsigned char const *img; /* font image */
|
||||
int const img_w, img_h; /* size of font image */
|
||||
int32_t const *otab; /* offset table */
|
||||
int32_t const *wtab; /* width table */
|
||||
|
||||
/**
|
||||
* Construct font from a TFF data block
|
||||
*/
|
||||
Font(const char *tff)
|
||||
:
|
||||
img((unsigned char *)(tff + 2056)),
|
||||
|
||||
img_w(*((int32_t *)(tff + 2048))),
|
||||
img_h(*((int32_t *)(tff + 2052))),
|
||||
|
||||
otab((int32_t *)(tff)),
|
||||
wtab((int32_t *)(tff + 1024))
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Calculate width of string when printed with the font
|
||||
*/
|
||||
int str_w(const char *sstr, size_t len = ~0UL) const
|
||||
{
|
||||
const unsigned char *str = (const unsigned char *)sstr;
|
||||
int res = 0;
|
||||
for (; str && *str && len; len--, str++) res += wtab[*str];
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate height of string when printed with the font
|
||||
*/
|
||||
int str_h(const char *, size_t = ~0UL) const { return img_h; }
|
||||
};
|
||||
|
||||
|
||||
typedef Genode::Surface_base::Point Point;
|
||||
typedef Genode::Surface_base::Area Area;
|
||||
typedef Genode::Surface_base::Rect Rect;
|
||||
typedef Genode::Codepoint Codepoint;
|
||||
|
||||
typedef Glyph_painter::Fixpoint_number Fixpoint_number;
|
||||
typedef Glyph_painter::Position Position;
|
||||
typedef Glyph_painter::Glyph Glyph;
|
||||
|
||||
|
||||
/***************************************
|
||||
** Interface for accessing font data **
|
||||
***************************************/
|
||||
|
||||
class Font : public Genode::Interface
|
||||
{
|
||||
protected:
|
||||
|
||||
struct Apply_fn : Genode::Interface
|
||||
{
|
||||
virtual void apply(Glyph const &) const = 0;
|
||||
};
|
||||
|
||||
virtual void _apply_glyph(Codepoint c, Apply_fn const &) const = 0;
|
||||
|
||||
public:
|
||||
|
||||
template <typename FN>
|
||||
void apply_glyph(Codepoint c, FN const &fn) const
|
||||
{
|
||||
/* helper to pass lambda 'fn' to virtual '_apply_glyph' method */
|
||||
struct Wrapped_fn : Apply_fn
|
||||
{
|
||||
FN const &_fn;
|
||||
void apply(Glyph const &glyph) const override { _fn(glyph); }
|
||||
Wrapped_fn(FN const &fn) : _fn(fn) { }
|
||||
};
|
||||
|
||||
_apply_glyph(c, Wrapped_fn(fn));
|
||||
}
|
||||
|
||||
struct Advance_info
|
||||
{
|
||||
unsigned const width;
|
||||
Fixpoint_number const advance;
|
||||
};
|
||||
|
||||
virtual Advance_info advance_info(Codepoint c) const = 0;
|
||||
|
||||
/**
|
||||
* Return distance from the top of a glyph the baseline of the font
|
||||
*/
|
||||
virtual unsigned baseline() const = 0;
|
||||
|
||||
/**
|
||||
* Return the bounding box that fits each single glyph of the font
|
||||
*/
|
||||
virtual Area bounding_box() const = 0;
|
||||
|
||||
/**
|
||||
* Compute width of UTF8 string in pixels when rendered with the font
|
||||
*/
|
||||
Fixpoint_number string_width(Genode::Utf8_ptr utf8, unsigned len = ~0U) const
|
||||
{
|
||||
Fixpoint_number result { (int)0 };
|
||||
|
||||
for (; utf8.complete() && len--; utf8 = utf8.next())
|
||||
result.value += advance_info(utf8.codepoint()).advance.value;
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Paint UTF8 string to surface
|
||||
*/
|
||||
template <typename PT>
|
||||
static inline void paint(Genode::Surface<PT> &surface,
|
||||
Point p,
|
||||
Position position,
|
||||
Font const &font,
|
||||
Genode::Color color,
|
||||
char const *sstr)
|
||||
char const *string)
|
||||
{
|
||||
unsigned char const *str = (unsigned char const *)sstr;
|
||||
int x = p.x(), y = p.y();
|
||||
/* use sub-pixel positioning horizontally */
|
||||
Fixpoint_number x = position.x();
|
||||
Fixpoint_number const y = position.y();
|
||||
|
||||
unsigned char const *src = font.img;
|
||||
int d, h = font.img_h;
|
||||
int const clip_top = surface.clip().y1(),
|
||||
clip_bottom = surface.clip().y2() + 1,
|
||||
clip_left = surface.clip().x1(),
|
||||
clip_right = surface.clip().x2() + 1;
|
||||
|
||||
/* check top clipping */
|
||||
if ((d = surface.clip().y1() - y) > 0) {
|
||||
src += d*font.img_w;
|
||||
y += d;
|
||||
h -= d;
|
||||
Genode::Utf8_ptr utf8(string);
|
||||
|
||||
/* skip glyphs hidden behind left clipping border */
|
||||
bool skip = true;
|
||||
while (skip && utf8.complete()) {
|
||||
auto const glyph = font.advance_info(utf8.codepoint());
|
||||
skip = x.decimal() + (int)glyph.width < clip_left;
|
||||
if (skip) {
|
||||
x.value += glyph.advance.value;
|
||||
utf8 = utf8.next();
|
||||
}
|
||||
}
|
||||
|
||||
/* check bottom clipping */
|
||||
if ((d = y + h -1 - surface.clip().y2()) > 0)
|
||||
h -= d;
|
||||
int const x_start = x.decimal();
|
||||
|
||||
if (h < 1) return;
|
||||
unsigned const dst_line_len = surface.size().w();
|
||||
|
||||
/* skip hidden glyphs */
|
||||
for ( ; *str && (x + font.wtab[*str] < surface.clip().x1()); )
|
||||
x += font.wtab[*str++];
|
||||
PT * const dst = surface.addr();
|
||||
|
||||
int const x_start = x;
|
||||
|
||||
PT *dst = surface.addr() + y*surface.size().w();
|
||||
|
||||
PT const pix(color.r, color.g, color.b);
|
||||
PT const pixel(color.r, color.g, color.b);
|
||||
int const alpha = color.a;
|
||||
|
||||
/* draw glyphs */
|
||||
for ( ; *str && (x <= surface.clip().x2()); str++) {
|
||||
for ( ; utf8.complete() && (x.decimal() <= clip_right); utf8 = utf8.next()) {
|
||||
|
||||
int const w = font.wtab[*str];
|
||||
int const start = Genode::max(0, surface.clip().x1() - x);
|
||||
int const end = Genode::min(w - 1, surface.clip().x2() - x);
|
||||
font.apply_glyph(utf8.codepoint(), [&] (Glyph const &glyph) {
|
||||
|
||||
PT *d = dst + x;
|
||||
unsigned char const *s = src + font.otab[*str];
|
||||
Glyph_painter::paint(Position(x, y), glyph, dst, dst_line_len,
|
||||
clip_top, clip_bottom, clip_left, clip_right,
|
||||
pixel, alpha);
|
||||
|
||||
for (int j = 0; j < h; j++, s += font.img_w, d += surface.size().w())
|
||||
for (int i = start; i <= end; i++)
|
||||
if (s[i])
|
||||
d[i] = (s[i] == 255 && alpha == 255)
|
||||
? pix : PT::mix(d[i], pix, (alpha*s[i]) >> 8);
|
||||
x += w;
|
||||
x.value += glyph.advance.value;
|
||||
});
|
||||
}
|
||||
|
||||
surface.flush_pixels(Rect(Point(x_start, y), Area(x - x_start + 1, h)));
|
||||
surface.flush_pixels(Rect(Point(x_start, y.decimal()),
|
||||
Area(x.decimal() - x_start + 1,
|
||||
font.bounding_box().h())));
|
||||
}
|
||||
};
|
||||
|
||||
|
237
repos/os/include/nitpicker_gfx/tff_font.h
Normal file
237
repos/os/include/nitpicker_gfx/tff_font.h
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* \brief Implementation of 'Text_painter::Font' using a trivial font format
|
||||
* \author Norman Feske
|
||||
* \date 2018-03-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__NITPICKER_GFX__TFF_FONT_H_
|
||||
#define _INCLUDE__NITPICKER_GFX__TFF_FONT_H_
|
||||
|
||||
#include <base/allocator.h>
|
||||
#include <nitpicker_gfx/text_painter.h>
|
||||
|
||||
class Tff_font : public Text_painter::Font
|
||||
{
|
||||
public:
|
||||
|
||||
struct Glyph_buffer
|
||||
{
|
||||
char * const ptr;
|
||||
Genode::size_t const size;
|
||||
};
|
||||
|
||||
template <unsigned SIZE>
|
||||
struct Static_glyph_buffer : Glyph_buffer
|
||||
{
|
||||
char _data[SIZE];
|
||||
Static_glyph_buffer() : Glyph_buffer({_data, sizeof(_data)}) { }
|
||||
};
|
||||
|
||||
struct Allocated_glyph_buffer : Tff_font::Glyph_buffer
|
||||
{
|
||||
Genode::Allocator &_alloc;
|
||||
|
||||
Allocated_glyph_buffer(void const *tff, Genode::Allocator &alloc)
|
||||
:
|
||||
Tff_font::Glyph_buffer({
|
||||
(char *)alloc.alloc(Tff_font::glyph_buffer_size(tff)),
|
||||
Tff_font::glyph_buffer_size(tff) }),
|
||||
_alloc(alloc)
|
||||
{ }
|
||||
|
||||
~Allocated_glyph_buffer()
|
||||
{
|
||||
_alloc.free(ptr, size);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
typedef Genode::int32_t int32_t;
|
||||
|
||||
typedef Text_painter::Codepoint Codepoint;
|
||||
typedef Text_painter::Area Area;
|
||||
typedef Text_painter::Glyph Glyph;
|
||||
|
||||
Glyph_buffer &_buf;
|
||||
|
||||
enum { NUM_GLYPHS = 256, PAD_LEFT = 1 };
|
||||
|
||||
struct Tff
|
||||
{
|
||||
unsigned char const *img; /* font image */
|
||||
int const img_w, img_h; /* size of font image */
|
||||
int32_t const *otab; /* offset table */
|
||||
int32_t const *wtab; /* width table */
|
||||
|
||||
Tff(void const *data)
|
||||
:
|
||||
img((unsigned char *)data + 2056),
|
||||
|
||||
img_w(*((int32_t *)((unsigned char *)data + 2048))),
|
||||
img_h(*((int32_t *)((unsigned char *)data + 2052))),
|
||||
|
||||
otab((int32_t *)(data)),
|
||||
wtab((int32_t *)((unsigned char *)data + 1024))
|
||||
{ }
|
||||
|
||||
Area bounding_box() const
|
||||
{
|
||||
unsigned max_w = 0;
|
||||
for (unsigned i = 0; i < NUM_GLYPHS; i++)
|
||||
max_w = Genode::max(max_w, (unsigned)wtab[i]);
|
||||
|
||||
return Area(max_w, img_h);
|
||||
}
|
||||
|
||||
bool _glyph_line_empty(unsigned char c, unsigned y) const
|
||||
{
|
||||
unsigned char const * const line = img + otab[c] + y*img_w;
|
||||
for (unsigned i = 0; i < (unsigned)wtab[c]; i++)
|
||||
if (line[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct Vertical_metrics
|
||||
{
|
||||
unsigned vpos;
|
||||
unsigned height;
|
||||
};
|
||||
|
||||
Vertical_metrics vertical_metrics(unsigned char c) const
|
||||
{
|
||||
unsigned y_start = 0;
|
||||
unsigned y_end = img_h;
|
||||
|
||||
/* determine empty lines below glyph */
|
||||
for (; y_end > 0; y_end--)
|
||||
if (!_glyph_line_empty(c, y_end - 1))
|
||||
break;
|
||||
|
||||
/* determine empty lines above glyph */
|
||||
for (; y_start < (unsigned)img_h; y_start++)
|
||||
if (!_glyph_line_empty(c, y_start))
|
||||
break;
|
||||
|
||||
return Vertical_metrics {
|
||||
.vpos = y_start,
|
||||
.height = (y_end > y_start) ? y_end - y_start : 0
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Tff const _tff;
|
||||
|
||||
Tff::Vertical_metrics _vertical_metrics[NUM_GLYPHS];
|
||||
|
||||
Area const _bounding_box = _tff.bounding_box();
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Tff_font(Tff_font const &);
|
||||
Tff_font &operator = (Tff_font const &);
|
||||
|
||||
public:
|
||||
|
||||
struct Invalid_format : Genode::Exception { };
|
||||
struct Insufficient_glyph_buffer : Genode::Exception { };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param tff font data
|
||||
* \param glyph_buffer buffer for rendered glyph
|
||||
*
|
||||
* \throw Invalid_format
|
||||
* \throw Insufficient_glyph_buffer
|
||||
*
|
||||
* The 'glyph_buffer' should be dimensioned via 'glyph_buffer_size()'.
|
||||
*/
|
||||
Tff_font(void const *tff, Glyph_buffer &glyph_buffer)
|
||||
:
|
||||
_buf(glyph_buffer), _tff(tff)
|
||||
{
|
||||
if (_tff.img_h < 1 || _tff.img_w < 1)
|
||||
throw Invalid_format();
|
||||
|
||||
if (_buf.size < glyph_buffer_size(tff))
|
||||
throw Insufficient_glyph_buffer();
|
||||
|
||||
for (unsigned i = 0; i < NUM_GLYPHS; i++)
|
||||
_vertical_metrics[i] = _tff.vertical_metrics(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return required glyph-buffer size for a given font
|
||||
*/
|
||||
static Genode::size_t glyph_buffer_size(void const *tff)
|
||||
{
|
||||
/* account for four-times horizontal supersampling */
|
||||
return Tff(tff).bounding_box().count()*4;
|
||||
}
|
||||
|
||||
void _apply_glyph(Codepoint c, Apply_fn const &fn) const override
|
||||
{
|
||||
unsigned const ascii = c.value & 0xff;
|
||||
|
||||
unsigned const w = _tff.wtab[ascii],
|
||||
h = _vertical_metrics[ascii].height,
|
||||
vpos = _vertical_metrics[ascii].vpos;
|
||||
|
||||
unsigned char const *glyph_line = _tff.img + _tff.otab[ascii]
|
||||
+ vpos*_tff.img_w;
|
||||
|
||||
Glyph::Opacity *dst = (Glyph::Opacity *)_buf.ptr;
|
||||
|
||||
for (unsigned j = 0; j < h; j++) {
|
||||
|
||||
/* insert padding in front */
|
||||
for (unsigned k = 0; k < PAD_LEFT*4; k++)
|
||||
*dst++ = Glyph::Opacity { 0 };
|
||||
|
||||
/* copy line from font image to glyph */
|
||||
for (unsigned i = 0; i < w; i++) {
|
||||
Glyph::Opacity const opacity { glyph_line[i] };
|
||||
for (unsigned k = 0; k < 4; k++)
|
||||
*dst++ = opacity;
|
||||
}
|
||||
glyph_line += _tff.img_w;
|
||||
}
|
||||
|
||||
Glyph const glyph { .width = w + PAD_LEFT,
|
||||
.height = h,
|
||||
.vpos = vpos,
|
||||
.advance = (int)w,
|
||||
.values = (Glyph::Opacity *)_buf.ptr };
|
||||
fn.apply(glyph);
|
||||
}
|
||||
|
||||
Advance_info advance_info(Codepoint c) const override
|
||||
{
|
||||
unsigned const ascii = c.value & 0xff;
|
||||
unsigned const w = _tff.wtab[ascii];
|
||||
|
||||
return Advance_info { .width = w + PAD_LEFT,
|
||||
.advance = (int)w };
|
||||
}
|
||||
|
||||
unsigned baseline() const override
|
||||
{
|
||||
Tff::Vertical_metrics const m = _vertical_metrics['m'];
|
||||
return m.vpos + m.height;
|
||||
}
|
||||
|
||||
Area bounding_box() const override { return _bounding_box; }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NITPICKER_GFX__TFF_FONT_H_ */
|
@ -261,7 +261,7 @@ puts $launchpad_config_fd {<config>
|
||||
<launcher name="launchpad" ram_quota="6M" caps="1000">
|
||||
<configfile name="launchpad.config" />
|
||||
</launcher>
|
||||
<launcher name="nitlog" ram_quota="1M" caps="50"/>
|
||||
<launcher name="nitlog" ram_quota="1M" caps="70"/>
|
||||
<launcher name="liquid_fb" ram_quota="7M" caps="70">
|
||||
<config resize_handle="on" />
|
||||
</launcher>
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <os/pixel_rgb565.h>
|
||||
#include <nitpicker_session/connection.h>
|
||||
#include <nitpicker_gfx/box_painter.h>
|
||||
#include <nitpicker_gfx/text_painter.h>
|
||||
#include <nitpicker_gfx/tff_font.h>
|
||||
|
||||
namespace Status_bar {
|
||||
|
||||
@ -61,7 +61,8 @@ struct Status_bar::Buffer
|
||||
|
||||
Attached_dataspace _fb_ds;
|
||||
|
||||
Text_painter::Font const _font { &_binary_default_tff_start };
|
||||
Tff_font::Static_glyph_buffer<4096> _glyph_buffer { };
|
||||
Tff_font _font { &_binary_default_tff_start, _glyph_buffer };
|
||||
|
||||
Buffer(Region_map &rm, Nitpicker::Connection &nitpicker)
|
||||
:
|
||||
@ -74,8 +75,9 @@ struct Status_bar::Buffer
|
||||
for (int j = -1; j <= 1; j++)
|
||||
for (int i = -1; i <= 1; i++)
|
||||
if (i || j)
|
||||
Text_painter::paint(surface, pos + Point(i, j), _font,
|
||||
Color(0, 0, 0), s);
|
||||
Text_painter::paint(surface,
|
||||
Text_painter::Position(pos.x() + i, pos.y() + j),
|
||||
_font, Color(0, 0, 0), s);
|
||||
}
|
||||
|
||||
template <typename PT>
|
||||
@ -91,20 +93,21 @@ struct Status_bar::Buffer
|
||||
pos = pos + Point(1, 1);
|
||||
|
||||
_draw_outline(surface, pos, domain_name.string());
|
||||
Text_painter::paint(surface, pos, _font, domain_text_color,
|
||||
domain_name.string());
|
||||
Text_painter::paint(surface, Text_painter::Position(pos.x(), pos.y()),
|
||||
_font, domain_text_color, domain_name.string());
|
||||
|
||||
pos = pos + Point(_font.str_w(domain_name.string()) + LABEL_GAP, 0);
|
||||
pos = pos + Point(_font.string_width(domain_name.string()).decimal() + LABEL_GAP, 0);
|
||||
|
||||
_draw_outline(surface, pos, label.string());
|
||||
Text_painter::paint(surface, pos, _font, label_text_color, label.string());
|
||||
Text_painter::paint(surface, Text_painter::Position(pos.x(), pos.y()),
|
||||
_font, label_text_color, label.string());
|
||||
}
|
||||
|
||||
Area _label_size(Domain_name const &domain_name, Label const &label) const
|
||||
{
|
||||
return Area(_font.str_w(domain_name.string()) + LABEL_GAP
|
||||
+ _font.str_w(label.string()) + 2,
|
||||
_font.str_h(domain_name.string()) + 2);
|
||||
return Area(_font.string_width(domain_name.string()).decimal() + LABEL_GAP
|
||||
+ _font.string_width(label.string()).decimal() + 2,
|
||||
_font.bounding_box().h() + 2);
|
||||
}
|
||||
|
||||
void draw(Domain_name const &, Label const &, Color);
|
||||
|
@ -50,7 +50,7 @@ struct Nitpicker::Background : private Texture_base, View_component
|
||||
int frame_size(Focus const &) const override { return 0; }
|
||||
void frame(Canvas_base &, Focus const &) const override { }
|
||||
|
||||
void draw(Canvas_base &canvas, Focus const &) const override
|
||||
void draw(Canvas_base &canvas, Font const &, Focus const &) const override
|
||||
{
|
||||
Rect const view_rect = abs_geometry();
|
||||
Clip_guard clip_guard(canvas, view_rect);
|
||||
|
@ -24,6 +24,8 @@
|
||||
namespace Nitpicker {
|
||||
struct Canvas_base;
|
||||
template <typename PT> class Canvas;
|
||||
|
||||
typedef Text_painter::Font Font;
|
||||
}
|
||||
|
||||
|
||||
@ -92,10 +94,11 @@ class Nitpicker::Canvas : public Canvas_base, public Surface_base::Flusher
|
||||
allow_alpha);
|
||||
}
|
||||
|
||||
void draw_text(Point pos, Text_painter::Font const &font,
|
||||
void draw_text(Point pos, Font const &font,
|
||||
Color color, char const *string)
|
||||
{
|
||||
Text_painter::paint(_surface, pos, font, color, string);
|
||||
Text_painter::paint(_surface, Text_painter::Position(pos.x(), pos.y()),
|
||||
font, color, string);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -20,8 +20,6 @@
|
||||
|
||||
namespace Nitpicker {
|
||||
|
||||
extern Text_painter::Font default_font;
|
||||
|
||||
/*
|
||||
* Gap between session label and view title in pixels
|
||||
*/
|
||||
@ -30,12 +28,13 @@ namespace Nitpicker {
|
||||
/**
|
||||
* Draw black outline of string
|
||||
*/
|
||||
inline void draw_string_outline(Canvas_base &canvas, Point pos, char const *s)
|
||||
inline void draw_string_outline(Canvas_base &canvas, Text_painter::Font const &font,
|
||||
Point pos, char const *s)
|
||||
{
|
||||
for (int j = -1; j <= 1; j++)
|
||||
for (int i = -1; i <= 1; i++)
|
||||
if (i || j)
|
||||
canvas.draw_text(pos + Point(i, j), default_font, black(), s);
|
||||
canvas.draw_text(pos + Point(i, j), font, black(), s);
|
||||
}
|
||||
|
||||
|
||||
@ -45,9 +44,10 @@ namespace Nitpicker {
|
||||
* \param sl session label string
|
||||
* \param vt view title string
|
||||
*/
|
||||
inline Area label_size(const char *sl, const char *vt) {
|
||||
return Area(default_font.str_w(sl) + LABEL_GAP + default_font.str_w(vt) + 2,
|
||||
default_font.str_h(sl) + 2); }
|
||||
inline Area label_size(Font const &font, const char *sl, const char *vt) {
|
||||
return Area(font.string_width(sl).decimal() + LABEL_GAP +
|
||||
font.string_width(vt).decimal() + 2,
|
||||
font.bounding_box().h() + 2); }
|
||||
|
||||
|
||||
/**
|
||||
@ -58,19 +58,19 @@ namespace Nitpicker {
|
||||
* policy. In contrast, the view title can individually be defined by the
|
||||
* application.
|
||||
*/
|
||||
static inline void draw_label(Canvas_base &canvas, Point pos,
|
||||
static inline void draw_label(Canvas_base &canvas, Font const &font, Point pos,
|
||||
char const *session_label, Color session_label_color,
|
||||
char const *view_title, Color view_title_color)
|
||||
{
|
||||
pos = pos + Point(1, 1);
|
||||
|
||||
draw_string_outline(canvas, pos, session_label);
|
||||
canvas.draw_text(pos, default_font, session_label_color, session_label);
|
||||
draw_string_outline(canvas, font, pos, session_label);
|
||||
canvas.draw_text(pos, font, session_label_color, session_label);
|
||||
|
||||
pos = pos + Point(default_font.str_w(session_label) + LABEL_GAP, 0);
|
||||
pos = pos + Point(font.string_width(session_label).decimal() + LABEL_GAP, 0);
|
||||
|
||||
draw_string_outline(canvas, pos, view_title);
|
||||
canvas.draw_text(pos, default_font, view_title_color, view_title);
|
||||
draw_string_outline(canvas, font, pos, view_title);
|
||||
canvas.draw_text(pos, font, view_title_color, view_title);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <input_session/connection.h>
|
||||
#include <framebuffer_session/connection.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <nitpicker_gfx/tff_font.h>
|
||||
|
||||
/* local includes */
|
||||
#include "types.h"
|
||||
@ -40,16 +41,11 @@ namespace Nitpicker {
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
** Font initialization **
|
||||
*************************/
|
||||
/*********************************
|
||||
** Font used for view labeling **
|
||||
*********************************/
|
||||
|
||||
extern char _binary_default_tff_start;
|
||||
|
||||
namespace Nitpicker {
|
||||
|
||||
Text_painter::Font default_font(&_binary_default_tff_start);
|
||||
}
|
||||
extern char _binary_default_tff_start[];
|
||||
|
||||
|
||||
/************************************
|
||||
@ -81,6 +77,7 @@ class Nitpicker::Root : public Root_component<Session_component>,
|
||||
Global_keys &_global_keys;
|
||||
Framebuffer::Mode _scr_mode { };
|
||||
View_stack &_view_stack;
|
||||
Font const &_font;
|
||||
User_state &_user_state;
|
||||
View_component &_pointer_origin;
|
||||
View_component &_builtin_background;
|
||||
@ -109,7 +106,7 @@ class Nitpicker::Root : public Root_component<Session_component>,
|
||||
bool const provides_default_bg = (label == "backdrop");
|
||||
|
||||
Session_component *session = new (md_alloc())
|
||||
Session_component(_env, label, _view_stack, _user_state,
|
||||
Session_component(_env, label, _view_stack, _font, _user_state,
|
||||
_pointer_origin, _builtin_background, _framebuffer,
|
||||
provides_default_bg, *md_alloc(), unused_quota,
|
||||
_focus_reporter, *this);
|
||||
@ -146,7 +143,7 @@ class Nitpicker::Root : public Root_component<Session_component>,
|
||||
*/
|
||||
Root(Env &env, Attached_rom_dataspace const &config,
|
||||
Session_list &session_list, Domain_registry const &domain_registry,
|
||||
Global_keys &global_keys, View_stack &view_stack,
|
||||
Global_keys &global_keys, View_stack &view_stack, Font const &font,
|
||||
User_state &user_state, View_component &pointer_origin,
|
||||
View_component &builtin_background, Allocator &md_alloc,
|
||||
Framebuffer::Session &framebuffer, Reporter &focus_reporter,
|
||||
@ -155,7 +152,7 @@ class Nitpicker::Root : public Root_component<Session_component>,
|
||||
Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc),
|
||||
_env(env), _config(config), _session_list(session_list),
|
||||
_domain_registry(domain_registry), _global_keys(global_keys),
|
||||
_view_stack(view_stack), _user_state(user_state),
|
||||
_view_stack(view_stack), _font(font), _user_state(user_state),
|
||||
_pointer_origin(pointer_origin),
|
||||
_builtin_background(builtin_background),
|
||||
_framebuffer(framebuffer),
|
||||
@ -278,10 +275,14 @@ struct Nitpicker::Main : Focus_updater
|
||||
|
||||
Constructible<Attached_rom_dataspace> _focus_rom { };
|
||||
|
||||
Root<PT> _root = { _env, _config_rom, _session_list, *_domain_registry,
|
||||
_global_keys, _view_stack, _user_state, _pointer_origin,
|
||||
_builtin_background, _sliced_heap, _framebuffer,
|
||||
_focus_reporter, *this };
|
||||
Tff_font::Static_glyph_buffer<4096> _glyph_buffer { };
|
||||
|
||||
Tff_font const _font { _binary_default_tff_start, _glyph_buffer };
|
||||
|
||||
Root<PT> _root { _env, _config_rom, _session_list, *_domain_registry,
|
||||
_global_keys, _view_stack, _font, _user_state, _pointer_origin,
|
||||
_builtin_background, _sliced_heap, _framebuffer,
|
||||
_focus_reporter, *this };
|
||||
|
||||
/**
|
||||
* Focus_updater interface
|
||||
@ -350,7 +351,7 @@ struct Nitpicker::Main : Focus_updater
|
||||
*/
|
||||
void _draw_and_flush()
|
||||
{
|
||||
_view_stack.draw(_fb_screen->screen).flush([&] (Rect const &rect) {
|
||||
_view_stack.draw(_fb_screen->screen, _font).flush([&] (Rect const &rect) {
|
||||
_framebuffer.refresh(rect.x1(), rect.y1(),
|
||||
rect.w(), rect.h()); });
|
||||
}
|
||||
@ -446,7 +447,7 @@ void Nitpicker::Main::_handle_input()
|
||||
_view_stack.geometry(_pointer_origin, Rect(_user_state.pointer_pos(), Area()));
|
||||
|
||||
/* perform redraw and flush pixels to the framebuffer */
|
||||
_view_stack.draw(_fb_screen->screen).flush([&] (Rect const &rect) {
|
||||
_view_stack.draw(_fb_screen->screen, _font).flush([&] (Rect const &rect) {
|
||||
_framebuffer.refresh(rect.x1(), rect.y1(),
|
||||
rect.w(), rect.h()); });
|
||||
|
||||
|
@ -35,7 +35,7 @@ struct Nitpicker::Pointer_origin : View_component
|
||||
|
||||
int frame_size(Focus const &) const override { return 0; }
|
||||
void frame(Canvas_base &, Focus const &) const override { }
|
||||
void draw(Canvas_base &, Focus const &) const override { }
|
||||
void draw(Canvas_base &, Font const &, Focus const &) const override { }
|
||||
};
|
||||
|
||||
#endif /* _POINTER_ORIGIN_H_ */
|
||||
|
@ -167,7 +167,7 @@ void Session_component::_execute_command(Command const &command)
|
||||
Locked_ptr<View_component> view(_view_handle_registry.lookup(cmd.view));
|
||||
|
||||
if (view.valid())
|
||||
_view_stack.title(*view, cmd.title.string());
|
||||
_view_stack.title(*view, _font, cmd.title.string());
|
||||
|
||||
return;
|
||||
}
|
||||
@ -259,6 +259,7 @@ Session_component::View_handle Session_component::create_view(View_handle parent
|
||||
catch (Allocator::Out_of_memory) { throw Out_of_ram(); }
|
||||
}
|
||||
|
||||
view->title(_font, "");
|
||||
view->apply_origin_policy(_pointer_origin);
|
||||
|
||||
_view_list.insert(view);
|
||||
|
@ -99,6 +99,8 @@ class Nitpicker::Session_component : public Rpc_object<Session>,
|
||||
|
||||
View_stack &_view_stack;
|
||||
|
||||
Font const &_font;
|
||||
|
||||
Focus_controller &_focus_controller;
|
||||
|
||||
Signal_context_capability _mode_sigh { };
|
||||
@ -166,6 +168,7 @@ class Nitpicker::Session_component : public Rpc_object<Session>,
|
||||
Session_component(Env &env,
|
||||
Session_label const &label,
|
||||
View_stack &view_stack,
|
||||
Font const &font,
|
||||
Focus_controller &focus_controller,
|
||||
View_component &pointer_origin,
|
||||
View_component &builtin_background,
|
||||
@ -181,7 +184,7 @@ class Nitpicker::Session_component : public Rpc_object<Session>,
|
||||
_session_alloc(&session_alloc, ram_quota),
|
||||
_framebuffer(framebuffer),
|
||||
_framebuffer_session_component(view_stack, *this, framebuffer, *this),
|
||||
_view_stack(view_stack), _focus_controller(focus_controller),
|
||||
_view_stack(view_stack), _font(font), _focus_controller(focus_controller),
|
||||
_pointer_origin(pointer_origin),
|
||||
_builtin_background(builtin_background),
|
||||
_framebuffer_session_cap(_env.ep().manage(_framebuffer_session_component)),
|
||||
|
@ -76,12 +76,12 @@ namespace Nitpicker {
|
||||
using namespace Nitpicker;
|
||||
|
||||
|
||||
void View_component::title(Title const &title)
|
||||
void View_component::title(Font const &font, Title const &title)
|
||||
{
|
||||
_title = title;
|
||||
|
||||
/* calculate label size, the position is defined by the view stack */
|
||||
_label_rect = Rect(Point(0, 0), label_size(_owner.label().string(),
|
||||
_label_rect = Rect(Point(0, 0), label_size(font, _owner.label().string(),
|
||||
_title.string()));
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ void View_component::frame(Canvas_base &canvas, Focus const &focus) const
|
||||
}
|
||||
|
||||
|
||||
void View_component::draw(Canvas_base &canvas, Focus const &focus) const
|
||||
void View_component::draw(Canvas_base &canvas, Font const &font, Focus const &focus) const
|
||||
{
|
||||
Texture_painter::Mode const op = texture_painter_mode(focus, _owner);
|
||||
|
||||
@ -138,7 +138,7 @@ void View_component::draw(Canvas_base &canvas, Focus const &focus) const
|
||||
|
||||
/* draw label */
|
||||
Color const frame_color = owner_color;
|
||||
draw_label(canvas, _label_rect.p1(), _owner.label().string(), white(),
|
||||
draw_label(canvas, font, _label_rect.p1(), _owner.label().string(), white(),
|
||||
_title.string(), frame_color);
|
||||
}
|
||||
|
||||
|
@ -96,10 +96,10 @@ class Nitpicker::View_component : private Same_buffer_list_elem,
|
||||
|
||||
View_component *_parent; /* parent view */
|
||||
Rect _geometry { }; /* position and size relative to parent */
|
||||
Rect _label_rect { }; /* position and size of label */
|
||||
Rect _label_rect { }; /* position and size of label */
|
||||
Point _buffer_off { }; /* offset to the visible buffer area */
|
||||
View_owner &_owner;
|
||||
Title _title { };
|
||||
Title _title { "" };
|
||||
Dirty_rect _dirty_rect { };
|
||||
|
||||
List<View_parent_elem> _children { };
|
||||
@ -130,11 +130,8 @@ class Nitpicker::View_component : private Same_buffer_list_elem,
|
||||
View_component(View_owner &owner, Transparent transparent,
|
||||
Background bg, View_component *parent)
|
||||
:
|
||||
_transparent(transparent), _background(bg), _parent(parent),
|
||||
_owner(owner)
|
||||
{
|
||||
title(""); /* initialize '_label_rect' */
|
||||
}
|
||||
_transparent(transparent), _background(bg), _parent(parent), _owner(owner)
|
||||
{ }
|
||||
|
||||
virtual ~View_component()
|
||||
{
|
||||
@ -217,12 +214,12 @@ class Nitpicker::View_component : private Same_buffer_list_elem,
|
||||
/**
|
||||
* Draw view on canvas
|
||||
*/
|
||||
virtual void draw(Canvas_base &canvas, Focus const &) const;
|
||||
virtual void draw(Canvas_base &, Font const &, Focus const &) const;
|
||||
|
||||
/**
|
||||
* Set view title
|
||||
*/
|
||||
void title(Title const &title);
|
||||
void title(Font const &, Title const &);
|
||||
|
||||
/**
|
||||
* Return successor in view stack
|
||||
|
@ -168,7 +168,8 @@ void View_stack::_place_labels(Rect rect)
|
||||
}
|
||||
|
||||
|
||||
void View_stack::draw_rec(Canvas_base &canvas, View_component const *view, Rect rect) const
|
||||
void View_stack::draw_rec(Canvas_base &canvas, Font const &font,
|
||||
View_component const *view, Rect rect) const
|
||||
{
|
||||
Rect clipped;
|
||||
|
||||
@ -185,8 +186,8 @@ void View_stack::draw_rec(Canvas_base &canvas, View_component const *view, Rect
|
||||
View_component const *next = _next_view(*view);
|
||||
|
||||
/* draw areas at the top/left of the current view */
|
||||
if (next && top.valid()) draw_rec(canvas, next, top);
|
||||
if (next && left.valid()) draw_rec(canvas, next, left);
|
||||
if (next && top.valid()) draw_rec(canvas, font, next, top);
|
||||
if (next && left.valid()) draw_rec(canvas, font, next, left);
|
||||
|
||||
/* draw current view */
|
||||
view->dirty_rect().flush([&] (Rect const &dirty_rect) {
|
||||
@ -195,15 +196,15 @@ void View_stack::draw_rec(Canvas_base &canvas, View_component const *view, Rect
|
||||
|
||||
/* draw background if view is transparent */
|
||||
if (view->uses_alpha())
|
||||
draw_rec(canvas, _next_view(*view), clipped);
|
||||
draw_rec(canvas, font, _next_view(*view), clipped);
|
||||
|
||||
view->frame(canvas, _focus);
|
||||
view->draw(canvas, _focus);
|
||||
view->draw(canvas, font, _focus);
|
||||
});
|
||||
|
||||
/* draw areas at the bottom/right of the current view */
|
||||
if (next && right.valid()) draw_rec(canvas, next, right);
|
||||
if (next && bottom.valid()) draw_rec(canvas, next, bottom);
|
||||
if (next && right.valid()) draw_rec(canvas, font, next, right);
|
||||
if (next && bottom.valid()) draw_rec(canvas, font, next, bottom);
|
||||
}
|
||||
|
||||
|
||||
@ -285,9 +286,9 @@ void View_stack::stack(View_component &view, View_component const *neighbor, boo
|
||||
}
|
||||
|
||||
|
||||
void View_stack::title(View_component &view, const char *title)
|
||||
void View_stack::title(View_component &view, Font const &font, const char *title)
|
||||
{
|
||||
view.title(title);
|
||||
view.title(font, title);
|
||||
_place_labels(view.abs_geometry());
|
||||
|
||||
_mark_view_as_dirty(view, _outline(view));
|
||||
|
@ -115,17 +115,17 @@ class Nitpicker::View_stack
|
||||
*
|
||||
* \param view current view in view stack
|
||||
*/
|
||||
void draw_rec(Canvas_base &, View_component const *view, Rect) const;
|
||||
void draw_rec(Canvas_base &, Font const &, View_component const *, Rect) const;
|
||||
|
||||
/**
|
||||
* Draw dirty areas
|
||||
*/
|
||||
Dirty_rect draw(Canvas_base &canvas) const
|
||||
Dirty_rect draw(Canvas_base &canvas, Font const &font) const
|
||||
{
|
||||
Dirty_rect result = _dirty_rect;
|
||||
|
||||
_dirty_rect.flush([&] (Rect const &rect) {
|
||||
draw_rec(canvas, _first_view(), rect); });
|
||||
draw_rec(canvas, font, _first_view(), rect); });
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -227,7 +227,7 @@ class Nitpicker::View_stack
|
||||
/**
|
||||
* Set view title
|
||||
*/
|
||||
void title(View_component &view, char const *title);
|
||||
void title(View_component &view, Font const &font, char const *title);
|
||||
|
||||
/**
|
||||
* Find view at specified position
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <util/register.h>
|
||||
|
||||
/* nitpicker graphics backend */
|
||||
#include <nitpicker_gfx/text_painter.h>
|
||||
#include <nitpicker_gfx/tff_font.h>
|
||||
|
||||
#include <nul/motherboard.h>
|
||||
#include <host/screen.h>
|
||||
@ -32,8 +32,10 @@
|
||||
/* local includes */
|
||||
#include "console.h"
|
||||
|
||||
extern char _binary_mono_tff_start;
|
||||
Text_painter::Font default_font(&_binary_mono_tff_start);
|
||||
extern char _binary_mono_tff_start[];
|
||||
|
||||
static Tff_font::Static_glyph_buffer<4096> glyph_buffer { };
|
||||
static Tff_font default_font(_binary_mono_tff_start, glyph_buffer);
|
||||
|
||||
static struct {
|
||||
Genode::uint64_t checksum1 = 0;
|
||||
@ -241,7 +243,7 @@ unsigned Seoul::Console::_handle_fb()
|
||||
|
||||
for (int j=0; j<25; j++) {
|
||||
for (int i=0; i<80; i++) {
|
||||
Genode::Surface_base::Point where(i*8, j*15);
|
||||
Text_painter::Position const where(i*8, j*15);
|
||||
char character = *((char *) (_guest_fb +(_regs->offset << 1) +j*80*2+i*2));
|
||||
char colorvalue = *((char *) (_guest_fb+(_regs->offset << 1)+j*80*2+i*2+1));
|
||||
char buffer[2]; buffer[0] = character; buffer[1] = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user