menu_view: VFS-based font handling

Fixes #2773
This commit is contained in:
Norman Feske 2018-04-17 13:35:30 +02:00 committed by Christian Helmuth
parent 403b5413fc
commit 26a2591896
8 changed files with 118 additions and 54 deletions

View File

@ -13,3 +13,7 @@ framebuffer_session
input_session
timer_session
report_session
block_session
file_system_session
rtc_session
terminal_session

View File

@ -4,6 +4,7 @@ import_from_depot genodelabs/src/[base_src] \
genodelabs/pkg/[drivers_interactive_pkg] \
genodelabs/pkg/wm \
genodelabs/raw/genode_bg \
genodelabs/pkg/fonts_fs \
genodelabs/pkg/backdrop \
genodelabs/src/demo \
genodelabs/src/init \
@ -220,38 +221,48 @@ install_config {
</route>
</start>
<start name="launcher" caps="1000">
<start name="fonts_fs" caps="300">
<resource name="RAM" quantum="8M"/>
<binary name="vfs"/>
<route>
<service name="ROM" label="config"> <parent label="fonts_fs.config"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="File_system"/> </provides>
</start>
<start name="launcher" caps="10000">
<resource name="RAM" quantum="60M" />
<config focus_prefix="wm -> launcher -> ">
<subsystem name="scout" title="Scout" caps="200">
<resource name="RAM" quantum="20M" />
<binary name="scout" />
</subsystem>
<subsystem name="testnit1" title="Nitpicker Test" caps="25">
<subsystem name="testnit1" title="Nitpicker Test" caps="100">
<resource name="RAM" quantum="2M" />
<binary name="testnit" />
</subsystem>
<subsystem name="testnit2" title="Nitpicker Test 2" caps="25">
<subsystem name="testnit2" title="Nitpicker Test 2" caps="100">
<resource name="RAM" quantum="2M" />
<binary name="testnit" />
</subsystem>
<subsystem name="testnit3" title="Nitpicker Test 3" caps="25">
<subsystem name="testnit3" title="Nitpicker Test 3" caps="100">
<resource name="RAM" quantum="2M" />
<binary name="testnit" />
</subsystem>
<subsystem name="scout2" title="Scoutx" caps="25">
<subsystem name="scout2" title="Scoutx" caps="200">
<resource name="RAM" quantum="20M" />
<binary name="scout" />
</subsystem>
<subsystem name="testnit4" title="Nitpicker Testx" caps="25">
<subsystem name="testnit4" title="Nitpicker Testx" caps="100">
<resource name="RAM" quantum="2M" />
<binary name="testnit" />
</subsystem>
<subsystem name="testnit5" title="Nitpicker Test5" caps="25">
<subsystem name="testnit5" title="Nitpicker Test5" caps="100">
<resource name="RAM" quantum="2M" />
<binary name="testnit" />
</subsystem>
<subsystem name="backdrop" title="Backdrop" caps="25">
<subsystem name="backdrop" title="Backdrop" caps="100">
<resource name="RAM" quantum="4M"/>
<binary name="backdrop" />
<config>
@ -266,6 +277,7 @@ install_config {
</config>
<route>
<service name="ROM" label="focus"> <child name="report_rom" /> </service>
<service name="File_system" label="fonts"> <child name="fonts_fs"/> </service>
<any-service> <child name="wm"/> <parent/> <any-child/> </any-service>
</route>
</start>
@ -275,5 +287,4 @@ build { app/launcher test/nitpicker app/status_bar app/global_keys_handler }
build_boot_image { testnit launcher global_keys_handler status_bar }
run_genode_until forever

View File

@ -2,6 +2,7 @@ create_boot_directory
import_from_depot genodelabs/src/[base_src] \
genodelabs/pkg/[drivers_interactive_pkg] \
genodelabs/pkg/fonts_fs \
genodelabs/src/init \
genodelabs/src/dynamic_rom \
genodelabs/src/report_rom \
@ -162,13 +163,16 @@ install_config {
<label text="VirtualBox"/>
</button>
<button name="toolchain" hovered="yes">
<label text="Tool chain"/>
<label text="Tool chain"
font="monospace/regular"/>
</button>
<button name="log" hovered="yes" selected="yes">
<label text="Log window"/>
<label text="Log window"
font="title/regular"/>
</button>
<button name="config" selected="yes">
<label text="Configuration"/>
<label text="Configuration"
font="annotation/regular"/>
</button>
</vbox>
</frame>
@ -204,19 +208,31 @@ install_config {
<config verbose="yes"/>
</start>
<start name="fonts_fs" caps="300">
<resource name="RAM" quantum="8M"/>
<binary name="vfs"/>
<route>
<service name="ROM" label="config"> <parent label="fonts_fs.config"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="File_system"/> </provides>
</start>
<start name="menu_view" caps="200">
<resource name="RAM" quantum="5M"/>
<resource name="RAM" quantum="8M"/>
<config xpos="200" ypos="100">
<report hover="yes"/>
<libc stderr="/dev/log"/>
<vfs>
<tar name="menu_view_styles.tar" />
<dir name="dev"> <log/> </dir>
<dir name="fonts"> <fs label="fonts"/> </dir>
</vfs>
</config>
<route>
<service name="ROM" label="dialog"> <child name="dynamic_rom" /> </service>
<service name="Report" label="hover"> <child name="report_rom"/> </service>
<service name="File_system" label="fonts"> <child name="fonts_fs"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>

View File

@ -18,6 +18,7 @@
#include <os/static_parent_services.h>
#include <os/slave.h>
#include <nitpicker_session/nitpicker_session.h>
#include <file_system_session/file_system_session.h>
/* gems includes */
#include <os/single_session_service.h>
@ -43,6 +44,7 @@ class Launcher::Menu_view_slave
Genode::Ram_session,
Genode::Rom_session,
Genode::Log_session,
File_system::Session,
Timer::Session>,
public Genode::Slave::Policy
{
@ -66,6 +68,7 @@ class Launcher::Menu_view_slave
" <libc stderr=\"/dev/log\"/>\n"
" <vfs>\n"
" <tar name=\"menu_view_styles.tar\" />\n"
" <dir name=\"fonts\"> <fs label=\"fonts\"/> </dir>\n"
" </vfs>\n"
"</config>",
pos.x(), pos.y());

View File

@ -35,7 +35,7 @@ struct Menu_view::Label_widget : Widget
void update(Xml_node node)
{
font = _factory.styles.font(node, "font");
font = _factory.styles.font(node);
text = Decorator::string_attribute(node, "text", Text(""));
}
@ -45,7 +45,7 @@ struct Menu_view::Label_widget : Widget
return Area(0, 0);
return Area(font->string_width(text.string()).decimal(),
font->bounding_box().h());
font->height());
}
void draw(Surface<Pixel_rgb888> &pixel_surface,

View File

@ -28,6 +28,7 @@
/* gems includes */
#include <gems/nitpicker_buffer.h>
#include <gems/vfs.h>
namespace Menu_view { struct Main; }
@ -69,9 +70,34 @@ struct Menu_view::Main
Signal_handler<Main> _dialog_update_handler = {
_env.ep(), *this, &Main::_handle_dialog_update};
Attached_rom_dataspace _config { _env, "config" };
Heap _heap { _env.ram(), _env.rm() };
Style_database _styles { _env.ram(), _env.rm(), _heap };
struct Vfs_env : Vfs::Env, Vfs::Io_response_handler, Vfs::Watch_response_handler
{
Genode::Env &_env;
Allocator &_alloc;
Vfs::File_system &_vfs;
Vfs_env(Genode::Env &env, Allocator &alloc, Vfs::File_system &vfs)
: _env(env), _alloc(alloc), _vfs(vfs) { }
void handle_io_response (Vfs::Vfs_handle::Context *) override { }
void handle_watch_response(Vfs::Vfs_watch_handle::Context*) override { }
Genode::Env &env() override { return _env; }
Allocator &alloc() override { return _alloc; }
Vfs::File_system &root_dir() override { return _vfs; }
Io_response_handler &io_handler() override { return *this; }
Watch_response_handler &watch_handler() override { return *this; }
} _vfs_env;
Directory _root_dir { _vfs_env };
Directory _fonts_dir { _root_dir, "fonts" };
Style_database _styles { _env.ram(), _env.rm(), _heap, _fonts_dir };
Animator _animator;
@ -85,8 +111,6 @@ struct Menu_view::Main
Widget::Unique_id _hovered;
Attached_rom_dataspace _config { _env, "config" };
void _handle_config();
Signal_handler<Main> _config_handler = {
@ -138,7 +162,9 @@ struct Menu_view::Main
*/
unsigned _frame_cnt = 0;
Main(Env &env) : _env(env)
Main(Env &env, Vfs::File_system &libc_vfs)
:
_env(env), _vfs_env(_env, _heap, libc_vfs)
{
_dialog_rom.sigh(_dialog_update_handler);
_config.sigh(_config_handler);
@ -332,5 +358,8 @@ Menu_view::Widget_factory::create(Xml_node node)
extern "C" void _sigprocmask() { }
void Libc::Component::construct(Libc::Env &env) { static Menu_view::Main main(env); }
void Libc::Component::construct(Libc::Env &env)
{
static Menu_view::Main main(env, env.vfs());
}

View File

@ -14,12 +14,11 @@
#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>
#include <gems/cached_font.h>
#include <gems/vfs_font.h>
/* local includes */
#include "types.h"
@ -33,10 +32,14 @@ class Menu_view::Style_database
enum { PATH_MAX_LEN = 200 };
typedef String<PATH_MAX_LEN> Path;
typedef ::File::Reading_failed Reading_failed;
struct Texture_entry : List<Texture_entry>::Element
{
String<PATH_MAX_LEN> path;
File png_file;
Path const path;
::File png_file;
Png_image png_image;
Texture<Pixel_rgb888> &texture;
@ -46,10 +49,10 @@ class Menu_view::Style_database
* \throw Reading_failed
*/
Texture_entry(Ram_session &ram, Region_map &rm,
Allocator &alloc, char const *path)
Allocator &alloc, Path const &path)
:
path(path),
png_file(path, alloc),
png_file(path.string(), alloc),
png_image(ram, rm, alloc, png_file.data<void>()),
texture(*png_image.texture<Pixel_rgb888>())
{ }
@ -57,31 +60,32 @@ class Menu_view::Style_database
struct Font_entry : List<Font_entry>::Element
{
String<PATH_MAX_LEN> path;
Path const path;
File tff_file;
Cached_font::Limit _font_cache_limit { 256*1024 };
Vfs_font _vfs_font;
Cached_font _cached_font;
Tff_font::Allocated_glyph_buffer glyph_buffer;
Tff_font font;
Text_painter::Font const &font() const { return _cached_font; }
/**
* Constructor
*
* \throw Reading_failed
*/
Font_entry(char const *path, Allocator &alloc)
:
Font_entry(Directory const &fonts_dir, Path const &path, Allocator &alloc)
try :
path(path),
tff_file(path, alloc),
glyph_buffer(tff_file.data<char>(), alloc),
font(tff_file.data<char>(), glyph_buffer)
_vfs_font(alloc, fonts_dir, path),
_cached_font(alloc, _vfs_font, _font_cache_limit)
{ }
catch (...) { throw Reading_failed(); }
};
Ram_session &_ram;
Region_map &_rm;
Allocator &_alloc;
Ram_session &_ram;
Region_map &_rm;
Allocator &_alloc;
Directory const &_fonts_dir;
/*
* The list is mutable because it is populated as a side effect of
@ -100,8 +104,6 @@ class Menu_view::Style_database
return 0;
}
typedef String<256> Path;
/*
* Assemble path name 'styles/<widget>/<style>/<name>.<extension>'
*/
@ -116,9 +118,10 @@ class Menu_view::Style_database
public:
Style_database(Ram_session &ram, Region_map &rm, Allocator &alloc)
Style_database(Ram_session &ram, Region_map &rm, Allocator &alloc,
Directory const &fonts_dir)
:
_ram(ram), _rm(rm), _alloc(alloc)
_ram(ram), _rm(rm), _alloc(alloc), _fonts_dir(fonts_dir)
{ }
Texture<Pixel_rgb888> const *texture(Xml_node node, char const *png_name) const
@ -138,8 +141,7 @@ class Menu_view::Style_database
_textures.insert(e);
return &e->texture;
} catch (File::Reading_failed) {
} catch (Reading_failed) {
warning("could not read texture data from file \"", path.string(), "\"");
return nullptr;
}
@ -147,24 +149,23 @@ class Menu_view::Style_database
return nullptr;
}
Text_painter::Font const *font(Xml_node node, char const *tff_name) const
Text_painter::Font const *font(Xml_node node) const
{
Path const path = _construct_path(node, tff_name, "tff");
Path const path = node.attribute_value("font", Path("text/regular"));
if (Font_entry const *e = _lookup(_fonts, path.string()))
return &e->font;
return &e->font();
/*
* Load and remember font
*/
try {
Font_entry *e = new (_alloc)
Font_entry(path.string(), _alloc);
Font_entry(_fonts_dir, path, _alloc);
_fonts.insert(e);
return &e->font;
return &e->font();
} catch (File::Reading_failed) {
} catch (Reading_failed) {
warning("could not read font from file \"", path.string(), "\"");
return nullptr;

View File

@ -1,6 +1,6 @@
TARGET = menu_view
SRC_CC = main.cc
LIBS = base libc libm libpng zlib blit file
LIBS = base libc libm vfs libpng zlib blit file
INC_DIR += $(PRG_DIR)
.PHONY: menu_view_styles.tar