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

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

Issue 8725002: Draw text via Skia in RenderTextLinux. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 9 years 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
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/render_text_linux.h" 5 #include "ui/gfx/render_text_linux.h"
6 6
7 #include <pango/pangocairo.h> 7 #include <pango/pangocairo.h>
8 #include <algorithm> 8 #include <algorithm>
9 #include <vector>
9 10
10 #include "base/i18n/break_iterator.h" 11 #include "base/i18n/break_iterator.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "ui/gfx/canvas_skia.h" 13 #include "ui/gfx/canvas_skia.h"
14 #include "ui/gfx/font.h"
13 #include "ui/gfx/pango_util.h" 15 #include "ui/gfx/pango_util.h"
14 #include "unicode/uchar.h" 16 #include "unicode/uchar.h"
15 #include "unicode/ustring.h" 17 #include "unicode/ustring.h"
16 18
17 namespace { 19 namespace {
18 20
19 // TODO(xji): instead of converting each R or G or B from 8-bit to 16-bit, 21 // TODO(xji): instead of converting each R or G or B from 8-bit to 16-bit,
20 // it should also massage A in the conversion. 22 // it should also massage A in the conversion.
21 int ConvertColorFrom8BitTo16Bit(int c) { 23 int ConvertColorFrom8BitTo16Bit(int c) {
22 return (c << 8) + c; 24 return (c << 8) + c;
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 pango_layout_line_ref(current_line_); 255 pango_layout_line_ref(current_line_);
254 256
255 pango_layout_get_log_attrs(layout_, &log_attrs_, &num_log_attrs_); 257 pango_layout_get_log_attrs(layout_, &log_attrs_, &num_log_attrs_);
256 258
257 layout_text_ = pango_layout_get_text(layout_); 259 layout_text_ = pango_layout_get_text(layout_);
258 layout_text_len_ = strlen(layout_text_); 260 layout_text_len_ = strlen(layout_text_);
259 } 261 }
260 } 262 }
261 263
262 void RenderTextLinux::DrawVisualText(Canvas* canvas) { 264 void RenderTextLinux::DrawVisualText(Canvas* canvas) {
263 Rect bounds(display_rect()); 265 DCHECK(layout_);
264 266
265 // Clip the canvas to the text display area. 267 Point offset(ToViewPoint(Point()));
266 SkCanvas* canvas_skia = canvas->GetSkCanvas(); 268 // TODO(msw): Establish a vertical baseline for strings of mixed font heights.
269 size_t height = default_style().font.GetHeight();
267 270
268 skia::ScopedPlatformPaint scoped_platform_paint(canvas_skia); 271 SkScalar x = SkIntToScalar(offset.x());
269 cairo_t* cr = scoped_platform_paint.GetPlatformSurface(); 272 SkScalar y = SkIntToScalar(offset.y());
270 cairo_save(cr); 273 // Center the text vertically in the display area.
271 cairo_rectangle(cr, bounds.x(), bounds.y(), bounds.width(), bounds.height()); 274 y += (display_rect().height() - height) / 2;
272 cairo_clip(cr); 275 // Offset by the font size to account for Skia expecting y to be the bottom.
276 y += default_style().font.GetFontSize();
xji 2011/12/05 23:47:09 The x/y initialization is the same for Win and Lin
Alexei Svitkine (slow) 2011/12/06 22:05:36 I've added a helper function for this.
273 277
274 int text_width, text_height; 278 std::vector<SkPoint> pos;
275 pango_layout_get_pixel_size(layout_, &text_width, &text_height); 279 std::vector<uint16> glyphs;
276 Point offset(ToViewPoint(Point()));
277 // Vertically centered.
278 int text_y = offset.y() + ((bounds.height() - text_height) / 2);
279 // TODO(xji): need to use SkCanvas->drawPosText() for gpu acceleration.
280 cairo_move_to(cr, offset.x(), text_y);
281 pango_cairo_show_layout(cr, layout_);
282 280
283 cairo_restore(cr); 281 internal::SkiaTextRenderer renderer(canvas);
282 renderer.Init();
283
xji 2011/12/05 23:47:09 you need to call ApplyCompositionAndSelectionStyle
Alexei Svitkine (slow) 2011/12/06 22:05:36 Done. On the Windows side, this needed to be done
284 for (GSList* it = current_line_->runs; it; it = it->next) {
285 PangoLayoutRun* run = reinterpret_cast<PangoLayoutRun*>(it->data);
286 size_t run_start = Utf8IndexToUtf16Index(run->item->offset);
287
288 // Find the initial style for this run.
289 StyleRanges::const_iterator style = style_ranges().begin();
290 StyleRanges::const_iterator next = style + 1;
291 while (next < style_ranges().end() && next->range.start() <= run_start)
msw 2011/12/06 18:40:56 This seems pretty inefficient, can we do better th
Alexei Svitkine (slow) 2011/12/06 19:10:12 I agree this is bad, I've added a TODO for now.
292 style = next++;
293
294 int glyph_count = run->glyphs->num_glyphs;
295 glyphs.resize(glyph_count);
296 pos.resize(glyph_count);
297
298 PangoFontDescription* native_font =
299 pango_font_describe(run->item->analysis.font);
300 renderer.SetFont(gfx::Font(native_font));
301 pango_font_description_free(native_font);
302
303 SkScalar glyph_x = x;
304 SkScalar start_x = x;
305 int start = 0;
306 for (int i = 0; i < glyph_count; ++i) {
307 const PangoGlyphInfo& glyph = run->glyphs->glyphs[i];
308 glyphs[i] = static_cast<uint16>(glyph.glyph);
xji 2011/12/05 23:47:09 will cast from uint32 to uint16 cause problem?
Alexei Svitkine (slow) 2011/12/06 19:10:12 See my other comment.
309 pos[i].set(glyph_x + PANGO_PIXELS(glyph.geometry.x_offset),
310 y + PANGO_PIXELS(glyph.geometry.y_offset));
311 glyph_x += PANGO_PIXELS(glyph.geometry.width);
312
313 // If this glyph is the last for the current style, draw the glyphs so far
xji 2011/12/05 23:47:09 this glyph is *beyond* the current style.
Alexei Svitkine (slow) 2011/12/06 19:10:12 You're right, I've fixed the comment.
314 // and advance the style iterator.
315 size_t glyph_char_index = run->glyphs->log_clusters[i];
316 if (run_start + glyph_char_index >= style->range.end()) {
xji 2011/12/05 23:47:09 glyph_char_index is *byte* index relative to run s
Alexei Svitkine (slow) 2011/12/06 19:10:12 Good catch! Rather than doing the conversion for e
317 renderer.SetForegroundColor(style->foreground);
318 renderer.DrawPosText(&pos[start], &glyphs[start], i - start);
319 if (style->strike || style->underline) {
320 renderer.DrawDecorations(start_x, y, glyph_x - start_x,
321 style->underline, style->strike);
322 }
323
324 ++style;
325 start = i;
326 start_x = glyph_x;
327 }
328 }
329
330 // Draw the remaining glyphs.
331 renderer.SetForegroundColor(style->foreground);
332 renderer.DrawPosText(&pos[start], &glyphs[start], glyph_count - start);
333 if (style->strike || style->underline) {
334 renderer.DrawDecorations(start_x, y, glyph_x - start_x,
335 style->underline, style->strike);
336 }
337
338 x = glyph_x;
xji 2011/12/05 23:47:09 Nice mechanism on drawing with styles. But seems t
Alexei Svitkine (slow) 2011/12/06 22:05:36 Good catch. I've updated the code to hopefully han
339 }
284 } 340 }
285 341
286 size_t RenderTextLinux::IndexOfAdjacentGrapheme(size_t index, bool next) { 342 size_t RenderTextLinux::IndexOfAdjacentGrapheme(size_t index, bool next) {
287 if (index > text().length()) 343 if (index > text().length())
288 return text().length(); 344 return text().length();
289 EnsureLayout(); 345 EnsureLayout();
290 return Utf16IndexOfAdjacentGrapheme(Utf16IndexToUtf8Index(index), next); 346 return Utf16IndexOfAdjacentGrapheme(Utf16IndexToUtf8Index(index), next);
291 } 347 }
292 348
293 GSList* RenderTextLinux::GetRunContainingPosition(size_t position) const { 349 GSList* RenderTextLinux::GetRunContainingPosition(size_t position) const {
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 } 741 }
686 742
687 void RenderTextLinux::GetSelectionBounds(std::vector<Rect>* bounds) { 743 void RenderTextLinux::GetSelectionBounds(std::vector<Rect>* bounds) {
688 if (selection_visual_bounds_.empty()) 744 if (selection_visual_bounds_.empty())
689 CalculateSubstringBounds(GetSelectionStart(), GetCursorPosition(), 745 CalculateSubstringBounds(GetSelectionStart(), GetCursorPosition(),
690 &selection_visual_bounds_); 746 &selection_visual_bounds_);
691 *bounds = selection_visual_bounds_; 747 *bounds = selection_visual_bounds_;
692 } 748 }
693 749
694 } // namespace gfx 750 } // namespace gfx
OLDNEW
« ui/gfx/render_text.cc ('K') | « ui/gfx/render_text.cc ('k') | ui/gfx/render_text_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698