diff options
author | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-19 17:15:22 +0000 |
---|---|---|
committer | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-19 17:15:22 +0000 |
commit | 5275c3dbc87f48da96a2880c2ac12e956c18784c (patch) | |
tree | 1c1a15bba4f850e55fcc444ba5f53a488082a97d /app | |
parent | c6f26b5d3fb527d4731b08553fd2ba8272df550f (diff) | |
download | chromium_src-5275c3dbc87f48da96a2880c2ac12e956c18784c.zip chromium_src-5275c3dbc87f48da96a2880c2ac12e956c18784c.tar.gz chromium_src-5275c3dbc87f48da96a2880c2ac12e956c18784c.tar.bz2 |
Do work necessary to make Views About panel work on Chrome OS. This is to be used for forcing Chrome OS updates.
There were many things that needed to be fixed for this to work.
Make skia's canvas return height of font for size of strings, instead of the actual height of the characters to bring it in line with Windows.
Make average character widths use pango metrics and windows dialog units. Make this lazy, to avoid most calls.
Fix bug in About panel that failed to adjust the embedded links to allow for the padding that Link adds so they can be focused.
Support gtk about panel in regular build, views in chrome os only.
Fix WindowGtk to call WindowClosing()
Fix canvas_linux::SetupPangoLayout() to wrap correctly, if passed a width
Fix Label::ComputeMultiLineFlags() to turn off eliding. With eliding the pango routines always return 1 line.
Enable focus manager in dialogs.
Version loader crashed in debug.
Review URL: http://codereview.chromium.org/282002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29414 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'app')
-rw-r--r-- | app/gfx/canvas_linux.cc | 30 | ||||
-rw-r--r-- | app/gfx/font.h | 5 | ||||
-rw-r--r-- | app/gfx/font_skia.cc | 43 |
3 files changed, 54 insertions, 24 deletions
diff --git a/app/gfx/canvas_linux.cc b/app/gfx/canvas_linux.cc index 7ed1904..fc4e10e3 100644 --- a/app/gfx/canvas_linux.cc +++ b/app/gfx/canvas_linux.cc @@ -98,8 +98,10 @@ Canvas::Canvas() : skia::PlatformCanvas() { Canvas::~Canvas() { } +// Pass a width > 0 to force wrapping and elliding. static void SetupPangoLayout(PangoLayout* layout, const gfx::Font& font, + int width, int flags) { if (!cairo_font_options) UpdateCairoFontOptions(); @@ -112,6 +114,9 @@ static void SetupPangoLayout(PangoLayout* layout, // scope out RTL characters. pango_layout_set_auto_dir(layout, FALSE); + if (width > 0) + pango_layout_set_width(layout, width * PANGO_SCALE); + if (flags & Canvas::NO_ELLIPSIS) { pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); } else { @@ -144,14 +149,16 @@ void Canvas::SizeStringInt(const std::wstring& text, cairo_t* cr = cairo_create(surface); PangoLayout* layout = pango_cairo_create_layout(cr); - SetupPangoLayout(layout, font, flags); + SetupPangoLayout(layout, font, *width, flags); std::string utf8 = WideToUTF8(text); pango_layout_set_text(layout, utf8.data(), utf8.size()); - pango_layout_get_size(layout, width, height); + int chars_height; + pango_layout_get_size(layout, width, &chars_height); *width /= PANGO_SCALE; - *height /= PANGO_SCALE; + // Pango returns the height of the characters, not the height of the font. + *height = font.height(); g_object_unref(layout); cairo_destroy(cr); @@ -160,14 +167,14 @@ void Canvas::SizeStringInt(const std::wstring& text, void Canvas::DrawStringInt(const std::wstring& text, const gfx::Font& font, - const SkColor& color, int x, int y, int w, int h, + const SkColor& color, + int x, int y, int w, int h, int flags) { cairo_t* cr = beginPlatformPaint(); PangoLayout* layout = pango_cairo_create_layout(cr); - SetupPangoLayout(layout, font, flags); + SetupPangoLayout(layout, font, w, flags); - pango_layout_set_width(layout, w * PANGO_SCALE); pango_layout_set_height(layout, h * PANGO_SCALE); cairo_save(cr); @@ -179,16 +186,19 @@ void Canvas::DrawStringInt(const std::wstring& text, std::string utf8 = WideToUTF8(text); pango_layout_set_text(layout, utf8.data(), utf8.size()); - int width, height; - pango_layout_get_size(layout, &width, &height); + int width, height, chars_height; + pango_layout_get_size(layout, &width, &chars_height); + width /= PANGO_SCALE; + // Pango returns the height of the characters, not the height of the font. + height = font.height(); if (flags & Canvas::TEXT_VALIGN_TOP) { // Cairo should draw from the top left corner already. } else if (flags & Canvas::TEXT_VALIGN_BOTTOM) { - y = y + (h - (height / PANGO_SCALE)); + y += (h - height); } else { // Vertically centered. - y = y + ((h - (height / PANGO_SCALE)) / 2); + y += ((h - height) / 2); } cairo_rectangle(cr, x, y, w, h); diff --git a/app/gfx/font.h b/app/gfx/font.h index e53bd79..bc8ee92 100644 --- a/app/gfx/font.h +++ b/app/gfx/font.h @@ -206,6 +206,9 @@ class Font { // The default font, used for the default constructor. static Font* default_font_; + // The average width of a character, initialized and cached if needed. + double avg_width(); + // These two both point to the same SkTypeface. We use the SkAutoUnref to // handle the reference counting, but without @typeface_ we would have to // cast the SkRefCnt from @typeface_helper_ every time. @@ -221,7 +224,7 @@ class Font { // Cached metrics, generated at construction int height_; int ascent_; - int avg_width_; + double avg_width_; #elif defined(OS_MACOSX) explicit Font(const std::wstring& font_name, int font_size, int style); diff --git a/app/gfx/font_skia.cc b/app/gfx/font_skia.cc index 41c29c6..70d6cf2 100644 --- a/app/gfx/font_skia.cc +++ b/app/gfx/font_skia.cc @@ -69,22 +69,14 @@ Font::Font(SkTypeface* tf, const std::wstring& font_family, int font_size, void Font::calculateMetrics() { SkPaint paint; SkPaint::FontMetrics metrics; - PaintSetup(&paint); paint.getFontMetrics(&metrics); ascent_ = SkScalarCeil(-metrics.fAscent); height_ = ascent_ + SkScalarCeil(metrics.fDescent); + // avg_width_ is calculated lazily, as it's expensive and not used often. + avg_width_ = -1.0; - if (metrics.fAvgCharWidth) { - avg_width_ = SkScalarRound(metrics.fAvgCharWidth); - } else { - static const char x_char = 'x'; - paint.setTextEncoding(SkPaint::kUTF8_TextEncoding); - SkScalar width = paint.measureText(&x_char, 1); - - avg_width_ = static_cast<int>(ceilf(SkScalarToFloat(width))); - } } void Font::CopyFont(const Font& other) { @@ -108,7 +100,7 @@ int Font::baseline() const { } int Font::ave_char_width() const { - return avg_width_; + return SkScalarRound(const_cast<Font*>(this)->avg_width()); } Font Font::CreateFont(const std::wstring& font_family, int font_size) { @@ -176,10 +168,35 @@ int Font::GetStringWidth(const std::wstring& text) const { return width; } -int Font::GetExpectedTextWidth(int length) const { - return length * avg_width_; +double Font::avg_width() { + if (avg_width_ < 0) { + // First get the pango based width + PangoFontDescription* pango_desc = gfx::Font::PangoFontFromGfxFont(*this); + PangoContext* context = + gdk_pango_context_get_for_screen(gdk_screen_get_default()); + PangoFontMetrics* pango_metrics = + pango_context_get_metrics(context, + pango_desc, + pango_language_get_default()); + double pango_width = + pango_font_metrics_get_approximate_char_width(pango_metrics); + pango_width /= PANGO_SCALE; + + // Yes, this is how Microsoft recommends calculating the dialog unit + // conversions. + int text_width = GetStringWidth( + L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + double dialog_units = (text_width / 26 + 1) / 2; + + avg_width_ = std::min(pango_width, dialog_units); + } + return avg_width_; } +int Font::GetExpectedTextWidth(int length) const { + double char_width = const_cast<Font*>(this)->avg_width(); + return round(static_cast<float>(length) * char_width); +} int Font::style() const { return style_; |