From 5c567d4f2034ac227350b2d72647cd0d37ebee68 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 24 Apr 2016 20:17:52 +0100 Subject: [PATCH] update beos to use font layout table --- beos/font.cpp | 484 +++++++++++++++++++++++++------------------------- beos/font.h | 4 +- beos/gui.cpp | 7 +- 3 files changed, 248 insertions(+), 247 deletions(-) diff --git a/beos/font.cpp b/beos/font.cpp index cba3e4d4b..cb4d3e6c9 100644 --- a/beos/font.cpp +++ b/beos/font.cpp @@ -30,260 +30,20 @@ #include #include #include + extern "C" { -#include "desktop/font.h" #include "utils/utils.h" #include "utils/log.h" #include "utils/nsoption.h" #include "utils/nsurl.h" + +#include "desktop/gui_layout.h" } #include "beos/gui.h" #include "beos/font.h" #include "beos/plotters.h" -static bool nsfont_width(const plot_font_style_t *fstyle, - const char *string, size_t length, - int *width); -static bool nsfont_position_in_string(const plot_font_style_t *fstyle, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x); -static bool nsfont_split(const plot_font_style_t *fstyle, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x); - -const struct font_functions nsfont = { - nsfont_width, - nsfont_position_in_string, - nsfont_split -}; - - -/** - * Measure the width of a string. - * - * \param fstyle style for this text - * \param string UTF-8 string to measure - * \param length length of string - * \param width updated to width of string[0..length) - * \return true on success, false on error and error reported - */ - -bool nsfont_width(const plot_font_style_t *fstyle, - const char *string, size_t length, - int *width) -{ - //fprintf(stderr, "%s(, '%s', %d, )\n", __FUNCTION__, string, length); - BFont font; - - if (length == 0) { - *width = 0; - return true; - } - - nsbeos_style_to_font(font, fstyle); - *width = (int)font.StringWidth(string, length); - return true; -} - - -static int utf8_char_len(const char *c) -{ - uint8 *p = (uint8 *)c; - uint8 m = 0xE0; - uint8 v = 0xC0; - int i; - if (!*p) - return 0; - if ((*p & 0x80) == 0) - return 1; - if ((*p & 0xC0) == 0x80) - return 1; // actually one of the remaining bytes... - for (i = 2; i < 5; i++) { - if ((*p & m) == v) - return i; - v = (v >> 1) | 0x80; - m = (m >> 1) | 0x80; - } - return i; -} - - -/** - * Find the position in a string where an x coordinate falls. - * - * \param fstyle style for this text - * \param string UTF-8 string to measure - * \param length length of string - * \param x x coordinate to search for - * \param char_offset updated to offset in string of actual_x, [0..length] - * \param actual_x updated to x coordinate of character closest to x - * \return true on success, false on error and error reported - */ - -bool nsfont_position_in_string(const plot_font_style_t *fstyle, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x) -{ - //LOG("(, '%s', %d, %d, , )", string, length, x); - //fprintf(stderr, "%s(, '%s', %d, %d, , )\n", __FUNCTION__, string, length, x); - int index; - BFont font; - - nsbeos_style_to_font(font, fstyle); - BString str(string); - int32 len = str.CountChars(); - float escapements[len]; - float esc = 0.0; - float current = 0.0; - int i; - index = 0; - font.GetEscapements(string, len, escapements); - // slow but it should work - for (i = 0; string[index] && i < len; i++) { - esc += escapements[i]; - current = font.Size() * esc; - index += utf8_char_len(&string[index]); - // is current char already too far away? - if (x < current) - break; - } - *actual_x = (int)current; - *char_offset = i; //index; - - return true; -} - - -/** - * Find where to split a string to make it fit a width. - * - * \param fstyle style for this text - * \param string UTF-8 string to measure - * \param length length of string, in bytes - * \param x width available - * \param char_offset updated to offset in string of actual_x, [1..length] - * \param actual_x updated to x coordinate of character closest to x - * \return true on success, false on error and error reported - * - * On exit, char_offset indicates first character after split point. - * - * Note: char_offset of 0 should never be returned. - * - * Returns: - * char_offset giving split point closest to x, where actual_x <= x - * else - * char_offset giving split point closest to x, where actual_x > x - * - * Returning char_offset == length means no split possible - */ - -bool nsfont_split(const plot_font_style_t *fstyle, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x) -{ - //fprintf(stderr, "%s(, '%s', %d, %d, , )\n", __FUNCTION__, string, length, x); - //LOG("(, '%s', %d, %d, , )", string, length, x); - int index = 0; - BFont font; - - nsbeos_style_to_font(font, fstyle); - BString str(string); - int32 len = str.CountChars(); - float escapements[len]; - float esc = 0.0; - float current = 0.0; - float last_x = 0.0; - int i; - int last_space = 0; - font.GetEscapements(string, len, escapements); - // very slow but it should work - for (i = 0; string[index] && i < len; i++) { - if (string[index] == ' ') { - last_x = current; - last_space = index; - } - if (x < current && last_space != 0) { - *actual_x = (int)last_x; - *char_offset = last_space; - return true; - } - esc += escapements[i]; - current = font.Size() * esc; - index += utf8_char_len(&string[index]); - } - *actual_x = MIN(*actual_x, (int)current); - *char_offset = index; - - return true; -} - - -/** - * Render a string. - * - * \param fstyle style for this text - * \param string UTF-8 string to measure - * \param length length of string - * \param x x coordinate - * \param y y coordinate - * \return true on success, false on error and error reported - */ - -bool nsfont_paint(const plot_font_style_t *fstyle, - const char *string, size_t length, - int x, int y) -{ - //fprintf(stderr, "%s(, '%s', %d, %d, %d, )\n", __FUNCTION__, string, length, x, y); - //CALLED(); - BFont font; - rgb_color oldbg; - rgb_color background; - rgb_color foreground; - BView *view; - float size; - - if (length == 0) - return true; - - nsbeos_style_to_font(font, fstyle); - background = nsbeos_rgb_colour(fstyle->background); - foreground = nsbeos_rgb_colour(fstyle->foreground); - - view = nsbeos_current_gc/*_lock*/(); - if (view == NULL) { - warn_user("No GC", 0); - return false; - } - - oldbg = view->LowColor(); - drawing_mode oldmode = view->DrawingMode(); - view->SetLowColor(B_TRANSPARENT_32_BIT); - - //view->SetScale() XXX - -//printf("nsfont_paint: Size: %f\n", font.Size()); - size = (float)font.Size(); -#warning XXX use scale - - view->SetFont(&font); - view->SetHighColor(foreground); - view->SetDrawingMode(B_OP_OVER); - - BString line(string, length); - - BPoint where(x, y + 1); - view->DrawString(line.String(), where); - - view->SetDrawingMode(oldmode); - if (memcmp(&oldbg, &background, sizeof(rgb_color))) - view->SetLowColor(oldbg); - - //nsbeos_current_gc_unlock(); - - return true; -} - /** * Convert a font style to a PangoFontDescription. @@ -291,7 +51,7 @@ bool nsfont_paint(const plot_font_style_t *fstyle, * \param font Beos font object. * \param fstyle style for this text */ -void nsbeos_style_to_font(BFont &font, const plot_font_style_t *fstyle) +void nsbeos_style_to_font(BFont &font, const struct plot_font_style *fstyle) { float size; uint16 face = 0; @@ -377,3 +137,239 @@ void nsbeos_style_to_font(BFont &font, const plot_font_style_t *fstyle) font.SetSize(size); } + + +/** + * Measure the width of a string. + * + * \param fstyle style for this text + * \param string UTF-8 string to measure + * \param length length of string + * \param width updated to width of string[0..length) + * \return true on success, false on error and error reported + */ +static nserror beos_font_width(const plot_font_style_t *fstyle, + const char *string, size_t length, + int *width) +{ + //fprintf(stderr, "%s(, '%s', %d, )\n", __FUNCTION__, string, length); + BFont font; + + if (length == 0) { + *width = 0; + return NSERROR_OK; + } + + nsbeos_style_to_font(font, fstyle); + *width = (int)font.StringWidth(string, length); + + return NSERROR_OK; +} + + +static int utf8_char_len(const char *c) +{ + uint8 *p = (uint8 *)c; + uint8 m = 0xE0; + uint8 v = 0xC0; + int i; + + if (!*p) + return 0; + if ((*p & 0x80) == 0) + return 1; + if ((*p & 0xC0) == 0x80) + return 1; // actually one of the remaining bytes... + for (i = 2; i < 5; i++) { + if ((*p & m) == v) + return i; + v = (v >> 1) | 0x80; + m = (m >> 1) | 0x80; + } + return i; +} + + +/** + * Find the position in a string where an x coordinate falls. + * + * \param fstyle style for this text + * \param string UTF-8 string to measure + * \param length length of string + * \param x x coordinate to search for + * \param char_offset updated to offset in string of actual_x, [0..length] + * \param actual_x updated to x coordinate of character closest to x + * \return true on success, false on error and error reported + */ +static nserror beos_font_position(const plot_font_style_t *fstyle, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) +{ + //LOG("(, '%s', %d, %d, , )", string, length, x); + //fprintf(stderr, "%s(, '%s', %d, %d, , )\n", __FUNCTION__, string, length, x); + int index; + BFont font; + + nsbeos_style_to_font(font, fstyle); + BString str(string); + int32 len = str.CountChars(); + float escapements[len]; + float esc = 0.0; + float current = 0.0; + int i; + + index = 0; + font.GetEscapements(string, len, escapements); + // slow but it should work + for (i = 0; string[index] && i < len; i++) { + esc += escapements[i]; + current = font.Size() * esc; + index += utf8_char_len(&string[index]); + // is current char already too far away? + if (x < current) + break; + } + *actual_x = (int)current; + *char_offset = i; //index; + + return NSERROR_OK; +} + + +/** + * Find where to split a string to make it fit a width. + * + * \param fstyle style for this text + * \param string UTF-8 string to measure + * \param length length of string, in bytes + * \param x width available + * \param char_offset updated to offset in string of actual_x, [1..length] + * \param actual_x updated to x coordinate of character closest to x + * \return true on success, false on error and error reported + * + * On exit, char_offset indicates first character after split point. + * + * Note: char_offset of 0 should never be returned. + * + * Returns: + * char_offset giving split point closest to x, where actual_x <= x + * else + * char_offset giving split point closest to x, where actual_x > x + * + * Returning char_offset == length means no split possible + */ +static nserror beos_font_split(const plot_font_style_t *fstyle, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) +{ + //fprintf(stderr, "%s(, '%s', %d, %d, , )\n", __FUNCTION__, string, length, x); + //LOG("(, '%s', %d, %d, , )", string, length, x); + int index = 0; + BFont font; + + nsbeos_style_to_font(font, fstyle); + BString str(string); + int32 len = str.CountChars(); + float escapements[len]; + float esc = 0.0; + float current = 0.0; + float last_x = 0.0; + int i; + int last_space = 0; + + font.GetEscapements(string, len, escapements); + // very slow but it should work + for (i = 0; string[index] && i < len; i++) { + if (string[index] == ' ') { + last_x = current; + last_space = index; + } + if (x < current && last_space != 0) { + *actual_x = (int)last_x; + *char_offset = last_space; + return true; + } + esc += escapements[i]; + current = font.Size() * esc; + index += utf8_char_len(&string[index]); + } + *actual_x = MIN(*actual_x, (int)current); + *char_offset = index; + + return NSERROR_OK; +} + + +/** + * Render a string. + * + * \param fstyle style for this text + * \param string UTF-8 string to measure + * \param length length of string + * \param x x coordinate + * \param y y coordinate + * \return true on success, false on error and error reported + */ + +bool nsfont_paint(const plot_font_style_t *fstyle, + const char *string, size_t length, + int x, int y) +{ + //fprintf(stderr, "%s(, '%s', %d, %d, %d, )\n", __FUNCTION__, string, length, x, y); + //CALLED(); + BFont font; + rgb_color oldbg; + rgb_color background; + rgb_color foreground; + BView *view; + float size; + + if (length == 0) + return true; + + nsbeos_style_to_font(font, fstyle); + background = nsbeos_rgb_colour(fstyle->background); + foreground = nsbeos_rgb_colour(fstyle->foreground); + + view = nsbeos_current_gc/*_lock*/(); + if (view == NULL) { + warn_user("No GC", 0); + return false; + } + + oldbg = view->LowColor(); + drawing_mode oldmode = view->DrawingMode(); + view->SetLowColor(B_TRANSPARENT_32_BIT); + + //view->SetScale() XXX + +//printf("nsfont_paint: Size: %f\n", font.Size()); + size = (float)font.Size(); +#warning XXX use scale + + view->SetFont(&font); + view->SetHighColor(foreground); + view->SetDrawingMode(B_OP_OVER); + + BString line(string, length); + + BPoint where(x, y + 1); + view->DrawString(line.String(), where); + + view->SetDrawingMode(oldmode); + if (memcmp(&oldbg, &background, sizeof(rgb_color))) + view->SetLowColor(oldbg); + + //nsbeos_current_gc_unlock(); + + return true; +} + + +static struct gui_layout_table layout_table = { + .width = beos_font_width, + .position = beos_font_position, + .split = beos_font_split, +}; + +struct gui_layout_table *beos_layout_table = &layout_table; diff --git a/beos/font.h b/beos/font.h index aefd898da..ce31929a9 100644 --- a/beos/font.h +++ b/beos/font.h @@ -28,4 +28,6 @@ bool nsfont_paint(const plot_font_style_t *fstyle, const char *string, size_t length, int x, int y); -void nsbeos_style_to_font(BFont &font, const plot_font_style_t *fstyle); +void nsbeos_style_to_font(BFont &font, const struct plot_font_style *fstyle); + +struct gui_layout_table *beos_layout_table; diff --git a/beos/gui.cpp b/beos/gui.cpp index c91cc43db..5171b211a 100644 --- a/beos/gui.cpp +++ b/beos/gui.cpp @@ -82,6 +82,7 @@ extern "C" { #include "beos/fetch_rsrc.h" #include "beos/scaffolding.h" #include "beos/bitmap.h" +#include "beos/font.h" //TODO: use resources // enable using resources instead of files @@ -989,7 +990,8 @@ int main(int argc, char** argv) NULL, /* default search */ NULL, /* default web search */ NULL, /* default low level cache persistant storage */ - beos_bitmap_table + beos_bitmap_table, + beos_layout_table }; ret = netsurf_register(&beos_table); @@ -1069,7 +1071,8 @@ int gui_init_replicant(int argc, char** argv) NULL, /* default search */ NULL, /* default web search */ NULL, /* default low level cache persistant storage */ - beos_bitmap_table + beos_bitmap_table, + beos_layout_table }; ret = netsurf_register(&beos_table);