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

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 const StyleRanges& styles = style_ranges();
282
283 // Pre-calculate UTF16 indeces style ranges to UTF16 indices.
284 // TODO(asvitkine): Can we cache these?
285 std::vector<ui::Range> style_ranges_utf8;
286 style_ranges_utf8.reserve(styles.size());
287 size_t start_index = 0;
288 for (size_t i = 0; i < styles.size(); ++i) {
289 size_t end_index = Utf16IndexToUtf8Index(styles[i].range.end());
290 style_ranges_utf8.push_back(ui::Range(start_index, end_index));
291 start_index = end_index;
292 }
293
294 internal::SkiaTextRenderer renderer(canvas);
295 for (GSList* it = current_line_->runs; it; it = it->next) {
296 PangoLayoutRun* run = reinterpret_cast<PangoLayoutRun*>(it->data);
297 size_t run_start = run->item->offset;
298
299 // Find the initial style for this run.
300 // TODO(asvitkine): Can avoid this loop, e.g. by caching this per run?
301 size_t style = 0;
302 size_t next = style + 1;
303 while (next < styles.size() && style_ranges_utf8[next].start() <= run_start)
304 style = next++;
305
306 int glyph_count = run->glyphs->num_glyphs;
307 glyphs.resize(glyph_count);
308 pos.resize(glyph_count);
309
310 PangoFontDescription* native_font =
311 pango_font_describe(run->item->analysis.font);
312 renderer.SetFont(gfx::Font(native_font));
behdad_google 2011/12/06 19:23:13 Do we know how to create a Skia font from a FT_Fac
313 pango_font_description_free(native_font);
314
315 SkScalar glyph_x = x;
316 SkScalar start_x = x;
317 int start = 0;
318 for (int i = 0; i < glyph_count; ++i) {
319 const PangoGlyphInfo& glyph = run->glyphs->glyphs[i];
320 glyphs[i] = static_cast<uint16>(glyph.glyph);
321 pos[i].set(glyph_x + PANGO_PIXELS(glyph.geometry.x_offset),
322 y + PANGO_PIXELS(glyph.geometry.y_offset));
323 glyph_x += PANGO_PIXELS(glyph.geometry.width);
324
325 // If this glyph is beyond the current style, draw the glyphs so far and
326 // advance to the next style.
327 size_t glyph_byte_index = run->glyphs->log_clusters[i];
328 if (run_start + glyph_byte_index >= style_ranges_utf8[style].end()) {
329 renderer.SetForegroundColor(styles[style].foreground);
330 renderer.DrawPosText(&pos[start], &glyphs[start], i - start);
331 if (styles[style].underline || styles[style].strike) {
332 renderer.DrawDecorations(start_x, y, glyph_x - start_x,
333 styles[style].underline,
334 styles[style].strike);
335 }
336
337 ++style;
338 start = i;
339 start_x = glyph_x;
340 }
341 }
342
343 // Draw the remaining glyphs.
344 renderer.SetForegroundColor(styles[style].foreground);
345 renderer.DrawPosText(&pos[start], &glyphs[start], glyph_count - start);
346 if (styles[style].underline || styles[style].strike) {
347 renderer.DrawDecorations(start_x, y, glyph_x - start_x,
348 styles[style].underline,
349 styles[style].strike);
350 }
351
352 x = glyph_x;
353 }
284 } 354 }
285 355
286 size_t RenderTextLinux::IndexOfAdjacentGrapheme(size_t index, bool next) { 356 size_t RenderTextLinux::IndexOfAdjacentGrapheme(size_t index, bool next) {
287 EnsureLayout(); 357 EnsureLayout();
288 return Utf16IndexOfAdjacentGrapheme(Utf16IndexToUtf8Index(index), next); 358 return Utf16IndexOfAdjacentGrapheme(Utf16IndexToUtf8Index(index), next);
289 } 359 }
290 360
291 GSList* RenderTextLinux::GetRunContainingPosition(size_t position) const { 361 GSList* RenderTextLinux::GetRunContainingPosition(size_t position) const {
292 GSList* run = current_line_->runs; 362 GSList* run = current_line_->runs;
293 while (run) { 363 while (run) {
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 } 753 }
684 754
685 void RenderTextLinux::GetSelectionBounds(std::vector<Rect>* bounds) { 755 void RenderTextLinux::GetSelectionBounds(std::vector<Rect>* bounds) {
686 if (selection_visual_bounds_.empty()) 756 if (selection_visual_bounds_.empty())
687 CalculateSubstringBounds(GetSelectionStart(), GetCursorPosition(), 757 CalculateSubstringBounds(GetSelectionStart(), GetCursorPosition(),
688 &selection_visual_bounds_); 758 &selection_visual_bounds_);
689 *bounds = selection_visual_bounds_; 759 *bounds = selection_visual_bounds_;
690 } 760 }
691 761
692 } // namespace gfx 762 } // 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