Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(407)

Side by Side Diff: chrome/browser/ui/libgtk2ui/gtk2_ui.cc

Issue 2441043002: [linux] Allow font to use below 1.0f scale (Closed)
Patch Set: Allow font to use below 1.0f scale Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h" 5 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 #include <pango/pango.h> 8 #include <pango/pango.h>
9 #include <X11/Xcursor/Xcursor.h> 9 #include <X11/Xcursor/Xcursor.h>
10
11 #include <cmath>
10 #include <set> 12 #include <set>
11 #include <utility> 13 #include <utility>
12 14
13 #include "base/command_line.h" 15 #include "base/command_line.h"
14 #include "base/debug/leak_annotations.h" 16 #include "base/debug/leak_annotations.h"
15 #include "base/environment.h" 17 #include "base/environment.h"
16 #include "base/i18n/rtl.h" 18 #include "base/i18n/rtl.h"
17 #include "base/logging.h" 19 #include "base/logging.h"
18 #include "base/macros.h" 20 #include "base/macros.h"
19 #include "base/nix/mime_util_xdg.h" 21 #include "base/nix/mime_util_xdg.h"
20 #include "base/nix/xdg_util.h" 22 #include "base/nix/xdg_util.h"
21 #include "base/stl_util.h" 23 #include "base/stl_util.h"
22 #include "base/strings/string_split.h" 24 #include "base/strings/string_split.h"
23 #include "base/strings/stringprintf.h" 25 #include "base/strings/stringprintf.h"
24 #include "chrome/browser/themes/theme_properties.h" 26 #include "chrome/browser/themes/theme_properties.h"
25 #include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h" 27 #include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h"
26 #include "chrome/browser/ui/libgtk2ui/gtk2_event_loop.h" 28 #include "chrome/browser/ui/libgtk2ui/gtk2_event_loop.h"
27 #include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h" 29 #include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h"
28 #include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h" 30 #include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h"
29 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h" 31 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
30 #include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h" 32 #include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h"
31 #include "chrome/browser/ui/libgtk2ui/print_dialog_gtk2.h" 33 #include "chrome/browser/ui/libgtk2ui/print_dialog_gtk2.h"
32 #include "chrome/browser/ui/libgtk2ui/printing_gtk2_util.h" 34 #include "chrome/browser/ui/libgtk2ui/printing_gtk2_util.h"
33 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h" 35 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h"
34 #include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h" 36 #include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
35 #include "chrome/browser/ui/libgtk2ui/unity_service.h" 37 #include "chrome/browser/ui/libgtk2ui/unity_service.h"
36 #include "chrome/browser/ui/libgtk2ui/x11_input_method_context_impl_gtk2.h" 38 #include "chrome/browser/ui/libgtk2ui/x11_input_method_context_impl_gtk2.h"
39 #include "chrome/common/chrome_switches.h"
37 #include "chrome/grit/theme_resources.h" 40 #include "chrome/grit/theme_resources.h"
38 #include "components/grit/components_scaled_resources.h" 41 #include "components/grit/components_scaled_resources.h"
39 #include "third_party/skia/include/core/SkBitmap.h" 42 #include "third_party/skia/include/core/SkBitmap.h"
40 #include "third_party/skia/include/core/SkCanvas.h" 43 #include "third_party/skia/include/core/SkCanvas.h"
41 #include "third_party/skia/include/core/SkColor.h" 44 #include "third_party/skia/include/core/SkColor.h"
42 #include "third_party/skia/include/core/SkShader.h" 45 #include "third_party/skia/include/core/SkShader.h"
43 #include "ui/base/resource/resource_bundle.h" 46 #include "ui/base/resource/resource_bundle.h"
44 #include "ui/display/display.h" 47 #include "ui/display/display.h"
45 #include "ui/gfx/canvas.h" 48 #include "ui/gfx/canvas.h"
46 #include "ui/gfx/geometry/rect.h" 49 #include "ui/gfx/geometry/rect.h"
(...skipping 30 matching lines...) Expand all
77 // linux/debian_wheezy_i386-sysroot/usr/include/linux/stddef.h redefines NULL 80 // linux/debian_wheezy_i386-sysroot/usr/include/linux/stddef.h redefines NULL
78 // to 0, which breaks -Wsentinel. Get back the normal definition of NULL. 81 // to 0, which breaks -Wsentinel. Get back the normal definition of NULL.
79 // TODO(thakis): Remove this once we update sysroots. 82 // TODO(thakis): Remove this once we update sysroots.
80 #define __need_NULL 83 #define __need_NULL
81 #include <stddef.h> 84 #include <stddef.h>
82 85
83 namespace libgtk2ui { 86 namespace libgtk2ui {
84 87
85 namespace { 88 namespace {
86 89
90 const double kDefaultDPI = 96;
91
87 class GtkButtonImageSource : public gfx::ImageSkiaSource { 92 class GtkButtonImageSource : public gfx::ImageSkiaSource {
88 public: 93 public:
89 GtkButtonImageSource(const char* idr_string, gfx::Size size) 94 GtkButtonImageSource(const char* idr_string, gfx::Size size)
90 : width_(size.width()), height_(size.height()) { 95 : width_(size.width()), height_(size.height()) {
91 is_blue_ = !!strstr(idr_string, "IDR_BLUE"); 96 is_blue_ = !!strstr(idr_string, "IDR_BLUE");
92 focus_ = !!strstr(idr_string, "_FOCUSED_"); 97 focus_ = !!strstr(idr_string, "_FOCUSED_");
93 98
94 if (strstr(idr_string, "_DISABLED")) { 99 if (strstr(idr_string, "_DISABLED")) {
95 state_ = ui::NativeTheme::kDisabled; 100 state_ = ui::NativeTheme::kDisabled;
96 } else if (strstr(idr_string, "_HOVER")) { 101 } else if (strstr(idr_string, "_HOVER")) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 LOG(WARNING) << "Unexpected gtk-xft-rgba \"" << rgba << "\""; 350 LOG(WARNING) << "Unexpected gtk-xft-rgba \"" << rgba << "\"";
346 params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE; 351 params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE;
347 } 352 }
348 353
349 g_free(hint_style); 354 g_free(hint_style);
350 g_free(rgba); 355 g_free(rgba);
351 356
352 return params; 357 return params;
353 } 358 }
354 359
355 double GetDPI() { 360 double GetDPI() {
Evan Stade 2016/10/25 17:27:02 nit: GetDpi
356 // Linux chrome currently does not support dynamic DPI changes. 361 if (display::Display::HasForceDeviceScaleFactor())
357 // Keep using the first value detected. 362 return display::Display::GetForcedDeviceScaleFactor() * kDefaultDPI;
358 static double dpi = -1.f;
359 if (dpi < 0) {
360 const double kDefaultDPI = 96;
361 363
362 if (display::Display::HasForceDeviceScaleFactor()) { 364 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
363 dpi = display::Display::GetForcedDeviceScaleFactor() * kDefaultDPI; 365 switches::kEnableXDpiForDsf)) {
364 return dpi; 366 XDisplay* xdisplay = gfx::GetXDisplay();
365 } 367 int xscreen = DefaultScreen(xdisplay);
368 return (DisplayHeight(xdisplay, xscreen) * 25.4) /
369 DisplayHeightMM(xdisplay, xscreen);
370 }
366 371
367 GtkSettings* gtk_settings = gtk_settings_get_default(); 372 GtkSettings* gtk_settings = gtk_settings_get_default();
368 CHECK(gtk_settings); 373 CHECK(gtk_settings);
369 gint gtk_dpi = -1; 374 gint gtk_dpi = -1;
370 g_object_get(gtk_settings, "gtk-xft-dpi", &gtk_dpi, NULL); 375 g_object_get(gtk_settings, "gtk-xft-dpi", &gtk_dpi, NULL);
371 376
372 // GTK multiplies the DPI by 1024 before storing it. 377 // GTK multiplies the DPI by 1024 before storing it.
373 dpi = (gtk_dpi > 0) ? gtk_dpi / 1024.0 : kDefaultDPI; 378 return (gtk_dpi > 0) ? gtk_dpi / 1024.0 : kDefaultDPI;
374
375 // DSF is always >=1.0 on win/cros and lower DSF has never been considered
376 // nor tested.
377 dpi = std::max(kDefaultDPI, dpi);
378 }
379 return dpi;
380 } 379 }
381 380
382 // Queries GTK for its font DPI setting and returns the number of pixels in a 381 float GetRawDeviceScaleFactor() {
383 // point. 382 if (display::Display::HasForceDeviceScaleFactor())
384 double GetPixelsInPoint(float device_scale_factor) { 383 return display::Display::GetForcedDeviceScaleFactor();
385 double dpi = GetDPI(); 384 return GetDPI() / kDefaultDPI;
385 }
386
387 // Returns the font size for the *raw* device scale factor in points.
388 // The |device_scale_factor| is used to cancel the scale to be applied by UI
389 // and to compensate the scale when the device_scale_factor is floored.
390 double GetFontSizePixelsInPoint(float device_scale_factor) {
391 // There are 72 points in an inch.
392 double point = GetDPI() / 72.0;
386 393
387 // Take device_scale_factor into account — if Chrome already scales the 394 // Take device_scale_factor into account — if Chrome already scales the
388 // entire UI up by 2x, we should not also scale up. 395 // entire UI up by 2x, we should not also scale up.
389 dpi /= device_scale_factor; 396 point /= device_scale_factor;
390 397
391 // There are 72 points in an inch. 398 // Allow the scale lower than 1.0 only for fonts. Don't always use
392 return dpi / 72.0; 399 // the raw value however, beacuse the 1.0~1.3 is rounded to 1.0.
400 float raw_scale = GetRawDeviceScaleFactor();
401 if (raw_scale < 1.0f)
402 return point * raw_scale / device_scale_factor;
403 return point;
393 } 404 }
394 405
395 views::LinuxUI::NonClientMiddleClickAction GetDefaultMiddleClickAction() { 406 views::LinuxUI::NonClientMiddleClickAction GetDefaultMiddleClickAction() {
396 std::unique_ptr<base::Environment> env(base::Environment::Create()); 407 std::unique_ptr<base::Environment> env(base::Environment::Create());
397 switch (base::nix::GetDesktopEnvironment(env.get())) { 408 switch (base::nix::GetDesktopEnvironment(env.get())) {
398 case base::nix::DESKTOP_ENVIRONMENT_KDE4: 409 case base::nix::DESKTOP_ENVIRONMENT_KDE4:
399 case base::nix::DESKTOP_ENVIRONMENT_KDE5: 410 case base::nix::DESKTOP_ENVIRONMENT_KDE5:
400 // Starting with KDE 4.4, windows' titlebars can be dragged with the 411 // Starting with KDE 4.4, windows' titlebars can be dragged with the
401 // middle mouse button to create tab groups. We don't support that in 412 // middle mouse button to create tab groups. We don't support that in
402 // Chrome, but at least avoid lowering windows in response to middle 413 // Chrome, but at least avoid lowering windows in response to middle
403 // clicks to avoid surprising users who expect the KDE behavior. 414 // clicks to avoid surprising users who expect the KDE behavior.
404 return views::LinuxUI::MIDDLE_CLICK_ACTION_NONE; 415 return views::LinuxUI::MIDDLE_CLICK_ACTION_NONE;
405 default: 416 default:
406 return views::LinuxUI::MIDDLE_CLICK_ACTION_LOWER; 417 return views::LinuxUI::MIDDLE_CLICK_ACTION_LOWER;
407 } 418 }
408 } 419 }
409 420
410 } // namespace 421 } // namespace
411 422
412 Gtk2UI::Gtk2UI() 423 Gtk2UI::Gtk2UI()
413 : default_font_size_pixels_(0), 424 : default_font_size_pixels_(0),
414 default_font_style_(gfx::Font::NORMAL), 425 default_font_style_(gfx::Font::NORMAL),
415 default_font_weight_(gfx::Font::Weight::NORMAL), 426 default_font_weight_(gfx::Font::Weight::NORMAL),
416 middle_click_action_(GetDefaultMiddleClickAction()), 427 middle_click_action_(GetDefaultMiddleClickAction()) {
417 device_scale_factor_(1.0) {
418 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); 428 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
419 } 429 }
420 430
421 Gtk2UI::~Gtk2UI() {} 431 Gtk2UI::~Gtk2UI() {}
422 432
423 void OnThemeChanged(GObject* obj, GParamSpec* param, Gtk2UI* gtkui) { 433 void OnThemeChanged(GObject* obj, GParamSpec* param, Gtk2UI* gtkui) {
424 gtkui->ResetStyle(); 434 gtkui->ResetStyle();
425 } 435 }
426 436
427 void Gtk2UI::Initialize() { 437 void Gtk2UI::Initialize() {
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 colors_[ThemeProperties::COLOR_TOOLBAR] = toolbar_color; 816 colors_[ThemeProperties::COLOR_TOOLBAR] = toolbar_color;
807 817
808 colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON] = 818 colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON] =
809 color_utils::DeriveDefaultIconColor(label_color); 819 color_utils::DeriveDefaultIconColor(label_color);
810 820
811 colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color; 821 colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color;
812 colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color; 822 colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color;
813 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = 823 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] =
814 color_utils::BlendTowardOppositeLuma(label_color, 50); 824 color_utils::BlendTowardOppositeLuma(label_color, 50);
815 825
816 UpdateDefaultFont(); 826 UpdateDeviceScaleFactor();
817 827
818 // Build the various icon tints. 828 // Build the various icon tints.
819 GetNormalButtonTintHSL(&button_tint_); 829 GetNormalButtonTintHSL(&button_tint_);
820 GetNormalEntryForegroundHSL(&entry_tint_); 830 GetNormalEntryForegroundHSL(&entry_tint_);
821 GetSelectedEntryForegroundHSL(&selected_entry_tint_); 831 GetSelectedEntryForegroundHSL(&selected_entry_tint_);
822 832
823 // We pick the text and background colors for the NTP out of the colors for a 833 // We pick the text and background colors for the NTP out of the colors for a
824 // GtkEntry. We do this because GtkEntries background color is never the same 834 // GtkEntry. We do this because GtkEntries background color is never the same
825 // as |toolbar_color|, is usually a white, and when it isn't a white, 835 // as |toolbar_color|, is usually a white, and when it isn't a white,
826 // provides sufficient contrast to |toolbar_color|. Try this out with 836 // provides sufficient contrast to |toolbar_color|. Try this out with
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 // If the size is absolute, it's specified in Pango units. There are 1049 // If the size is absolute, it's specified in Pango units. There are
1040 // PANGO_SCALE Pango units in a device unit (pixel). 1050 // PANGO_SCALE Pango units in a device unit (pixel).
1041 const int size_pixels = pango_font_description_get_size(desc) / PANGO_SCALE; 1051 const int size_pixels = pango_font_description_get_size(desc) / PANGO_SCALE;
1042 default_font_size_pixels_ = size_pixels; 1052 default_font_size_pixels_ = size_pixels;
1043 query.pixel_size = size_pixels; 1053 query.pixel_size = size_pixels;
1044 } else { 1054 } else {
1045 // Non-absolute sizes are in points (again scaled by PANGO_SIZE). 1055 // Non-absolute sizes are in points (again scaled by PANGO_SIZE).
1046 // Round the value when converting to pixels to match GTK's logic. 1056 // Round the value when converting to pixels to match GTK's logic.
1047 const double size_points = pango_font_description_get_size(desc) / 1057 const double size_points = pango_font_description_get_size(desc) /
1048 static_cast<double>(PANGO_SCALE); 1058 static_cast<double>(PANGO_SCALE);
1049 default_font_size_pixels_ = static_cast<int>( 1059 default_font_size_pixels_ = std::round(
1050 GetPixelsInPoint(device_scale_factor_) * size_points + 0.5); 1060 GetFontSizePixelsInPoint(GetDeviceScaleFactor()) * size_points);
1051 query.point_size = static_cast<int>(size_points); 1061 query.point_size = static_cast<int>(size_points);
1052 } 1062 }
1053 1063
1054 query.style = gfx::Font::NORMAL; 1064 query.style = gfx::Font::NORMAL;
1055 query.weight = 1065 query.weight =
1056 static_cast<gfx::Font::Weight>(pango_font_description_get_weight(desc)); 1066 static_cast<gfx::Font::Weight>(pango_font_description_get_weight(desc));
1057 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? 1067 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE?
1058 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) 1068 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC)
1059 query.style |= gfx::Font::ITALIC; 1069 query.style |= gfx::Font::ITALIC;
1060 1070
1061 default_font_render_params_ = 1071 default_font_render_params_ =
1062 gfx::GetFontRenderParams(query, &default_font_family_); 1072 gfx::GetFontRenderParams(query, &default_font_family_);
1063 default_font_style_ = query.style; 1073 default_font_style_ = query.style;
1064 } 1074 }
1065 1075
1066 void Gtk2UI::ResetStyle() { 1076 void Gtk2UI::ResetStyle() {
1067 LoadGtkValues(); 1077 LoadGtkValues();
1068 NativeThemeGtk2::instance()->NotifyObservers(); 1078 NativeThemeGtk2::instance()->NotifyObservers();
1069 } 1079 }
1070 1080
1071 void Gtk2UI::UpdateDeviceScaleFactor(float device_scale_factor) { 1081 void Gtk2UI::UpdateDeviceScaleFactor() {
1072 device_scale_factor_ = device_scale_factor; 1082 // Note: Linux chrome currently does not support dynamic DPI
1083 // changes. This is to allow flags to override the DPI settings
1084 // during startup.
1085 float scale = GetRawDeviceScaleFactor();
1086
1087 // Blacklist scaling factors <130% (crbug.com/484400) and round
1088 // to 1 decimal to prevent rendering problems (crbug.com/485183).
1089 device_scale_factor_ = scale < 1.3f ? 1.0f : roundf(scale * 10) / 10;
1073 UpdateDefaultFont(); 1090 UpdateDefaultFont();
1074 } 1091 }
1075 1092
1076 float Gtk2UI::GetDeviceScaleFactor() const { 1093 float Gtk2UI::GetDeviceScaleFactor() const {
1077 if (display::Display::HasForceDeviceScaleFactor()) 1094 return device_scale_factor_;
1078 return display::Display::GetForcedDeviceScaleFactor();
1079 const int kCSSDefaultDPI = 96;
1080 const float scale = GetDPI() / kCSSDefaultDPI;
1081
1082 // Blacklist scaling factors <130% (crbug.com/484400) and round
1083 // to 1 decimal to prevent rendering problems (crbug.com/485183).
1084 return scale < 1.3f ? 1.0f : roundf(scale * 10) / 10;
1085 } 1095 }
1086 1096
1087 } // namespace libgtk2ui 1097 } // namespace libgtk2ui
1088 1098
1089 views::LinuxUI* BuildGtk2UI() { 1099 views::LinuxUI* BuildGtk2UI() {
1090 return new libgtk2ui::Gtk2UI; 1100 return new libgtk2ui::Gtk2UI;
1091 } 1101 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/libgtk2ui/gtk2_ui.h ('k') | chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698