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

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 cursor bounds for RTL UI 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>
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 } 100 }
101 cairo_font_options_set_hint_style(cairo_font_options, cairo_hint_style); 101 cairo_font_options_set_hint_style(cairo_font_options, cairo_hint_style);
102 } 102 }
103 103
104 if (hint_style) 104 if (hint_style)
105 g_free(hint_style); 105 g_free(hint_style);
106 if (rgba_style) 106 if (rgba_style)
107 g_free(rgba_style); 107 g_free(rgba_style);
108 } 108 }
109 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);
msw 2011/08/19 23:16:59 You removed this line amidst the function move, an
xji 2011/08/22 23:57:28 The condition checking was changed from base:i18n:
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. 110 // A class to encapsulate string drawing params and operations.
193 class DrawStringContext { 111 class DrawStringContext {
194 public: 112 public:
195 DrawStringContext(gfx::CanvasSkia* canvas, 113 DrawStringContext(gfx::CanvasSkia* canvas,
196 const string16& text, 114 const string16& text,
197 const gfx::Font& font, 115 const gfx::Font& font,
198 const gfx::Rect& bounds, 116 const gfx::Rect& bounds,
199 const gfx::Rect& clip, 117 const gfx::Rect& clip,
200 int flags); 118 int flags);
201 ~DrawStringContext(); 119 ~DrawStringContext();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 text_x_(bounds.x()), 160 text_x_(bounds.x()),
243 text_y_(bounds.y()), 161 text_y_(bounds.y()),
244 text_width_(0), 162 text_width_(0),
245 text_height_(0), 163 text_height_(0),
246 text_direction_(base::i18n::GetFirstStrongCharacterDirection(text)) { 164 text_direction_(base::i18n::GetFirstStrongCharacterDirection(text)) {
247 DCHECK(!bounds_.IsEmpty()); 165 DCHECK(!bounds_.IsEmpty());
248 166
249 cr_ = skia::BeginPlatformPaint(canvas_); 167 cr_ = skia::BeginPlatformPaint(canvas_);
250 layout_ = pango_cairo_create_layout(cr_); 168 layout_ = pango_cairo_create_layout(cr_);
251 169
252 SetupPangoLayout( 170 gfx::SetupPangoLayout(
253 layout_, text, font, bounds_.width(), text_direction_, flags_); 171 layout_, text, font, bounds_.width(), text_direction_, flags_);
254 172
255 pango_layout_set_height(layout_, bounds_.height() * PANGO_SCALE); 173 pango_layout_set_height(layout_, bounds_.height() * PANGO_SCALE);
256 174
257 cairo_save(cr_); 175 cairo_save(cr_);
258 176
259 cairo_rectangle(cr_, clip.x(), clip.y(), clip.width(), clip.height()); 177 cairo_rectangle(cr_, clip.x(), clip.y(), clip.width(), clip.height());
260 cairo_clip(cr_); 178 cairo_clip(cr_);
261 179
262 pango_layout_get_pixel_size(layout_, &text_width_, &text_height_); 180 pango_layout_get_pixel_size(layout_, &text_width_, &text_height_);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 cr, platform_font->underline_thickness() + 2 * extra_edge_width); 301 cr, platform_font->underline_thickness() + 2 * extra_edge_width);
384 cairo_move_to(cr, text_x_ - extra_edge_width, underline_y); 302 cairo_move_to(cr, text_x_ - extra_edge_width, underline_y);
385 cairo_line_to(cr, text_x_ + text_width_ + extra_edge_width, underline_y); 303 cairo_line_to(cr, text_x_ + text_width_ + extra_edge_width, underline_y);
386 cairo_stroke(cr); 304 cairo_stroke(cr);
387 } 305 }
388 306
389 } // namespace 307 } // namespace
390 308
391 namespace gfx { 309 namespace gfx {
392 310
311 // Pass a width > 0 to force wrapping and elliding.
312 void SetupPangoLayout(PangoLayout* layout,
313 const string16& text,
314 const Font& font,
315 int width,
316 base::i18n::TextDirection text_direction,
317 int flags) {
318 if (!cairo_font_options)
319 UpdateCairoFontOptions();
320 // This needs to be done early on; it has no effect when called just before
321 // pango_cairo_show_layout().
322 pango_cairo_context_set_font_options(
323 pango_layout_get_context(layout), cairo_font_options);
324
325 // Callers of DrawStringInt handle RTL layout themselves, so tell pango to not
326 // scope out RTL characters.
327 pango_layout_set_auto_dir(layout, FALSE);
328
329 if (width > 0)
330 pango_layout_set_width(layout, width * PANGO_SCALE);
331
332 if (flags & Canvas::TEXT_ALIGN_CENTER) {
333 // We don't support center aligned w/ eliding.
334 DCHECK(gfx::Canvas::NO_ELLIPSIS);
335 pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
336 } else if (flags & Canvas::TEXT_ALIGN_RIGHT) {
337 pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT);
338 }
339
340 if (flags & Canvas::NO_ELLIPSIS) {
341 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
342 if (flags & Canvas::MULTI_LINE) {
343 pango_layout_set_wrap(layout,
344 (flags & Canvas::CHARACTER_BREAK) ?
345 PANGO_WRAP_WORD_CHAR : PANGO_WRAP_WORD);
346 }
347 } else if (text_direction == base::i18n::RIGHT_TO_LEFT) {
348 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
349 } else {
350 // Fading the text will be handled in the draw operation.
351 // that the text is only on one line.
msw 2011/08/19 23:16:59 Can you clarify (or at least complete) the second
xji 2011/08/22 23:57:28 the comments was added by davemoore in http://code
352 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
353 }
354
355 if (!base::i18n::IsRTL())
356 pango_layout_set_width(layout, -1);
357
358 // Set the resolution to match that used by Gtk. If we don't set the
359 // resolution and the resolution differs from the default, Gtk and Chrome end
360 // up drawing at different sizes.
361 double resolution = GetPangoResolution();
362 if (resolution > 0) {
363 pango_cairo_context_set_resolution(pango_layout_get_context(layout),
364 resolution);
365 }
366
367 PangoFontDescription* desc = font.GetNativeFont();
368 pango_layout_set_font_description(layout, desc);
369 pango_font_description_free(desc);
370
371 // Set text and accelerator character if needed.
372 std::string utf8 = UTF16ToUTF8(text);
373 if (flags & Canvas::SHOW_PREFIX) {
374 // Escape the text string to be used as markup.
375 gchar* escaped_text = g_markup_escape_text(utf8.c_str(), utf8.size());
376 pango_layout_set_markup_with_accel(layout,
377 escaped_text,
378 strlen(escaped_text),
379 kAcceleratorChar, NULL);
380 g_free(escaped_text);
381 } else if (flags & Canvas::HIDE_PREFIX) {
382 // Remove the ampersand character. A double ampersand is output as
383 // a single ampersand.
384 DCHECK_EQ(1, g_unichar_to_utf8(kAcceleratorChar, NULL));
385 const std::string accelerator_removed =
386 RemoveAcceleratorChar(utf8, static_cast<char>(kAcceleratorChar));
387
388 pango_layout_set_text(layout,
389 accelerator_removed.data(), accelerator_removed.size());
390 } else {
391 pango_layout_set_text(layout, utf8.data(), utf8.size());
392 }
393 }
394
393 CanvasSkia::CanvasSkia(int width, int height, bool is_opaque) 395 CanvasSkia::CanvasSkia(int width, int height, bool is_opaque)
394 : skia::PlatformCanvas(width, height, is_opaque) { 396 : skia::PlatformCanvas(width, height, is_opaque) {
395 } 397 }
396 398
397 CanvasSkia::CanvasSkia() : skia::PlatformCanvas() { 399 CanvasSkia::CanvasSkia() : skia::PlatformCanvas() {
398 } 400 }
399 401
400 CanvasSkia::~CanvasSkia() { 402 CanvasSkia::~CanvasSkia() {
401 } 403 }
402 404
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); 497 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y);
496 cairo_paint(cr); 498 cairo_paint(cr);
497 } 499 }
498 500
499 ui::TextureID CanvasSkia::GetTextureID() { 501 ui::TextureID CanvasSkia::GetTextureID() {
500 // TODO(wjmaclean) 502 // TODO(wjmaclean)
501 return 0; 503 return 0;
502 } 504 }
503 505
504 } // namespace gfx 506 } // 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