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

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
« no previous file with comments | « ui/gfx/render_text.cc ('k') | ui/gfx/render_text_win.cc » ('j') | no next file with comments »
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/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();
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
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)
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);
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
314 // and advance the style iterator.
315 if (run_start + i >= style->range.end()) {
Alexei Svitkine (slow) 2011/12/02 16:19:59 There was an error here where the logic was using
316 renderer.SetForegroundColor(style->foreground);
317 renderer.DrawPosText(&pos[start], &glyphs[start], i - start);
318 if (style->strike || style->underline) {
319 renderer.DrawDecorations(start_x, y, glyph_x - start_x,
320 style->underline, style->strike);
321 }
322
323 ++style;
324 start = i;
325 start_x = glyph_x;
326 }
327 }
328
329 // Draw the remaining glyphs.
330 renderer.SetForegroundColor(style->foreground);
331 renderer.DrawPosText(&pos[start], &glyphs[start], glyph_count - start);
332 if (style->strike || style->underline) {
333 renderer.DrawDecorations(start_x, y, glyph_x - start_x,
334 style->underline, style->strike);
335 }
336
337 x = glyph_x;
338 }
284 } 339 }
285 340
286 size_t RenderTextLinux::IndexOfAdjacentGrapheme(size_t index, bool next) { 341 size_t RenderTextLinux::IndexOfAdjacentGrapheme(size_t index, bool next) {
287 EnsureLayout(); 342 EnsureLayout();
288 return Utf16IndexOfAdjacentGrapheme(Utf16IndexToUtf8Index(index), next); 343 return Utf16IndexOfAdjacentGrapheme(Utf16IndexToUtf8Index(index), next);
289 } 344 }
290 345
291 GSList* RenderTextLinux::GetRunContainingPosition(size_t position) const { 346 GSList* RenderTextLinux::GetRunContainingPosition(size_t position) const {
292 GSList* run = current_line_->runs; 347 GSList* run = current_line_->runs;
293 while (run) { 348 while (run) {
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 PangoAttribute* pango_attr; 612 PangoAttribute* pango_attr;
558 for (StyleRanges::const_iterator i = ranges_of_style.begin(); 613 for (StyleRanges::const_iterator i = ranges_of_style.begin();
559 i < ranges_of_style.end(); ++i) { 614 i < ranges_of_style.end(); ++i) {
560 size_t start = std::min(i->range.start(), text().length()); 615 size_t start = std::min(i->range.start(), text().length());
561 size_t end = std::min(i->range.end(), text().length()); 616 size_t end = std::min(i->range.end(), text().length());
562 if (start >= end) 617 if (start >= end)
563 continue; 618 continue;
564 619
565 const Font& font = i->font; 620 const Font& font = i->font;
566 // In Pango, different fonts means different runs, and it breaks Arabic 621 // In Pango, different fonts means different runs, and it breaks Arabic
567 // shaping acorss run boundaries. So, set font only when it is different 622 // shaping across run boundaries. So, set font only when it is different
568 // from the default faont. 623 // from the default font.
569 // TODO(xji): we'll eventually need to split up StyleRange into components 624 // TODO(xji): we'll eventually need to split up StyleRange into components
570 // (ColorRange, FontRange, etc.) so that we can combine adjacent ranges 625 // (ColorRange, FontRange, etc.) so that we can combine adjacent ranges
571 // with the same Fonts (to avoid unnecessarily splitting up runs) 626 // with the same Fonts (to avoid unnecessarily splitting up runs)
572 if (font.platform_font() != default_platform_font) { 627 if (font.platform_font() != default_platform_font) {
573 PangoFontDescription* desc = font.GetNativeFont(); 628 PangoFontDescription* desc = font.GetNativeFont();
574 pango_attr = pango_attr_font_desc_new(desc); 629 pango_attr = pango_attr_font_desc_new(desc);
575 AppendPangoAttribute(start, end, pango_attr, attrs); 630 AppendPangoAttribute(start, end, pango_attr, attrs);
576 pango_font_description_free(desc); 631 pango_font_description_free(desc);
577 } 632 }
578 633
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 } 738 }
684 739
685 void RenderTextLinux::GetSelectionBounds(std::vector<Rect>* bounds) { 740 void RenderTextLinux::GetSelectionBounds(std::vector<Rect>* bounds) {
686 if (selection_visual_bounds_.empty()) 741 if (selection_visual_bounds_.empty())
687 CalculateSubstringBounds(GetSelectionStart(), GetCursorPosition(), 742 CalculateSubstringBounds(GetSelectionStart(), GetCursorPosition(),
688 &selection_visual_bounds_); 743 &selection_visual_bounds_);
689 *bounds = selection_visual_bounds_; 744 *bounds = selection_visual_bounds_;
690 } 745 }
691 746
692 } // namespace gfx 747 } // namespace gfx
OLDNEW
« no previous file with comments | « 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