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

Side by Side Diff: ui/gfx/canvas_skia_linux.cc

Issue 7511029: Implement Pango RenderText for Linux. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: fix compilation error. using ICU functions for utf8/utf16 conversion Created 9 years, 4 months 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | ui/gfx/gtk_util.h » ('j') | ui/gfx/gtk_util.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "ui/gfx/canvas_skia.h" 5 #include "ui/gfx/canvas_skia.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include <cairo/cairo.h> 9 #include <cairo/cairo.h>
10 #include <gtk/gtk.h> 10 #include <gtk/gtk.h>
11 #include <pango/pango.h> 11 #include <pango/pango.h>
12 #include <pango/pangocairo.h> 12 #include <pango/pangocairo.h>
13 13
14 #include "base/i18n/rtl.h" 14 #include "base/i18n/rtl.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/utf_string_conversions.h"
17 #include "ui/gfx/font.h" 16 #include "ui/gfx/font.h"
18 #include "ui/gfx/gtk_util.h" 17 #include "ui/gfx/gtk_util.h"
19 #include "ui/gfx/platform_font_gtk.h" 18 #include "ui/gfx/platform_font_gtk.h"
20 #include "ui/gfx/rect.h" 19 #include "ui/gfx/rect.h"
21 #include "ui/gfx/skia_util.h" 20 #include "ui/gfx/skia_util.h"
22 21
23 using std::max; 22 using std::max;
24 23
25 namespace { 24 namespace {
26 25
27 const gunichar kAcceleratorChar = '&';
28
29 // Multiply by the text height to determine how much text should be faded 26 // Multiply by the text height to determine how much text should be faded
30 // when elliding. 27 // when elliding.
31 const double kFadeWidthFactor = 1.5; 28 const double kFadeWidthFactor = 1.5;
32 29
33 // End state of the elliding fade. 30 // End state of the elliding fade.
34 const double kFadeFinalAlpha = 0.15; 31 const double kFadeFinalAlpha = 0.15;
35 32
36 // Width of the border drawn around haloed text. 33 // Width of the border drawn around haloed text.
37 const double kTextHaloWidth = 1.0; 34 const double kTextHaloWidth = 1.0;
38 35
39 // Font settings that we initialize once and then use when drawing text in
40 // DrawStringInt().
41 cairo_font_options_t* cairo_font_options = NULL;
42
43 // Update |cairo_font_options| based on GtkSettings, allocating it if needed.
44 void UpdateCairoFontOptions() {
45 if (!cairo_font_options)
46 cairo_font_options = cairo_font_options_create();
47
48 gint antialias = 0;
49 gint hinting = 0;
50 gchar* hint_style = NULL;
51 gchar* rgba_style = NULL;
52
53 #if !defined(USE_WAYLAND)
54 GtkSettings* gtk_settings = gtk_settings_get_default();
55 g_object_get(gtk_settings,
56 "gtk-xft-antialias", &antialias,
57 "gtk-xft-hinting", &hinting,
58 "gtk-xft-hintstyle", &hint_style,
59 "gtk-xft-rgba", &rgba_style,
60 NULL);
61 #endif
62
63 // g_object_get() doesn't tell us whether the properties were present or not,
64 // but if they aren't (because gnome-settings-daemon isn't running), we'll get
65 // NULL values for the strings.
66 if (hint_style && rgba_style) {
67 if (!antialias) {
68 cairo_font_options_set_antialias(cairo_font_options,
69 CAIRO_ANTIALIAS_NONE);
70 } else if (strcmp(rgba_style, "none") == 0) {
71 cairo_font_options_set_antialias(cairo_font_options,
72 CAIRO_ANTIALIAS_GRAY);
73 } else {
74 cairo_font_options_set_antialias(cairo_font_options,
75 CAIRO_ANTIALIAS_SUBPIXEL);
76 cairo_subpixel_order_t cairo_subpixel_order =
77 CAIRO_SUBPIXEL_ORDER_DEFAULT;
78 if (strcmp(rgba_style, "rgb") == 0) {
79 cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
80 } else if (strcmp(rgba_style, "bgr") == 0) {
81 cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
82 } else if (strcmp(rgba_style, "vrgb") == 0) {
83 cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
84 } else if (strcmp(rgba_style, "vbgr") == 0) {
85 cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
86 }
87 cairo_font_options_set_subpixel_order(cairo_font_options,
88 cairo_subpixel_order);
89 }
90
91 cairo_hint_style_t cairo_hint_style = CAIRO_HINT_STYLE_DEFAULT;
92 if (hinting == 0 || strcmp(hint_style, "hintnone") == 0) {
93 cairo_hint_style = CAIRO_HINT_STYLE_NONE;
94 } else if (strcmp(hint_style, "hintslight") == 0) {
95 cairo_hint_style = CAIRO_HINT_STYLE_SLIGHT;
96 } else if (strcmp(hint_style, "hintmedium") == 0) {
97 cairo_hint_style = CAIRO_HINT_STYLE_MEDIUM;
98 } else if (strcmp(hint_style, "hintfull") == 0) {
99 cairo_hint_style = CAIRO_HINT_STYLE_FULL;
100 }
101 cairo_font_options_set_hint_style(cairo_font_options, cairo_hint_style);
102 }
103
104 if (hint_style)
105 g_free(hint_style);
106 if (rgba_style)
107 g_free(rgba_style);
108 }
109
110 // Pass a width > 0 to force wrapping and elliding.
111 void SetupPangoLayout(PangoLayout* layout,
112 const string16& text,
113 const gfx::Font& font,
114 int width,
115 base::i18n::TextDirection text_direction,
116 int flags) {
117 if (!cairo_font_options)
118 UpdateCairoFontOptions();
119 // This needs to be done early on; it has no effect when called just before
120 // pango_cairo_show_layout().
121 pango_cairo_context_set_font_options(
122 pango_layout_get_context(layout), cairo_font_options);
123
124 // Callers of DrawStringInt handle RTL layout themselves, so tell pango to not
125 // scope out RTL characters.
126 pango_layout_set_auto_dir(layout, FALSE);
127
128 if (width > 0)
129 pango_layout_set_width(layout, width * PANGO_SCALE);
130
131 if (flags & gfx::Canvas::TEXT_ALIGN_CENTER) {
132 // We don't support center aligned w/ eliding.
133 DCHECK(gfx::Canvas::NO_ELLIPSIS);
134 pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
135 } else if (flags & gfx::Canvas::TEXT_ALIGN_RIGHT) {
136 pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT);
137 }
138
139 if (flags & gfx::Canvas::NO_ELLIPSIS) {
140 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
141 if (flags & gfx::Canvas::MULTI_LINE) {
142 pango_layout_set_wrap(layout,
143 (flags & gfx::Canvas::CHARACTER_BREAK) ?
144 PANGO_WRAP_WORD_CHAR : PANGO_WRAP_WORD);
145 }
146 } else if (text_direction == base::i18n::RIGHT_TO_LEFT){
147 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
148 } else {
149 // Fading the text will be handled in the draw operation.
150 // that the text is only on one line.
151 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
152 pango_layout_set_width(layout, -1);
153 }
154
155 // Set the resolution to match that used by Gtk. If we don't set the
156 // resolution and the resolution differs from the default, Gtk and Chrome end
157 // up drawing at different sizes.
158 double resolution = gfx::GetPangoResolution();
159 if (resolution > 0) {
160 pango_cairo_context_set_resolution(pango_layout_get_context(layout),
161 resolution);
162 }
163
164 PangoFontDescription* desc = font.GetNativeFont();
165 pango_layout_set_font_description(layout, desc);
166 pango_font_description_free(desc);
167
168 // Set text and accelerator character if needed.
169 std::string utf8 = UTF16ToUTF8(text);
170 if (flags & gfx::Canvas::SHOW_PREFIX) {
171 // Escape the text string to be used as markup.
172 gchar* escaped_text = g_markup_escape_text(utf8.c_str(), utf8.size());
173 pango_layout_set_markup_with_accel(layout,
174 escaped_text,
175 strlen(escaped_text),
176 kAcceleratorChar, NULL);
177 g_free(escaped_text);
178 } else if (flags & gfx::Canvas::HIDE_PREFIX) {
179 // Remove the ampersand character. A double ampersand is output as
180 // a single ampersand.
181 DCHECK_EQ(1, g_unichar_to_utf8(kAcceleratorChar, NULL));
182 const std::string accelerator_removed =
183 gfx::RemoveAcceleratorChar(utf8, static_cast<char>(kAcceleratorChar));
184
185 pango_layout_set_text(layout,
186 accelerator_removed.data(), accelerator_removed.size());
187 } else {
188 pango_layout_set_text(layout, utf8.data(), utf8.size());
189 }
190 }
191
192 // A class to encapsulate string drawing params and operations. 36 // A class to encapsulate string drawing params and operations.
193 class DrawStringContext { 37 class DrawStringContext {
194 public: 38 public:
195 DrawStringContext(gfx::CanvasSkia* canvas, 39 DrawStringContext(gfx::CanvasSkia* canvas,
196 const string16& text, 40 const string16& text,
197 const gfx::Font& font, 41 const gfx::Font& font,
198 const gfx::Rect& bounds, 42 const gfx::Rect& bounds,
199 const gfx::Rect& clip, 43 const gfx::Rect& clip,
200 int flags); 44 int flags);
201 ~DrawStringContext(); 45 ~DrawStringContext();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 text_x_(bounds.x()), 86 text_x_(bounds.x()),
243 text_y_(bounds.y()), 87 text_y_(bounds.y()),
244 text_width_(0), 88 text_width_(0),
245 text_height_(0), 89 text_height_(0),
246 text_direction_(base::i18n::GetFirstStrongCharacterDirection(text)) { 90 text_direction_(base::i18n::GetFirstStrongCharacterDirection(text)) {
247 DCHECK(!bounds_.IsEmpty()); 91 DCHECK(!bounds_.IsEmpty());
248 92
249 cr_ = skia::BeginPlatformPaint(canvas_); 93 cr_ = skia::BeginPlatformPaint(canvas_);
250 layout_ = pango_cairo_create_layout(cr_); 94 layout_ = pango_cairo_create_layout(cr_);
251 95
252 SetupPangoLayout( 96 gfx::SetupPangoLayout(
253 layout_, text, font, bounds_.width(), text_direction_, flags_); 97 layout_, text, font, bounds_.width(), text_direction_, flags_);
254 98
255 pango_layout_set_height(layout_, bounds_.height() * PANGO_SCALE); 99 pango_layout_set_height(layout_, bounds_.height() * PANGO_SCALE);
256 100
257 cairo_save(cr_); 101 cairo_save(cr_);
258 102
259 cairo_rectangle(cr_, clip.x(), clip.y(), clip.width(), clip.height()); 103 cairo_rectangle(cr_, clip.x(), clip.y(), clip.width(), clip.height());
260 cairo_clip(cr_); 104 cairo_clip(cr_);
261 105
262 pango_layout_get_pixel_size(layout_, &text_width_, &text_height_); 106 pango_layout_get_pixel_size(layout_, &text_width_, &text_height_);
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); 339 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y);
496 cairo_paint(cr); 340 cairo_paint(cr);
497 } 341 }
498 342
499 ui::TextureID CanvasSkia::GetTextureID() { 343 ui::TextureID CanvasSkia::GetTextureID() {
500 // TODO(wjmaclean) 344 // TODO(wjmaclean)
501 return 0; 345 return 0;
502 } 346 }
503 347
504 } // namespace gfx 348 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | ui/gfx/gtk_util.h » ('j') | ui/gfx/gtk_util.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698