From 7cae04027847dad5d5b243274c940b9ee454d033 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 2 Sep 2015 03:31:28 +0200 Subject: [PATCH] Support custom font settings in splash window + X11 impl --- direct/src/plugin/p3dInstance.cxx | 40 +++++++++++++ direct/src/plugin/p3dOsxSplashWindow.cxx | 2 +- direct/src/plugin/p3dSplashWindow.cxx | 61 ++++++++++++++++++++ direct/src/plugin/p3dSplashWindow.h | 20 +++++++ direct/src/plugin/p3dX11SplashWindow.cxx | 73 ++++++++++++++++++++++-- 5 files changed, 190 insertions(+), 6 deletions(-) diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index 87db3f1edc..87fbf64dee 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -2830,6 +2830,46 @@ make_splash_window() { nout << "parse failure on bar_height " << bar_height << "\n"; } } + if (_fparams.has_token("font_family")) { + string family = _fparams.lookup_token("font_family"); + _splash_window->set_font_family(family); + } + if (_fparams.has_token("font_size")) { + int size = _fparams.lookup_token_int("font_size"); + _splash_window->set_font_size(size); + } + if (_fparams.has_token("font_style")) { + string style = _fparams.lookup_token("font_style"); + + if (style == "normal") { + _splash_window->set_font_style(P3DSplashWindow::FS_normal); + } else if (style == "oblique") { + _splash_window->set_font_style(P3DSplashWindow::FS_oblique); + } else if (style == "italic") { + _splash_window->set_font_style(P3DSplashWindow::FS_italic); + } else { + nout << "parse_failure on font_style " << style << "\n"; + } + } + if (_fparams.has_token("font_weight")) { + string weight = _fparams.lookup_token("font_weight"); + + if (weight == "normal") { + _splash_window->set_font_weight(400); + } else if (weight == "bold") { + _splash_window->set_font_weight(700); + } else if (weight == "bolder") { + _splash_window->set_font_weight(700); + } else if (weight == "lighter") { + _splash_window->set_font_weight(100); + } else if (weight.size() == 3 && + weight[0] >= '1' && weight[0] <= '9' && + weight[1] == '0' && weight[2] == '0') { + _splash_window->set_font_weight(((int)weight[0] - 48) * 100); + } else { + nout << "parse_failure on font_weight " << weight << "\n"; + } + } _splash_window->set_wparams(_wparams); _splash_window->set_install_label(_install_label); diff --git a/direct/src/plugin/p3dOsxSplashWindow.cxx b/direct/src/plugin/p3dOsxSplashWindow.cxx index 979b35160d..6b979b2a7b 100644 --- a/direct/src/plugin/p3dOsxSplashWindow.cxx +++ b/direct/src/plugin/p3dOsxSplashWindow.cxx @@ -683,7 +683,7 @@ paint_progress_bar(CGContextRef context) { // Choose a suitable font. float text_height = 15.0; - CGContextSelectFont(context, "Helvetica", text_height, kCGEncodingMacRoman); + CGContextSelectFont(context, _font_family.c_str(), text_height, kCGEncodingMacRoman); // Measure the text, for centering. CGContextSetTextPosition(context, 0, 0); diff --git a/direct/src/plugin/p3dSplashWindow.cxx b/direct/src/plugin/p3dSplashWindow.cxx index d9dcd802dd..37960d4499 100644 --- a/direct/src/plugin/p3dSplashWindow.cxx +++ b/direct/src/plugin/p3dSplashWindow.cxx @@ -57,6 +57,10 @@ P3DSplashWindow(P3DInstance *inst, bool make_visible) : _bar_height = 22; _bar_width_ratio = 0.6; _bar_height_ratio = 0.1; + _font_family = "Helvetica"; + _font_size = 12; + _font_style = FS_normal; + _font_weight = FW_normal; _button_width = 0; _button_height = 0; _button_x = 0; @@ -268,6 +272,63 @@ set_bar_height(int height, bool percent) { } } +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::set_font_family +// Access: Public +// Description: Sets the font family of the text above the loading +// bar. +// +// This may only be set before wparams is set. +//////////////////////////////////////////////////////////////////// +void P3DSplashWindow:: +set_font_family(const string &family) { + nout << "font_family " << family << "\n"; + _font_family = family; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::set_font_size +// Access: Public +// Description: Sets the font size in pixels of the text above the +// loading bar. The default value is 12. +// +// This may only be set before wparams is set. +//////////////////////////////////////////////////////////////////// +void P3DSplashWindow:: +set_font_size(int size) { + nout << "font_size " << size << "\n"; + _font_size = size; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::set_font_style +// Access: Public +// Description: Sets the font style of the text above the loading +// bar. +// +// This may only be set before wparams is set. +//////////////////////////////////////////////////////////////////// +void P3DSplashWindow:: +set_font_style(FontStyle style) { + nout << "font_style " << style << "\n"; + _font_style = style; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::set_font_weight +// Access: Public +// Description: Sets the font weight of the text above the loading +// bar. The default is FW_normal. It should be +// a multiple of 100 in the range 100-900. +// +// This may only be set before wparams is set. +//////////////////////////////////////////////////////////////////// +void P3DSplashWindow:: +set_font_weight(int weight) { + nout << "font_weight " << weight << "\n"; + _font_weight = weight; +} + //////////////////////////////////////////////////////////////////// // Function: P3DSplashWindow::set_install_label // Access: Public, Virtual diff --git a/direct/src/plugin/p3dSplashWindow.h b/direct/src/plugin/p3dSplashWindow.h index edbc02c448..3b98b2cfa1 100644 --- a/direct/src/plugin/p3dSplashWindow.h +++ b/direct/src/plugin/p3dSplashWindow.h @@ -51,6 +51,17 @@ public: IP_button_click, IP_none }; + enum FontStyle { + FS_normal, + FS_italic, + FS_oblique + }; + enum FontWeight { + FW_normal = 400, + FW_medium = 500, + FW_bold = 700, + FW_black = 900 + }; virtual void set_image_filename(const string &image_filename, ImagePlacement image_placement); @@ -62,6 +73,10 @@ public: void set_bar_bottom(int bottom); void set_bar_width(int width, bool percent=false); void set_bar_height(int height, bool percent=false); + void set_font_family(const string &family); + void set_font_size(int size); + void set_font_style(FontStyle style); + void set_font_weight(int weight); virtual void set_install_label(const string &install_label); virtual void set_install_progress(double install_progress, bool is_progress_known, size_t received_data); @@ -119,6 +134,11 @@ private: double _bar_width_ratio, _bar_height_ratio; protected: + string _font_family; + int _font_size; + FontStyle _font_style; + int _font_weight; + // The region of the window for accepting button clicks. int _button_width, _button_height; int _button_x, _button_y; diff --git a/direct/src/plugin/p3dX11SplashWindow.cxx b/direct/src/plugin/p3dX11SplashWindow.cxx index 6d3d2919a7..4c41b3ca4c 100644 --- a/direct/src/plugin/p3dX11SplashWindow.cxx +++ b/direct/src/plugin/p3dX11SplashWindow.cxx @@ -25,8 +25,6 @@ #include #include -static const char *xfont_name = "-*-helvetica-medium-r-normal--12-120-*-*-p-*-iso8859-1"; - //////////////////////////////////////////////////////////////////// // Function: P3DX11SplashWindow::Constructor // Access: Public @@ -987,12 +985,77 @@ setup_gc() { return; } - _font = XLoadQueryFont(_display, xfont_name); + char style = 'r'; + if (_font_style == FS_oblique) { + style = 'o'; + } else if (_font_style == FS_italic) { + style = 'i'; + } + + // Determine the order at which to try the various weights. From: + // https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight + const char *const *try_weights; + const int num_weights = 7; + + if (_font_weight > 700) { + static const char *const weights[] = {"black", "bold", "demibold", "semibold", "medium", "regular", "extralight"}; + try_weights = weights; + + } else if (_font_weight > 600) { + static const char *const weights[] = {"bold", "black", "demibold", "semibold", "medium", "regular", "extralight"}; + try_weights = weights; + + } else if (_font_weight > 500) { + static const char *const weights[] = {"demibold", "semibold", "bold", "black", "medium", "regular", "extralight"}; + try_weights = weights; + + } else if (_font_weight == 500) { + static const char *const weights[] = {"medium", "regular", "extralight", "demibold", "semibold", "bold", "black"}; + try_weights = weights; + + } else if (_font_weight >= 400) { + static const char *const weights[] = {"regular", "medium", "extralight", "demibold", "semibold", "bold", "black"}; + try_weights = weights; + + } else { + static const char *const weights[] = {"extralight", "regular", "medium", "demibold", "semibold", "bold", "black"}; + try_weights = weights; + } + + char font_name[1024]; + + // Go through the weights array to find the best matching font. + for (int i = 0; i < num_weights; ++i) { + const char *weight_name = try_weights[i]; + + // Compose the proper pattern for finding the desired font face. + snprintf(font_name, 1024, "-*-%s-%s-%c-normal--%d-*-*-*-*-*-iso8859-1", + _font_family.c_str(), weight_name, style, _font_size); + + _font = XLoadQueryFont(_display, font_name); + if (_font != NULL) { + break; + } + nout << "Font " << font_name << " unavailable.\n"; + + if (style == 'i' || style == 'o') { + // If oblique is not found, try italic, and vice versa. + char style2 = 216 - style; + snprintf(font_name, 1024, "-*-%s-%s-%c-normal--%d-*-*-*-*-*-iso8859-1", + _font_family.c_str(), weight_name, style2, _font_size); + + _font = XLoadQueryFont(_display, font_name); + if (_font != NULL) { + break; + } + nout << "Font " << font_name << " unavailable.\n"; + } + } if (_font != NULL) { - nout << "Loaded font " << xfont_name << "\n"; + nout << "Loaded font " << font_name << "\n"; } else { - nout << "Font " << xfont_name << " unavailable.\n"; + nout << "Using fallback font 6x13.\n"; _font = XLoadQueryFont(_display, "6x13"); }