linux: Use scalable fonts and Fontconfig's bitmap setting.
[chromium-blink-merge.git] / ui / gfx / font_render_params_linux.cc
blob7bdee19cc809f239f8805a3f942ee5d191e1f41e
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
3 // found in the LICENSE file.
5 #include "ui/gfx/font_render_params.h"
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "ui/gfx/font.h"
10 #include "ui/gfx/linux_font_delegate.h"
11 #include "ui/gfx/switches.h"
13 #include <fontconfig/fontconfig.h>
15 namespace gfx {
17 namespace {
19 // Converts Fontconfig FC_HINT_STYLE to FontRenderParams::Hinting.
20 FontRenderParams::Hinting ConvertFontconfigHintStyle(int hint_style) {
21 switch (hint_style) {
22 case FC_HINT_SLIGHT: return FontRenderParams::HINTING_SLIGHT;
23 case FC_HINT_MEDIUM: return FontRenderParams::HINTING_MEDIUM;
24 case FC_HINT_FULL: return FontRenderParams::HINTING_FULL;
25 default: return FontRenderParams::HINTING_NONE;
29 // Converts Fontconfig FC_RGBA to FontRenderParams::SubpixelRendering.
30 FontRenderParams::SubpixelRendering ConvertFontconfigRgba(int rgba) {
31 switch (rgba) {
32 case FC_RGBA_RGB: return FontRenderParams::SUBPIXEL_RENDERING_RGB;
33 case FC_RGBA_BGR: return FontRenderParams::SUBPIXEL_RENDERING_BGR;
34 case FC_RGBA_VRGB: return FontRenderParams::SUBPIXEL_RENDERING_VRGB;
35 case FC_RGBA_VBGR: return FontRenderParams::SUBPIXEL_RENDERING_VBGR;
36 default: return FontRenderParams::SUBPIXEL_RENDERING_NONE;
40 // Queries Fontconfig for rendering settings and updates |params_out| and
41 // |family_out| (if non-NULL). Returns false on failure. See
42 // GetCustomFontRenderParams() for descriptions of arguments.
43 bool QueryFontconfig(const std::vector<std::string>* family_list,
44 const int* pixel_size,
45 const int* point_size,
46 const int* style,
47 FontRenderParams* params_out,
48 std::string* family_out) {
49 FcPattern* pattern = FcPatternCreate();
50 CHECK(pattern);
52 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
54 if (family_list) {
55 for (std::vector<std::string>::const_iterator it = family_list->begin();
56 it != family_list->end(); ++it) {
57 FcPatternAddString(
58 pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(it->c_str()));
61 if (pixel_size)
62 FcPatternAddDouble(pattern, FC_PIXEL_SIZE, *pixel_size);
63 if (point_size)
64 FcPatternAddInteger(pattern, FC_SIZE, *point_size);
65 if (style) {
66 FcPatternAddInteger(pattern, FC_SLANT,
67 (*style & Font::ITALIC) ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
68 FcPatternAddInteger(pattern, FC_WEIGHT,
69 (*style & Font::BOLD) ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL);
72 FcConfigSubstitute(NULL, pattern, FcMatchPattern);
73 FcDefaultSubstitute(pattern);
74 FcResult result;
75 FcPattern* match = FcFontMatch(NULL, pattern, &result);
76 FcPatternDestroy(pattern);
77 if (!match)
78 return false;
80 if (family_out) {
81 FcChar8* family = NULL;
82 FcPatternGetString(match, FC_FAMILY, 0, &family);
83 if (family)
84 family_out->assign(reinterpret_cast<const char*>(family));
87 if (params_out) {
88 FcBool fc_antialias = 0;
89 FcPatternGetBool(match, FC_ANTIALIAS, 0, &fc_antialias);
90 params_out->antialiasing = fc_antialias;
92 FcBool fc_autohint = 0;
93 FcPatternGetBool(match, FC_AUTOHINT, 0, &fc_autohint);
94 params_out->autohinter = fc_autohint;
96 FcBool fc_bitmap = 0;
97 FcPatternGetBool(match, FC_EMBEDDED_BITMAP, 0, &fc_bitmap);
98 params_out->use_bitmaps = fc_bitmap;
100 FcBool fc_hinting = 0;
101 int fc_hint_style = FC_HINT_NONE;
102 FcPatternGetBool(match, FC_HINTING, 0, &fc_hinting);
103 if (fc_hinting)
104 FcPatternGetInteger(match, FC_HINT_STYLE, 0, &fc_hint_style);
105 params_out->hinting = ConvertFontconfigHintStyle(fc_hint_style);
107 int fc_rgba = FC_RGBA_NONE;
108 FcPatternGetInteger(match, FC_RGBA, 0, &fc_rgba);
109 params_out->subpixel_rendering = ConvertFontconfigRgba(fc_rgba);
112 FcPatternDestroy(match);
113 return true;
116 // Returns the system's default settings.
117 FontRenderParams LoadDefaults(bool for_web_contents) {
118 return GetCustomFontRenderParams(
119 for_web_contents, NULL, NULL, NULL, NULL, NULL);
122 } // namespace
124 const FontRenderParams& GetDefaultFontRenderParams() {
125 static FontRenderParams default_params = LoadDefaults(false);
126 return default_params;
129 const FontRenderParams& GetDefaultWebKitFontRenderParams() {
130 static FontRenderParams default_params = LoadDefaults(true);
131 return default_params;
134 FontRenderParams GetCustomFontRenderParams(
135 bool for_web_contents,
136 const std::vector<std::string>* family_list,
137 const int* pixel_size,
138 const int* point_size,
139 const int* style,
140 std::string* family_out) {
141 if (family_out)
142 family_out->clear();
144 // Start with the delegate's settings, but let Fontconfig have the final say.
145 FontRenderParams params;
146 const LinuxFontDelegate* delegate = LinuxFontDelegate::instance();
147 if (delegate)
148 params = delegate->GetDefaultFontRenderParams();
149 QueryFontconfig(
150 family_list, pixel_size, point_size, style, &params, family_out);
152 // Fontconfig doesn't support configuring subpixel positioning; check a flag.
153 params.subpixel_positioning = CommandLine::ForCurrentProcess()->HasSwitch(
154 for_web_contents ?
155 switches::kEnableWebkitTextSubpixelPositioning :
156 switches::kEnableBrowserTextSubpixelPositioning);
158 // To enable subpixel positioning, we need to disable hinting.
159 if (params.subpixel_positioning)
160 params.hinting = FontRenderParams::HINTING_NONE;
162 // Use the first family from the list if Fontconfig didn't suggest a family.
163 if (family_out && family_out->empty() &&
164 family_list && !family_list->empty())
165 *family_out = (*family_list)[0];
167 return params;
170 } // namespace gfx