| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "webkit/plugins/ppapi/webkit_forwarding_impl.h" | |
| 6 | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/debug/trace_event.h" | |
| 10 #include "base/memory/scoped_ptr.h" | |
| 11 #include "base/string_util.h" | |
| 12 #include "base/synchronization/waitable_event.h" | |
| 13 #include "base/utf_string_conversions.h" | |
| 14 #include "ppapi/c/dev/ppb_font_dev.h" | |
| 15 #include "ppapi/c/pp_point.h" | |
| 16 #include "ppapi/c/pp_rect.h" | |
| 17 #include "ppapi/shared_impl/ppapi_preferences.h" | |
| 18 #include "skia/ext/platform_canvas.h" | |
| 19 #include "third_party/skia/include/core/SkRect.h" | |
| 20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCanvas.h" | |
| 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFont.h" | |
| 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFontDescription.h" | |
| 23 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" | |
| 24 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoin
t.h" | |
| 25 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatRect
.h" | |
| 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextRun.h" | |
| 27 #include "webkit/glue/webkit_glue.h" | |
| 28 | |
| 29 using ::ppapi::WebKitForwarding; | |
| 30 using WebKit::WebCanvas; | |
| 31 using WebKit::WebFloatPoint; | |
| 32 using WebKit::WebFloatRect; | |
| 33 using WebKit::WebFont; | |
| 34 using WebKit::WebFontDescription; | |
| 35 using WebKit::WebRect; | |
| 36 using WebKit::WebTextRun; | |
| 37 | |
| 38 namespace webkit { | |
| 39 namespace ppapi { | |
| 40 | |
| 41 namespace { | |
| 42 | |
| 43 // The PP_* version lacks "None", so is just one value shifted from the | |
| 44 // WebFontDescription version. These values are checked in | |
| 45 // PPFontDescToWebFontDesc to make sure the conversion is correct. This is a | |
| 46 // macro so it can also be used in the COMPILE_ASSERTS. | |
| 47 #define PP_FONTFAMILY_TO_WEB_FONTFAMILY(f) \ | |
| 48 static_cast<WebFontDescription::GenericFamily>(f + 1) | |
| 49 | |
| 50 // Assumes the given PP_FontDescription has been validated. | |
| 51 WebFontDescription PPFontDescToWebFontDesc(const PP_FontDescription_Dev& font, | |
| 52 const std::string& face, | |
| 53 const ::ppapi::Preferences& prefs) { | |
| 54 // Verify that the enums match so we can just static cast. | |
| 55 COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight100) == | |
| 56 static_cast<int>(PP_FONTWEIGHT_100), | |
| 57 FontWeight100); | |
| 58 COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight900) == | |
| 59 static_cast<int>(PP_FONTWEIGHT_900), | |
| 60 FontWeight900); | |
| 61 COMPILE_ASSERT(WebFontDescription::GenericFamilyStandard == | |
| 62 PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_DEFAULT), | |
| 63 StandardFamily); | |
| 64 COMPILE_ASSERT(WebFontDescription::GenericFamilySerif == | |
| 65 PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SERIF), | |
| 66 SerifFamily); | |
| 67 COMPILE_ASSERT(WebFontDescription::GenericFamilySansSerif == | |
| 68 PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SANSSERIF), | |
| 69 SansSerifFamily); | |
| 70 COMPILE_ASSERT(WebFontDescription::GenericFamilyMonospace == | |
| 71 PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_MONOSPACE), | |
| 72 MonospaceFamily); | |
| 73 | |
| 74 WebFontDescription result; | |
| 75 string16 resolved_family; | |
| 76 if (face.empty()) { | |
| 77 // Resolve the generic family. | |
| 78 switch (font.family) { | |
| 79 case PP_FONTFAMILY_SERIF: | |
| 80 resolved_family = prefs.serif_font_family; | |
| 81 break; | |
| 82 case PP_FONTFAMILY_SANSSERIF: | |
| 83 resolved_family = prefs.sans_serif_font_family; | |
| 84 break; | |
| 85 case PP_FONTFAMILY_MONOSPACE: | |
| 86 resolved_family = prefs.fixed_font_family; | |
| 87 break; | |
| 88 case PP_FONTFAMILY_DEFAULT: | |
| 89 default: | |
| 90 resolved_family = prefs.standard_font_family; | |
| 91 break; | |
| 92 } | |
| 93 } else { | |
| 94 // Use the exact font. | |
| 95 resolved_family = UTF8ToUTF16(face); | |
| 96 } | |
| 97 result.family = resolved_family; | |
| 98 | |
| 99 result.genericFamily = PP_FONTFAMILY_TO_WEB_FONTFAMILY(font.family); | |
| 100 | |
| 101 if (font.size == 0) { | |
| 102 // Resolve the default font size, using the resolved family to see if | |
| 103 // we should use the fixed or regular font size. It's difficult at this | |
| 104 // level to detect if the requested font is fixed width, so we only apply | |
| 105 // the alternate font size to the default fixed font family. | |
| 106 if (StringToLowerASCII(resolved_family) == | |
| 107 StringToLowerASCII(prefs.fixed_font_family)) | |
| 108 result.size = static_cast<float>(prefs.default_fixed_font_size); | |
| 109 else | |
| 110 result.size = static_cast<float>(prefs.default_font_size); | |
| 111 } else { | |
| 112 // Use the exact size. | |
| 113 result.size = static_cast<float>(font.size); | |
| 114 } | |
| 115 | |
| 116 result.italic = font.italic != PP_FALSE; | |
| 117 result.smallCaps = font.small_caps != PP_FALSE; | |
| 118 result.weight = static_cast<WebFontDescription::Weight>(font.weight); | |
| 119 result.letterSpacing = static_cast<short>(font.letter_spacing); | |
| 120 result.wordSpacing = static_cast<short>(font.word_spacing); | |
| 121 return result; | |
| 122 } | |
| 123 | |
| 124 WebTextRun TextRunToWebTextRun(const WebKitForwarding::Font::TextRun& run) { | |
| 125 return WebTextRun(UTF8ToUTF16(run.text), | |
| 126 run.rtl != PP_FALSE, | |
| 127 run.override_direction != PP_FALSE); | |
| 128 } | |
| 129 | |
| 130 // FontImpl -------------------------------------------------------------------- | |
| 131 | |
| 132 class FontImpl : public WebKitForwarding::Font { | |
| 133 public: | |
| 134 FontImpl(const PP_FontDescription_Dev& desc, | |
| 135 const std::string& desc_face, | |
| 136 const ::ppapi::Preferences& prefs); | |
| 137 virtual ~FontImpl(); | |
| 138 | |
| 139 virtual void Describe(base::WaitableEvent* event, | |
| 140 PP_FontDescription_Dev* description, | |
| 141 std::string* face, | |
| 142 PP_FontMetrics_Dev* metrics, | |
| 143 PP_Bool* result) OVERRIDE; | |
| 144 virtual void DrawTextAt(base::WaitableEvent* event, | |
| 145 const DrawTextParams& params) OVERRIDE; | |
| 146 virtual void MeasureText(base::WaitableEvent* event, | |
| 147 const TextRun& text, | |
| 148 int32_t* result) OVERRIDE; | |
| 149 virtual void CharacterOffsetForPixel(base::WaitableEvent* event, | |
| 150 const TextRun& text, | |
| 151 int32_t pixel_position, | |
| 152 uint32_t* result) OVERRIDE; | |
| 153 virtual void PixelOffsetForCharacter(base::WaitableEvent* event, | |
| 154 const TextRun& text, | |
| 155 uint32_t char_offset, | |
| 156 int32_t* result) OVERRIDE; | |
| 157 | |
| 158 private: | |
| 159 scoped_ptr<WebFont> font_; | |
| 160 | |
| 161 DISALLOW_COPY_AND_ASSIGN(FontImpl); | |
| 162 }; | |
| 163 | |
| 164 FontImpl::FontImpl(const PP_FontDescription_Dev& desc, | |
| 165 const std::string& desc_face, | |
| 166 const ::ppapi::Preferences& prefs) { | |
| 167 WebFontDescription web_font_desc = PPFontDescToWebFontDesc(desc, desc_face, | |
| 168 prefs); | |
| 169 font_.reset(WebFont::create(web_font_desc)); | |
| 170 } | |
| 171 | |
| 172 FontImpl::~FontImpl() { | |
| 173 } | |
| 174 | |
| 175 void FontImpl::Describe(base::WaitableEvent* event, | |
| 176 PP_FontDescription_Dev* description, | |
| 177 std::string* face, | |
| 178 PP_FontMetrics_Dev* metrics, | |
| 179 PP_Bool* result) { | |
| 180 TRACE_EVENT0("ppapi WebKit thread", "FontImpl::Describe"); | |
| 181 if (description->face.type != PP_VARTYPE_UNDEFINED) { | |
| 182 *result = PP_FALSE; | |
| 183 } else { | |
| 184 WebFontDescription web_desc = font_->fontDescription(); | |
| 185 | |
| 186 // While converting the other way in PPFontDescToWebFontDesc we validated | |
| 187 // that the enums can be casted. | |
| 188 description->face = PP_MakeUndefined(); | |
| 189 description->family = | |
| 190 static_cast<PP_FontFamily_Dev>(web_desc.genericFamily); | |
| 191 description->size = static_cast<uint32_t>(web_desc.size); | |
| 192 description->weight = static_cast<PP_FontWeight_Dev>(web_desc.weight); | |
| 193 description->italic = web_desc.italic ? PP_TRUE : PP_FALSE; | |
| 194 description->small_caps = web_desc.smallCaps ? PP_TRUE : PP_FALSE; | |
| 195 description->letter_spacing = static_cast<int32_t>(web_desc.letterSpacing); | |
| 196 description->word_spacing = static_cast<int32_t>(web_desc.wordSpacing); | |
| 197 | |
| 198 *face = UTF16ToUTF8(web_desc.family); | |
| 199 | |
| 200 metrics->height = font_->height(); | |
| 201 metrics->ascent = font_->ascent(); | |
| 202 metrics->descent = font_->descent(); | |
| 203 metrics->line_spacing = font_->lineSpacing(); | |
| 204 metrics->x_height = static_cast<int32_t>(font_->xHeight()); | |
| 205 | |
| 206 *result = PP_TRUE; | |
| 207 } | |
| 208 if (event) | |
| 209 event->Signal(); | |
| 210 } | |
| 211 | |
| 212 void FontImpl::DrawTextAt(base::WaitableEvent* event, | |
| 213 const DrawTextParams& params) { | |
| 214 TRACE_EVENT0("ppapi WebKit thread", "FontImpl::DrawTextAt"); | |
| 215 WebTextRun run = TextRunToWebTextRun(params.text); | |
| 216 | |
| 217 // Convert position and clip. | |
| 218 WebFloatPoint web_position(static_cast<float>(params.position->x), | |
| 219 static_cast<float>(params.position->y)); | |
| 220 WebRect web_clip; | |
| 221 if (!params.clip) { | |
| 222 // Use entire canvas. SkCanvas doesn't have a size on it, so we just use | |
| 223 // the current clip bounds. | |
| 224 SkRect skclip; | |
| 225 params.destination->getClipBounds(&skclip); | |
| 226 web_clip = WebRect(skclip.fLeft, skclip.fTop, skclip.fRight - skclip.fLeft, | |
| 227 skclip.fBottom - skclip.fTop); | |
| 228 } else { | |
| 229 web_clip = WebRect(params.clip->point.x, params.clip->point.y, | |
| 230 params.clip->size.width, params.clip->size.height); | |
| 231 } | |
| 232 | |
| 233 font_->drawText(webkit_glue::ToWebCanvas(params.destination), run, | |
| 234 web_position, params.color, web_clip, | |
| 235 params.image_data_is_opaque == PP_TRUE); | |
| 236 if (event) | |
| 237 event->Signal(); | |
| 238 } | |
| 239 | |
| 240 void FontImpl::MeasureText(base::WaitableEvent* event, | |
| 241 const TextRun& text, int32_t* result) { | |
| 242 TRACE_EVENT0("ppapi WebKit thread", "FontImpl::MeasureText"); | |
| 243 *result = font_->calculateWidth(TextRunToWebTextRun(text)); | |
| 244 if (event) | |
| 245 event->Signal(); | |
| 246 } | |
| 247 | |
| 248 void FontImpl::CharacterOffsetForPixel(base::WaitableEvent* event, | |
| 249 const TextRun& text, | |
| 250 int32_t pixel_position, | |
| 251 uint32_t* result) { | |
| 252 TRACE_EVENT0("ppapi WebKit thread", "FontImpl::CharacterOffsetForPixel"); | |
| 253 *result = static_cast<uint32_t>(font_->offsetForPosition( | |
| 254 TextRunToWebTextRun(text), static_cast<float>(pixel_position))); | |
| 255 if (event) | |
| 256 event->Signal(); | |
| 257 } | |
| 258 | |
| 259 void FontImpl::PixelOffsetForCharacter(base::WaitableEvent* event, | |
| 260 const TextRun& text, | |
| 261 uint32_t char_offset, | |
| 262 int32_t* result) { | |
| 263 TRACE_EVENT0("ppapi WebKit thread", "FontImpl::PixelOffsetForCharacter"); | |
| 264 WebTextRun run = TextRunToWebTextRun(text); | |
| 265 if (char_offset >= run.text.length()) { | |
| 266 *result = -1; | |
| 267 } else { | |
| 268 WebFloatRect rect = font_->selectionRectForText( | |
| 269 run, WebFloatPoint(0.0f, 0.0f), font_->height(), 0, char_offset); | |
| 270 *result = static_cast<int>(rect.width); | |
| 271 } | |
| 272 if (event) | |
| 273 event->Signal(); | |
| 274 } | |
| 275 | |
| 276 } // namespace | |
| 277 | |
| 278 // WebKitForwardingImpl -------------------------------------------------------- | |
| 279 | |
| 280 WebKitForwardingImpl::WebKitForwardingImpl() { | |
| 281 } | |
| 282 | |
| 283 WebKitForwardingImpl::~WebKitForwardingImpl() { | |
| 284 } | |
| 285 | |
| 286 void WebKitForwardingImpl::CreateFontForwarding( | |
| 287 base::WaitableEvent* event, | |
| 288 const PP_FontDescription_Dev& desc, | |
| 289 const std::string& desc_face, | |
| 290 const ::ppapi::Preferences& prefs, | |
| 291 Font** result) { | |
| 292 TRACE_EVENT0("ppapi WebKit thread", | |
| 293 "WebKitForwardingImpl::CreateFontForwarding"); | |
| 294 *result = new FontImpl(desc, desc_face, prefs); | |
| 295 if (event) | |
| 296 event->Signal(); | |
| 297 } | |
| 298 | |
| 299 } // namespace ppapi | |
| 300 } // namespace webkit | |
| OLD | NEW |