15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/pango_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cairo/cairo.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pango/pango.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pango/pangocairo.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/font_list.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/font_render_params.h" 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gfx/linux_font_delegate.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/platform_font_pango.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/text_utils.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Marker for accelerators in the text. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gunichar kAcceleratorChar = '&'; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Creates and returns a PangoContext. The caller owns the context. 32116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPangoContext* GetPangoContext() { 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PangoFontMap* font_map = pango_cairo_font_map_get_default(); 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return pango_font_map_create_context(font_map); 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Creates a new cairo_font_options_t based on |params|. 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdochcairo_font_options_t* CreateCairoFontOptions(const FontRenderParams& params) { 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cairo_font_options_t* cairo_font_options = cairo_font_options_create(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FontRenderParams::SubpixelRendering subpixel = params.subpixel_rendering; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!params.antialiasing) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_font_options_set_antialias(cairo_font_options, CAIRO_ANTIALIAS_NONE); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (subpixel == FontRenderParams::SUBPIXEL_RENDERING_NONE) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_font_options_set_antialias(cairo_font_options, CAIRO_ANTIALIAS_GRAY); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_font_options_set_antialias(cairo_font_options, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CAIRO_ANTIALIAS_SUBPIXEL); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_subpixel_order_t cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (subpixel == FontRenderParams::SUBPIXEL_RENDERING_RGB) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (subpixel == FontRenderParams::SUBPIXEL_RENDERING_BGR) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (subpixel == FontRenderParams::SUBPIXEL_RENDERING_VRGB) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (subpixel == FontRenderParams::SUBPIXEL_RENDERING_VBGR) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unhandled subpixel rendering type " << subpixel; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_font_options_set_subpixel_order(cairo_font_options, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_subpixel_order); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params.hinting == FontRenderParams::HINTING_NONE || 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.subpixel_positioning) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_font_options_set_hint_style(cairo_font_options, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CAIRO_HINT_STYLE_NONE); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_font_options_set_hint_metrics(cairo_font_options, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CAIRO_HINT_METRICS_OFF); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_hint_style_t cairo_hint_style = CAIRO_HINT_STYLE_DEFAULT; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params.hinting == FontRenderParams::HINTING_SLIGHT) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_hint_style = CAIRO_HINT_STYLE_SLIGHT; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (params.hinting == FontRenderParams::HINTING_MEDIUM) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_hint_style = CAIRO_HINT_STYLE_MEDIUM; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (params.hinting == FontRenderParams::HINTING_FULL) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_hint_style = CAIRO_HINT_STYLE_FULL; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unhandled hinting style " << params.hinting; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_font_options_set_hint_style(cairo_font_options, cairo_hint_style); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_font_options_set_hint_metrics(cairo_font_options, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CAIRO_HINT_METRICS_ON); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cairo_font_options; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Returns the DPI that should be used by Pango. 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)double GetPangoDPI() { 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static double dpi = -1.0; 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (dpi < 0.0) { 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const gfx::LinuxFontDelegate* delegate = gfx::LinuxFontDelegate::instance(); 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (delegate) 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dpi = delegate->GetFontDPI(); 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (dpi <= 0.0) 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dpi = 96.0; 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return dpi; 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the number of pixels in a point. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - multiply a point size by this to get pixels ("device units") 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - divide a pixel size by this to get points 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)double GetPixelsInPoint() { 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static double pixels_in_point = GetPangoDPI() / 72.0; // 72 points in an inch 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pixels_in_point; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SetUpPangoLayout( 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PangoLayout* layout, 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16& text, 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const FontList& font_list, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::i18n::TextDirection text_direction, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags) { 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cairo_font_options_t* cairo_font_options = CreateCairoFontOptions( 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch font_list.GetPrimaryFont().GetFontRenderParams()); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If we got an explicit request to turn off subpixel rendering, disable it. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((flags & Canvas::NO_SUBPIXEL_RENDERING) && 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cairo_font_options_get_antialias(cairo_font_options) == 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CAIRO_ANTIALIAS_SUBPIXEL)) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_font_options_set_antialias(cairo_font_options, CAIRO_ANTIALIAS_GRAY); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This needs to be done early on; it has no effect when called just before 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pango_cairo_show_layout(). 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_cairo_context_set_font_options( 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_get_context(layout), cairo_font_options); 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cairo_font_options_destroy(cairo_font_options); 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cairo_font_options = NULL; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set Pango's base text direction explicitly from |text_direction|. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_set_auto_dir(layout, FALSE); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_context_set_base_dir(pango_layout_get_context(layout), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (text_direction == base::i18n::RIGHT_TO_LEFT ? 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR)); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags & Canvas::TEXT_ALIGN_CENTER) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't support center aligned w/ eliding. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(gfx::Canvas::NO_ELLIPSIS); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (flags & Canvas::TEXT_ALIGN_RIGHT) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags & Canvas::NO_ELLIPSIS) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags & Canvas::MULTI_LINE) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_set_wrap(layout, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (flags & Canvas::CHARACTER_BREAK) ? 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PANGO_WRAP_WORD_CHAR : PANGO_WRAP_WORD); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (text_direction == base::i18n::RIGHT_TO_LEFT) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fading the text will be handled in the draw operation. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the text is only on one line. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_set_width(layout, -1); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Set the layout's resolution to match the resolution used to convert from 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // points to pixels. 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pango_cairo_context_set_resolution(pango_layout_get_context(layout), 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetPangoDPI()); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set text and accelerator character if needed. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags & Canvas::SHOW_PREFIX) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Escape the text string to be used as markup. 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string utf8 = base::UTF16ToUTF8(text); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gchar* escaped_text = g_markup_escape_text(utf8.c_str(), utf8.size()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_set_markup_with_accel(layout, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) escaped_text, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strlen(escaped_text), 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kAcceleratorChar, NULL); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_free(escaped_text); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string utf8; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the ampersand character. A double ampersand is output as 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a single ampersand. 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags & Canvas::HIDE_PREFIX) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(1, g_unichar_to_utf8(kAcceleratorChar, NULL)); 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 accelerator_removed = 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RemoveAcceleratorChar(text, 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static_cast<base::char16>(kAcceleratorChar), 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL); 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) utf8 = base::UTF16ToUTF8(accelerator_removed); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) utf8 = base::UTF16ToUTF8(text); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_set_text(layout, utf8.data(), utf8.size()); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedPangoFontDescription desc(pango_font_description_from_string( 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch font_list.GetFontDescriptionString().c_str())); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_layout_set_font_description(layout, desc.get()); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint GetPangoFontSizeInPixels(PangoFontDescription* pango_font) { 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If the size is absolute, then it's in Pango units rather than points. There 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // are PANGO_SCALE Pango units in a device unit (pixel). 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (pango_font_description_get_size_is_absolute(pango_font)) 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return pango_font_description_get_size(pango_font) / PANGO_SCALE; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Otherwise, we need to convert from points. 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return static_cast<int>(GetPixelsInPoint() * 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pango_font_description_get_size(pango_font) / PANGO_SCALE + 0.5); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PangoFontMetrics* GetPangoFontMetrics(PangoFontDescription* desc) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static std::map<int, PangoFontMetrics*>* desc_to_metrics = NULL; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static PangoContext* context = NULL; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!context) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context = GetPangoContext(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pango_context_set_language(context, pango_language_get_default()); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!desc_to_metrics) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desc_to_metrics = new std::map<int, PangoFontMetrics*>(); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int desc_hash = pango_font_description_hash(desc); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, PangoFontMetrics*>::iterator i = 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desc_to_metrics->find(desc_hash); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == desc_to_metrics->end()) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PangoFontMetrics* metrics = pango_context_get_metrics(context, desc, NULL); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desc_to_metrics->insert(std::make_pair(desc_hash, metrics)); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metrics; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i->second; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 238