Index: ui/gfx/render_text_linux.cc |
=================================================================== |
--- ui/gfx/render_text_linux.cc (revision 112492) |
+++ 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,80 @@ |
} |
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(); |
- 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(); |
+ |
+ 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) |
+ 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); |
+ 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 |
+ // and advance the style iterator. |
+ 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
|
+ 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; |
+ } |
} |
size_t RenderTextLinux::IndexOfAdjacentGrapheme(size_t index, bool next) { |
@@ -564,8 +619,8 @@ |
const Font& font = i->font; |
// In Pango, different fonts means different runs, and it breaks Arabic |
- // shaping acorss run boundaries. So, set font only when it is different |
- // from the default faont. |
+ // shaping across run boundaries. So, set font only when it is different |
+ // from the default font. |
// TODO(xji): we'll eventually need to split up StyleRange into components |
// (ColorRange, FontRange, etc.) so that we can combine adjacent ranges |
// with the same Fonts (to avoid unnecessarily splitting up runs) |