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)
558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "content/child/browser_font_resource_trusted.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/common/web_preferences.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppb_font_dev.h"
1158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "ppapi/proxy/connection.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_preferences.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/enter.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/ppb_image_data_api.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/thunk.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_canvas.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebCanvas.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebFloatPoint.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebFloatRect.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebRect.h"
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFont.h"
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFontDescription.h"
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebTextRun.h"
25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/common/unicode/ubidi.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkRect.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::StringVar;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::thunk::EnterResourceNoLock;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::thunk::PPB_ImageData_API;
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFloatPoint;
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFloatRect;
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFont;
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFontDescription;
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebRect;
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebTextRun;
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebCanvas;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace content {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as WebPreferences::kCommonScript. I'd use that directly here, but get an
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// undefined reference linker error.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kCommonScript[] = "Zyyy";
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::string16 GetFontFromMap(const ScriptFontFamilyMap& map,
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              const std::string& script) {
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScriptFontFamilyMap::const_iterator it = map.find(script);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != map.end())
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return it->second;
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return base::string16();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Splits a PP_BrowserFont_Trusted_TextRun into a sequence or LTR and RTL
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebTextRuns that can be used for WebKit. Normally WebKit does this for us,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but the font drawing and measurement routines we call happen after this
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// step. So for correct rendering of RTL content, we need to do it ourselves.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TextRunCollection {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TextRunCollection(const PP_BrowserFont_Trusted_TextRun& run)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : bidi_(NULL),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        num_runs_(0) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StringVar* text_string = StringVar::FromPPVar(run.text);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!text_string)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;  // Leave num_runs_ = 0 so we'll do nothing.
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    text_ = base::UTF8ToUTF16(text_string->value());
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (run.override_direction) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Skip autodetection.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_runs_ = 1;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      override_run_ = WebTextRun(text_, PP_ToBool(run.rtl), true);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bidi_ = ubidi_open();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UErrorCode uerror = U_ZERO_ERROR;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ubidi_setPara(bidi_, text_.data(), text_.size(), run.rtl, NULL, &uerror);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (U_SUCCESS(uerror))
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        num_runs_ = ubidi_countRuns(bidi_, &uerror);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TextRunCollection() {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bidi_)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ubidi_close(bidi_);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::string16& text() const { return text_; }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_runs() const { return num_runs_; }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a WebTextRun with the info for the run at the given index.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The range covered by the run is in the two output params.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebTextRun GetRunAt(int index, int32_t* run_start, int32_t* run_len) const {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(index < num_runs_);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bidi_) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool run_rtl = !!ubidi_getVisualRun(bidi_, index, run_start, run_len);
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return WebTextRun(base::string16(&text_[*run_start], *run_len),
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        run_rtl, true);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Override run, return the single one.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(index == 0);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *run_start = 0;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *run_len = static_cast<int32_t>(text_.size());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return override_run_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Will be null if we skipped autodetection.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UBiDi* bidi_;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Text of all the runs.
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 text_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_runs_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the content specifies override_direction (bidi_ is null) then this
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will contain the single text run for WebKit.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebTextRun override_run_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TextRunCollection);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPTextRunToWebTextRun(const PP_BrowserFont_Trusted_TextRun& text,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           WebTextRun* run) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringVar* text_string = StringVar::FromPPVar(text.text);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!text_string)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *run = WebTextRun(base::UTF8ToUTF16(text_string->value()),
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PP_ToBool(text.rtl),
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PP_ToBool(text.override_direction));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The PP_* version lacks "None", so is just one value shifted from the
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebFontDescription version. These values are checked in
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPFontDescToWebFontDesc to make sure the conversion is correct. This is a
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// macro so it can also be used in the COMPILE_ASSERTS.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PP_FAMILY_TO_WEB_FAMILY(f) \
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_cast<WebFontDescription::GenericFamily>(f + 1)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assumes the given PP_FontDescription has been validated.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebFontDescription PPFontDescToWebFontDesc(
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_BrowserFont_Trusted_Description& font,
14558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    const ppapi::Preferences& prefs) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the enums match so we can just static cast.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight100) ==
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 static_cast<int>(PP_BROWSERFONT_TRUSTED_WEIGHT_100),
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FontWeight100);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight900) ==
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 static_cast<int>(PP_BROWSERFONT_TRUSTED_WEIGHT_900),
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FontWeight900);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(WebFontDescription::GenericFamilyStandard ==
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_DEFAULT),
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 StandardFamily);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(WebFontDescription::GenericFamilySerif ==
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_SERIF),
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 SerifFamily);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(WebFontDescription::GenericFamilySansSerif ==
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_SANSSERIF),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 SansSerifFamily);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(WebFontDescription::GenericFamilyMonospace ==
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_MONOSPACE),
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 MonospaceFamily);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringVar* face_name = StringVar::FromPPVar(font.face);  // Possibly null.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebFontDescription result;
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 resolved_family;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!face_name || face_name->value().empty()) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resolve the generic family.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (font.family) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case PP_BROWSERFONT_TRUSTED_FAMILY_SERIF:
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        resolved_family = GetFontFromMap(prefs.serif_font_family_map,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         kCommonScript);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case PP_BROWSERFONT_TRUSTED_FAMILY_SANSSERIF:
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        resolved_family = GetFontFromMap(prefs.sans_serif_font_family_map,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         kCommonScript);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE:
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        resolved_family = GetFontFromMap(prefs.fixed_font_family_map,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         kCommonScript);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT:
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        resolved_family = GetFontFromMap(prefs.standard_font_family_map,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         kCommonScript);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use the exact font.
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resolved_family = base::UTF8ToUTF16(face_name->value());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.family = resolved_family;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.genericFamily = PP_FAMILY_TO_WEB_FAMILY(font.family);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (font.size == 0) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resolve the default font size, using the resolved family to see if
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we should use the fixed or regular font size. It's difficult at this
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // level to detect if the requested font is fixed width, so we only apply
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the alternate font size to the default fixed font family.
2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (base::StringToLowerASCII(resolved_family) ==
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        base::StringToLowerASCII(GetFontFromMap(prefs.fixed_font_family_map,
2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                                kCommonScript)))
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result.size = static_cast<float>(prefs.default_fixed_font_size);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result.size = static_cast<float>(prefs.default_font_size);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use the exact size.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.size = static_cast<float>(font.size);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.italic = font.italic != PP_FALSE;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.smallCaps = font.small_caps != PP_FALSE;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.weight = static_cast<WebFontDescription::Weight>(font.weight);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.letterSpacing = static_cast<short>(font.letter_spacing);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.wordSpacing = static_cast<short>(font.word_spacing);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserFontResource_Trusted::IsPPFontDescriptionValid(
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_BrowserFont_Trusted_Description& desc) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check validity of string. We can't check the actual text since we could
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be on the wrong thread and don't know if we're in the plugin or the host.
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (desc.face.type != PP_VARTYPE_STRING &&
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      desc.face.type != PP_VARTYPE_UNDEFINED)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check enum ranges.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (static_cast<int>(desc.family) < PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT ||
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<int>(desc.family) > PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (static_cast<int>(desc.weight) < PP_BROWSERFONT_TRUSTED_WEIGHT_100 ||
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<int>(desc.weight) > PP_BROWSERFONT_TRUSTED_WEIGHT_900)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check for excessive sizes which may cause layout to get confused.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (desc.size > 200)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BrowserFontResource_Trusted::BrowserFontResource_Trusted(
25058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    ppapi::proxy::Connection connection,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Instance instance,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_BrowserFont_Trusted_Description& desc,
25358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    const ppapi::Preferences& prefs)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : PluginResource(connection, instance),
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      font_(WebFont::create(PPFontDescToWebFontDesc(desc, prefs))) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BrowserFontResource_Trusted::~BrowserFontResource_Trusted() {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochppapi::thunk::PPB_BrowserFont_Trusted_API*
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BrowserFontResource_Trusted::AsPPB_BrowserFont_Trusted_API() {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PP_Bool BrowserFontResource_Trusted::Describe(
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_BrowserFont_Trusted_Description* description,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_BrowserFont_Trusted_Metrics* metrics) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (description->face.type != PP_VARTYPE_UNDEFINED)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_FALSE;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // While converting the other way in PPFontDescToWebFontDesc we validated
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that the enums can be casted.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebFontDescription web_desc = font_->fontDescription();
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  description->face =
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      StringVar::StringToPPVar(base::UTF16ToUTF8(web_desc.family));
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  description->family =
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<PP_BrowserFont_Trusted_Family>(web_desc.genericFamily);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  description->size = static_cast<uint32_t>(web_desc.size);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  description->weight = static_cast<PP_BrowserFont_Trusted_Weight>(
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_desc.weight);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  description->italic = web_desc.italic ? PP_TRUE : PP_FALSE;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  description->small_caps = web_desc.smallCaps ? PP_TRUE : PP_FALSE;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  description->letter_spacing = static_cast<int32_t>(web_desc.letterSpacing);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  description->word_spacing = static_cast<int32_t>(web_desc.wordSpacing);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metrics->height = font_->height();
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metrics->ascent = font_->ascent();
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metrics->descent = font_->descent();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metrics->line_spacing = font_->lineSpacing();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metrics->x_height = static_cast<int32_t>(font_->xHeight());
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert the string.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_TRUE;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PP_Bool BrowserFontResource_Trusted::DrawTextAt(
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Resource image_data,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_BrowserFont_Trusted_TextRun* text,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_Point* position,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t color,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_Rect* clip,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Bool image_data_is_opaque) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Bool result = PP_FALSE;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get and map the image data we're painting to.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnterResourceNoLock<PPB_ImageData_API> enter(image_data, true);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter.failed())
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PPB_ImageData_API* image = static_cast<PPB_ImageData_API*>(
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      enter.object());
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkCanvas* canvas = image->GetPlatformCanvas();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool needs_unmapping = false;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!canvas) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    needs_unmapping = true;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    image->Map();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas = image->GetPlatformCanvas();
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!canvas)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return result;  // Failure mapping.
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawTextToCanvas(canvas, *text, position, color, clip, image_data_is_opaque);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (needs_unmapping)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    image->Unmap();
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_TRUE;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t BrowserFontResource_Trusted::MeasureText(
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_BrowserFont_Trusted_TextRun* text) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebTextRun run;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!PPTextRunToWebTextRun(*text, &run))
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return font_->calculateWidth(run);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)uint32_t BrowserFontResource_Trusted::CharacterOffsetForPixel(
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_BrowserFont_Trusted_TextRun* text,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t pixel_position) {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextRunCollection runs(*text);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t cur_pixel_offset = 0;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < runs.num_runs(); i++) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t run_begin = 0;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t run_len = 0;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebTextRun run = runs.GetRunAt(i, &run_begin, &run_len);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int run_width = font_->calculateWidth(run);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pixel_position < cur_pixel_offset + run_width) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Offset is in this run.
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return static_cast<uint32_t>(font_->offsetForPosition(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              run, static_cast<float>(pixel_position - cur_pixel_offset))) +
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          run_begin;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur_pixel_offset += run_width;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return runs.text().size();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t BrowserFontResource_Trusted::PixelOffsetForCharacter(
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_BrowserFont_Trusted_TextRun* text,
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t char_offset) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextRunCollection runs(*text);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t cur_pixel_offset = 0;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < runs.num_runs(); i++) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t run_begin = 0;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t run_len = 0;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebTextRun run = runs.GetRunAt(i, &run_begin, &run_len);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (char_offset >= static_cast<uint32_t>(run_begin) &&
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        char_offset < static_cast<uint32_t>(run_begin + run_len)) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Character we're looking for is in this run.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      //
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Here we ask WebKit to give us the rectangle around the character in
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // question, and then return the left edge. If we asked for a range of
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // 0 characters starting at the character in question, it would give us
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // a 0-width rect around the insertion point. But that will be on the
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // right side of the character for an RTL run, which would be wrong.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebFloatRect rect = font_->selectionRectForText(
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          run, WebFloatPoint(0.0f, 0.0f), font_->height(),
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          char_offset - run_begin, char_offset - run_begin + 1);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return cur_pixel_offset + static_cast<int>(rect.x);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Character is past this run, account for the pixels and continue
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // looking.
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cur_pixel_offset += font_->calculateWidth(run);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return -1;  // Requested a char beyond the end.
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BrowserFontResource_Trusted::DrawTextToCanvas(
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkCanvas* destination,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_BrowserFont_Trusted_TextRun& text,
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_Point* position,
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t color,
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_Rect* clip,
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Bool image_data_is_opaque) {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert position and clip.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebFloatPoint web_position(static_cast<float>(position->x),
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             static_cast<float>(position->y));
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebRect web_clip;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!clip) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use entire canvas. SkCanvas doesn't have a size on it, so we just use
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the current clip bounds.
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkRect skclip;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    destination->getClipBounds(&skclip);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_clip = WebRect(skclip.fLeft, skclip.fTop, skclip.fRight - skclip.fLeft,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       skclip.fBottom - skclip.fTop);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_clip = WebRect(clip->point.x, clip->point.y,
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       clip->size.width, clip->size.height);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextRunCollection runs(text);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < runs.num_runs(); i++) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t run_begin = 0;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t run_len = 0;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebTextRun run = runs.GetRunAt(i, &run_begin, &run_len);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    font_->drawText(destination, run, web_position, color, web_clip,
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PP_ToBool(image_data_is_opaque));
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Advance to the next run. Note that we avoid doing this for the last run
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // since it's unnecessary, measuring text is slow, and most of the time
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // there will be only one run anyway.
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i != runs.num_runs() - 1)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_position.x += font_->calculateWidth(run);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}  // namespace content
429