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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: ui/gfx/render_text_linux.cc
===================================================================
--- ui/gfx/render_text_linux.cc (revision 112983)
+++ ui/gfx/render_text_linux.cc (working copy)
@@ -6,10 +6,12 @@
#include <pango/pangocairo.h>
#include <algorithm>
+#include <vector>
#include "base/i18n/break_iterator.h"
#include "base/logging.h"
#include "ui/gfx/canvas_skia.h"
+#include "ui/gfx/font.h"
#include "ui/gfx/pango_util.h"
#include "unicode/uchar.h"
#include "unicode/ustring.h"
@@ -260,27 +262,81 @@
}
void RenderTextLinux::DrawVisualText(Canvas* canvas) {
- Rect bounds(display_rect());
+ DCHECK(layout_);
- // Clip the canvas to the text display area.
- SkCanvas* canvas_skia = canvas->GetSkCanvas();
+ Point offset(ToViewPoint(Point()));
+ // TODO(msw): Establish a vertical baseline for strings of mixed font heights.
+ size_t height = default_style().font.GetHeight();
- skia::ScopedPlatformPaint scoped_platform_paint(canvas_skia);
- cairo_t* cr = scoped_platform_paint.GetPlatformSurface();
- cairo_save(cr);
- cairo_rectangle(cr, bounds.x(), bounds.y(), bounds.width(), bounds.height());
- cairo_clip(cr);
+ SkScalar x = SkIntToScalar(offset.x());
+ SkScalar y = SkIntToScalar(offset.y());
+ // Center the text vertically in the display area.
+ y += (display_rect().height() - height) / 2;
+ // Offset by the font size to account for Skia expecting y to be the bottom.
+ 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.
- int text_width, text_height;
- pango_layout_get_pixel_size(layout_, &text_width, &text_height);
- Point offset(ToViewPoint(Point()));
- // Vertically centered.
- int text_y = offset.y() + ((bounds.height() - text_height) / 2);
- // TODO(xji): need to use SkCanvas->drawPosText() for gpu acceleration.
- cairo_move_to(cr, offset.x(), text_y);
- pango_cairo_show_layout(cr, layout_);
+ std::vector<SkPoint> pos;
+ std::vector<uint16> glyphs;
- cairo_restore(cr);
+ internal::SkiaTextRenderer renderer(canvas);
+ renderer.Init();
+
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
+ for (GSList* it = current_line_->runs; it; it = it->next) {
+ PangoLayoutRun* run = reinterpret_cast<PangoLayoutRun*>(it->data);
+ size_t run_start = Utf8IndexToUtf16Index(run->item->offset);
+
+ // Find the initial style for this run.
+ StyleRanges::const_iterator style = style_ranges().begin();
+ StyleRanges::const_iterator next = style + 1;
+ 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.
+ style = next++;
+
+ int glyph_count = run->glyphs->num_glyphs;
+ glyphs.resize(glyph_count);
+ pos.resize(glyph_count);
+
+ PangoFontDescription* native_font =
+ pango_font_describe(run->item->analysis.font);
+ renderer.SetFont(gfx::Font(native_font));
+ pango_font_description_free(native_font);
+
+ SkScalar glyph_x = x;
+ SkScalar start_x = x;
+ int start = 0;
+ for (int i = 0; i < glyph_count; ++i) {
+ const PangoGlyphInfo& glyph = run->glyphs->glyphs[i];
+ 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.
+ pos[i].set(glyph_x + PANGO_PIXELS(glyph.geometry.x_offset),
+ y + PANGO_PIXELS(glyph.geometry.y_offset));
+ glyph_x += PANGO_PIXELS(glyph.geometry.width);
+
+ // 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.
+ // and advance the style iterator.
+ size_t glyph_char_index = run->glyphs->log_clusters[i];
+ 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
+ renderer.SetForegroundColor(style->foreground);
+ renderer.DrawPosText(&pos[start], &glyphs[start], i - start);
+ if (style->strike || style->underline) {
+ renderer.DrawDecorations(start_x, y, glyph_x - start_x,
+ style->underline, style->strike);
+ }
+
+ ++style;
+ start = i;
+ start_x = glyph_x;
+ }
+ }
+
+ // Draw the remaining glyphs.
+ renderer.SetForegroundColor(style->foreground);
+ renderer.DrawPosText(&pos[start], &glyphs[start], glyph_count - start);
+ if (style->strike || style->underline) {
+ renderer.DrawDecorations(start_x, y, glyph_x - start_x,
+ style->underline, style->strike);
+ }
+
+ 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
+ }
}
size_t RenderTextLinux::IndexOfAdjacentGrapheme(size_t index, bool next) {
« 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