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

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(GetVisualOrigin());
266 SkCanvas* canvas_skia = canvas->GetSkCanvas(); 268 SkScalar x = SkIntToScalar(offset.x());
269 SkScalar y = SkIntToScalar(offset.y());
267 270
268 skia::ScopedPlatformPaint scoped_platform_paint(canvas_skia);
269 cairo_t* cr = scoped_platform_paint.GetPlatformSurface();
270 cairo_save(cr);
271 cairo_rectangle(cr, bounds.x(), bounds.y(), bounds.width(), bounds.height());
272 cairo_clip(cr);
273 271
274 int text_width, text_height; 272 std::vector<SkPoint> pos;
275 pango_layout_get_pixel_size(layout_, &text_width, &text_height); 273 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 274
283 cairo_restore(cr); 275 StyleRanges styles(style_ranges());
276 ApplyCompositionAndSelectionStyles(&styles);
277
278 // Pre-calculate UTF16 indeces style ranges to UTF16 indices.
xji 2011/12/07 00:56:51 to *UTF8* indices.
Alexei Svitkine (slow) 2011/12/07 16:11:21 Done.
279 // TODO(asvitkine): Can we cache these?
280 std::vector<ui::Range> style_ranges_utf8;
281 style_ranges_utf8.reserve(styles.size());
282 size_t start_index = 0;
283 for (size_t i = 0; i < styles.size(); ++i) {
284 size_t end_index = Utf16IndexToUtf8Index(styles[i].range.end());
285 style_ranges_utf8.push_back(ui::Range(start_index, end_index));
286 start_index = end_index;
287 }
288
289 bool is_rtl = (GetTextDirection() == base::i18n::RIGHT_TO_LEFT);
xji 2011/12/07 00:56:51 this should be run's directionality, not text's.
Alexei Svitkine (slow) 2011/12/07 16:11:21 Done. I've also added a helper function IsRunLTR()
290 size_t style_increment = (is_rtl ? -1 : 1);
291
292 internal::SkiaTextRenderer renderer(canvas);
293 for (GSList* it = current_line_->runs; it; it = it->next) {
294 PangoLayoutRun* run = reinterpret_cast<PangoLayoutRun*>(it->data);
295 size_t run_start = run->item->offset;
296 size_t run_end = run_start + run->item->length;
297
298 // Find the initial style for this run.
299 // TODO(asvitkine): Can we avoid looping here, e.g. by caching this per run?
300 int style;
301 if (is_rtl) {
xji 2011/12/07 00:56:51 sorry for the confusion. I mean the style initiali
Alexei Svitkine (slow) 2011/12/07 16:11:21 That version of the code was structured in a way t
302 style = style_ranges_utf8.size() - 1;
303 int prev = style - 1;
304 while (prev >= 0 && style_ranges_utf8[prev].end() >= run_end)
305 style = prev--;
306 } else {
307 style = 0;
308 size_t next = style + 1;
309 while (next < styles.size() &&
310 style_ranges_utf8[next].start() <= run_start) {
311 style = next++;
312 }
313 }
314
315 int glyph_count = run->glyphs->num_glyphs;
316 glyphs.resize(glyph_count);
317 pos.resize(glyph_count);
318
319 PangoFontDescription* native_font =
320 pango_font_describe(run->item->analysis.font);
321 renderer.SetFont(gfx::Font(native_font));
322 pango_font_description_free(native_font);
323
324 SkScalar glyph_x = x;
325 SkScalar start_x = x;
326 int start = 0;
327 for (int i = 0; i < glyph_count; ++i) {
328 const PangoGlyphInfo& glyph = run->glyphs->glyphs[i];
329 glyphs[i] = static_cast<uint16>(glyph.glyph);
330 pos[i].set(glyph_x + PANGO_PIXELS(glyph.geometry.x_offset),
331 y + PANGO_PIXELS(glyph.geometry.y_offset));
332 glyph_x += PANGO_PIXELS(glyph.geometry.width);
333
334 // If this glyph is beyond the current style, draw the glyphs so far and
335 // advance to the next style.
336 size_t glyph_byte_index = run_start + run->glyphs->log_clusters[i];
337 if (!style_ranges_utf8[style].Contains(ui::Range(glyph_byte_index))) {
xji 2011/12/07 00:56:51 isn't style_range's end exclusive? Then Contains()
Alexei Svitkine (slow) 2011/12/07 16:11:21 You're right! Fixed.
338 renderer.SetForegroundColor(styles[style].foreground);
339 renderer.DrawPosText(&pos[start], &glyphs[start], i - start);
340 if (styles[style].underline || styles[style].strike) {
341 renderer.DrawDecorations(start_x, y, glyph_x - start_x,
342 styles[style].underline,
343 styles[style].strike);
344 }
345
346 style += style_increment;
347 start = i;
348 start_x = glyph_x;
349 }
350 }
351
352 // Draw the remaining glyphs.
353 renderer.SetForegroundColor(styles[style].foreground);
354 renderer.DrawPosText(&pos[start], &glyphs[start], glyph_count - start);
355 if (styles[style].underline || styles[style].strike) {
356 renderer.DrawDecorations(start_x, y, glyph_x - start_x,
357 styles[style].underline,
358 styles[style].strike);
359 }
360
361 x = glyph_x;
362 }
284 } 363 }
285 364
286 size_t RenderTextLinux::IndexOfAdjacentGrapheme(size_t index, bool next) { 365 size_t RenderTextLinux::IndexOfAdjacentGrapheme(size_t index, bool next) {
287 EnsureLayout(); 366 EnsureLayout();
288 return Utf16IndexOfAdjacentGrapheme(Utf16IndexToUtf8Index(index), next); 367 return Utf16IndexOfAdjacentGrapheme(Utf16IndexToUtf8Index(index), next);
289 } 368 }
290 369
291 GSList* RenderTextLinux::GetRunContainingPosition(size_t position) const { 370 GSList* RenderTextLinux::GetRunContainingPosition(size_t position) const {
292 GSList* run = current_line_->runs; 371 GSList* run = current_line_->runs;
293 while (run) { 372 while (run) {
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 } 762 }
684 763
685 void RenderTextLinux::GetSelectionBounds(std::vector<Rect>* bounds) { 764 void RenderTextLinux::GetSelectionBounds(std::vector<Rect>* bounds) {
686 if (selection_visual_bounds_.empty()) 765 if (selection_visual_bounds_.empty())
687 CalculateSubstringBounds(GetSelectionStart(), GetCursorPosition(), 766 CalculateSubstringBounds(GetSelectionStart(), GetCursorPosition(),
688 &selection_visual_bounds_); 767 &selection_visual_bounds_);
689 *bounds = selection_visual_bounds_; 768 *bounds = selection_visual_bounds_;
690 } 769 }
691 770
692 } // namespace gfx 771 } // 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