Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: ppapi/shared_impl/private/ppb_font_shared.cc

Issue 9192038: Relanding this with fixes to the mac dbg builder (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/shared_impl/private/ppb_font_shared.h ('k') | ppapi/shared_impl/webkit_forwarding.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ppapi/shared_impl/ppb_font_shared.h" 5 #include "ppapi/shared_impl/private/ppb_font_shared.h"
6 6
7 #include "base/debug/trace_event.h"
8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h"
7 #include "ppapi/c/dev/ppb_font_dev.h" 10 #include "ppapi/c/dev/ppb_font_dev.h"
11 #include "ppapi/shared_impl/ppapi_preferences.h"
12 #include "ppapi/shared_impl/var.h"
13 #include "ppapi/thunk/enter.h"
14 #include "ppapi/thunk/ppb_image_data_api.h"
15 #include "ppapi/thunk/thunk.h"
16 #include "skia/ext/platform_canvas.h"
17 #include "third_party/skia/include/core/SkRect.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCanvas.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoin t.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatRect .h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFont.h"
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFontDescription.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextRun.h"
25
26 using ppapi::StringVar;
27 using ppapi::thunk::EnterResource;
28 using ppapi::thunk::EnterResourceNoLock;
29 using ppapi::thunk::PPB_ImageData_API;
30 using ppapi::WebKitForwarding;
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 using WebKit::WebCanvas;
8 38
9 namespace ppapi { 39 namespace ppapi {
10 40
41 namespace {
42
43 // Converts the given PP_TextRun to a TextRun, returning true on success.
44 // False means the input was invalid.
45 bool PPTextRunToTextRun(const PP_TextRun_Dev* run,
46 WebKitForwarding::Font::TextRun* output) {
47 StringVar* text_string = StringVar::FromPPVar(run->text);
48 if (!text_string)
49 return false;
50
51 output->text = text_string->value();
52 output->rtl = run->rtl == PP_TRUE ? true : false;
53 output->override_direction =
54 run->override_direction == PP_TRUE ? true : false;
55 return true;
56 }
57
58 // The PP_* version lacks "None", so is just one value shifted from the
59 // WebFontDescription version. These values are checked in
60 // PPFontDescToWebFontDesc to make sure the conversion is correct. This is a
61 // macro so it can also be used in the COMPILE_ASSERTS.
62 #define PP_FONTFAMILY_TO_WEB_FONTFAMILY(f) \
63 static_cast<WebFontDescription::GenericFamily>(f + 1)
64
65 // Assumes the given PP_FontDescription has been validated.
66 WebFontDescription PPFontDescToWebFontDesc(const PP_FontDescription_Dev& font,
67 const std::string& face,
68 const ::ppapi::Preferences& prefs) {
69 // Verify that the enums match so we can just static cast.
70 COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight100) ==
71 static_cast<int>(PP_FONTWEIGHT_100),
72 FontWeight100);
73 COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight900) ==
74 static_cast<int>(PP_FONTWEIGHT_900),
75 FontWeight900);
76 COMPILE_ASSERT(WebFontDescription::GenericFamilyStandard ==
77 PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_DEFAULT),
78 StandardFamily);
79 COMPILE_ASSERT(WebFontDescription::GenericFamilySerif ==
80 PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SERIF),
81 SerifFamily);
82 COMPILE_ASSERT(WebFontDescription::GenericFamilySansSerif ==
83 PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_SANSSERIF),
84 SansSerifFamily);
85 COMPILE_ASSERT(WebFontDescription::GenericFamilyMonospace ==
86 PP_FONTFAMILY_TO_WEB_FONTFAMILY(PP_FONTFAMILY_MONOSPACE),
87 MonospaceFamily);
88
89 WebFontDescription result;
90 string16 resolved_family;
91 if (face.empty()) {
92 // Resolve the generic family.
93 switch (font.family) {
94 case PP_FONTFAMILY_SERIF:
95 resolved_family = prefs.serif_font_family;
96 break;
97 case PP_FONTFAMILY_SANSSERIF:
98 resolved_family = prefs.sans_serif_font_family;
99 break;
100 case PP_FONTFAMILY_MONOSPACE:
101 resolved_family = prefs.fixed_font_family;
102 break;
103 case PP_FONTFAMILY_DEFAULT:
104 default:
105 resolved_family = prefs.standard_font_family;
106 break;
107 }
108 } else {
109 // Use the exact font.
110 resolved_family = UTF8ToUTF16(face);
111 }
112 result.family = resolved_family;
113
114 result.genericFamily = PP_FONTFAMILY_TO_WEB_FONTFAMILY(font.family);
115
116 if (font.size == 0) {
117 // Resolve the default font size, using the resolved family to see if
118 // we should use the fixed or regular font size. It's difficult at this
119 // level to detect if the requested font is fixed width, so we only apply
120 // the alternate font size to the default fixed font family.
121 if (StringToLowerASCII(resolved_family) ==
122 StringToLowerASCII(prefs.fixed_font_family))
123 result.size = static_cast<float>(prefs.default_fixed_font_size);
124 else
125 result.size = static_cast<float>(prefs.default_font_size);
126 } else {
127 // Use the exact size.
128 result.size = static_cast<float>(font.size);
129 }
130
131 result.italic = font.italic != PP_FALSE;
132 result.smallCaps = font.small_caps != PP_FALSE;
133 result.weight = static_cast<WebFontDescription::Weight>(font.weight);
134 result.letterSpacing = static_cast<short>(font.letter_spacing);
135 result.wordSpacing = static_cast<short>(font.word_spacing);
136 return result;
137 }
138
139 WebTextRun TextRunToWebTextRun(const WebKitForwarding::Font::TextRun& run) {
140 return WebTextRun(UTF8ToUTF16(run.text),
141 run.rtl != PP_FALSE,
142 run.override_direction != PP_FALSE);
143 }
144
145 // FontImpl --------------------------------------------------------------------
146
147 class FontImpl : public WebKitForwarding::Font {
148 public:
149 FontImpl(const PP_FontDescription_Dev& desc,
150 const std::string& desc_face,
151 const ::ppapi::Preferences& prefs);
152 virtual ~FontImpl();
153
154 virtual void Describe(PP_FontDescription_Dev* description,
155 std::string* face,
156 PP_FontMetrics_Dev* metrics,
157 PP_Bool* result) OVERRIDE;
158 virtual void DrawTextAt(const DrawTextParams& params) OVERRIDE;
159 virtual void MeasureText(const TextRun& text,
160 int32_t* result) OVERRIDE;
161 virtual void CharacterOffsetForPixel(const TextRun& text,
162 int32_t pixel_position,
163 uint32_t* result) OVERRIDE;
164 virtual void PixelOffsetForCharacter(const TextRun& text,
165 uint32_t char_offset,
166 int32_t* result) OVERRIDE;
167
168 private:
169 scoped_ptr<WebFont> font_;
170
171 DISALLOW_COPY_AND_ASSIGN(FontImpl);
172 };
173
174 FontImpl::FontImpl(const PP_FontDescription_Dev& desc,
175 const std::string& desc_face,
176 const ::ppapi::Preferences& prefs) {
177 WebFontDescription web_font_desc = PPFontDescToWebFontDesc(desc, desc_face,
178 prefs);
179 font_.reset(WebFont::create(web_font_desc));
180 }
181
182 FontImpl::~FontImpl() {
183 }
184
185 void FontImpl::Describe(PP_FontDescription_Dev* description,
186 std::string* face,
187 PP_FontMetrics_Dev* metrics,
188 PP_Bool* result) {
189 TRACE_EVENT0("ppapi WebKit thread", "FontImpl::Describe");
190 if (description->face.type != PP_VARTYPE_UNDEFINED) {
191 *result = PP_FALSE;
192 } else {
193 WebFontDescription web_desc = font_->fontDescription();
194
195 // While converting the other way in PPFontDescToWebFontDesc we validated
196 // that the enums can be casted.
197 description->face = PP_MakeUndefined();
198 description->family =
199 static_cast<PP_FontFamily_Dev>(web_desc.genericFamily);
200 description->size = static_cast<uint32_t>(web_desc.size);
201 description->weight = static_cast<PP_FontWeight_Dev>(web_desc.weight);
202 description->italic = web_desc.italic ? PP_TRUE : PP_FALSE;
203 description->small_caps = web_desc.smallCaps ? PP_TRUE : PP_FALSE;
204 description->letter_spacing = static_cast<int32_t>(web_desc.letterSpacing);
205 description->word_spacing = static_cast<int32_t>(web_desc.wordSpacing);
206
207 *face = UTF16ToUTF8(web_desc.family);
208
209 metrics->height = font_->height();
210 metrics->ascent = font_->ascent();
211 metrics->descent = font_->descent();
212 metrics->line_spacing = font_->lineSpacing();
213 metrics->x_height = static_cast<int32_t>(font_->xHeight());
214
215 *result = PP_TRUE;
216 }
217 }
218
219 void FontImpl::DrawTextAt(const DrawTextParams& params) {
220 TRACE_EVENT0("ppapi WebKit thread", "FontImpl::DrawTextAt");
221 WebTextRun run = TextRunToWebTextRun(params.text);
222
223 // Convert position and clip.
224 WebFloatPoint web_position(static_cast<float>(params.position->x),
225 static_cast<float>(params.position->y));
226 WebRect web_clip;
227 if (!params.clip) {
228 // Use entire canvas. SkCanvas doesn't have a size on it, so we just use
229 // the current clip bounds.
230 SkRect skclip;
231 params.destination->getClipBounds(&skclip);
232 web_clip = WebRect(skclip.fLeft, skclip.fTop, skclip.fRight - skclip.fLeft,
233 skclip.fBottom - skclip.fTop);
234 } else {
235 web_clip = WebRect(params.clip->point.x, params.clip->point.y,
236 params.clip->size.width, params.clip->size.height);
237 }
238
239 #if WEBKIT_USING_SKIA
240 WebCanvas* canvas = params.destination;
241 #elif WEBKIT_USING_CG
242 WebCanvas* canvas = skia::GetBitmapContext(skia::GetTopDevice(*destination));
243 #else
244 NOTIMPLEMENTED();
245 return;
246 #endif
247 font_->drawText(canvas, run, web_position, params.color, web_clip,
248 params.image_data_is_opaque == PP_TRUE);
249 }
250
251 void FontImpl::MeasureText(const TextRun& text, int32_t* result) {
252 TRACE_EVENT0("ppapi WebKit thread", "FontImpl::MeasureText");
253 *result = font_->calculateWidth(TextRunToWebTextRun(text));
254 }
255
256 void FontImpl::CharacterOffsetForPixel(const TextRun& text,
257 int32_t pixel_position,
258 uint32_t* result) {
259 TRACE_EVENT0("ppapi WebKit thread", "FontImpl::CharacterOffsetForPixel");
260 *result = static_cast<uint32_t>(font_->offsetForPosition(
261 TextRunToWebTextRun(text), static_cast<float>(pixel_position)));
262 }
263
264 void FontImpl::PixelOffsetForCharacter(const TextRun& text,
265 uint32_t char_offset,
266 int32_t* result) {
267 TRACE_EVENT0("ppapi WebKit thread", "FontImpl::PixelOffsetForCharacter");
268 WebTextRun run = TextRunToWebTextRun(text);
269 if (char_offset >= run.text.length()) {
270 *result = -1;
271 } else {
272 WebFloatRect rect = font_->selectionRectForText(
273 run, WebFloatPoint(0.0f, 0.0f), font_->height(), 0, char_offset);
274 *result = static_cast<int>(rect.width);
275 }
276 }
277
278 } // namespace
279
11 // static 280 // static
12 bool PPB_Font_Shared::IsPPFontDescriptionValid( 281 bool PPB_Font_Shared::IsPPFontDescriptionValid(
13 const PP_FontDescription_Dev& desc) { 282 const PP_FontDescription_Dev& desc) {
14 // Check validity of string. We can't check the actual text since we could 283 // Check validity of string. We can't check the actual text since we could
15 // be on the wrong thread and don't know if we're in the plugin or the host. 284 // be on the wrong thread and don't know if we're in the plugin or the host.
16 if (desc.face.type != PP_VARTYPE_STRING && 285 if (desc.face.type != PP_VARTYPE_STRING &&
17 desc.face.type != PP_VARTYPE_UNDEFINED) 286 desc.face.type != PP_VARTYPE_UNDEFINED)
18 return false; 287 return false;
19 288
20 // Check enum ranges. 289 // Check enum ranges.
21 if (static_cast<int>(desc.family) < PP_FONTFAMILY_DEFAULT || 290 if (static_cast<int>(desc.family) < PP_FONTFAMILY_DEFAULT ||
22 static_cast<int>(desc.family) > PP_FONTFAMILY_MONOSPACE) 291 static_cast<int>(desc.family) > PP_FONTFAMILY_MONOSPACE)
23 return false; 292 return false;
24 if (static_cast<int>(desc.weight) < PP_FONTWEIGHT_100 || 293 if (static_cast<int>(desc.weight) < PP_FONTWEIGHT_100 ||
25 static_cast<int>(desc.weight) > PP_FONTWEIGHT_900) 294 static_cast<int>(desc.weight) > PP_FONTWEIGHT_900)
26 return false; 295 return false;
27 296
28 // Check for excessive sizes which may cause layout to get confused. 297 // Check for excessive sizes which may cause layout to get confused.
29 if (desc.size > 200) 298 if (desc.size > 200)
30 return false; 299 return false;
31 300
32 return true; 301 return true;
33 } 302 }
34 303
304 // static
305 PP_Resource PPB_Font_Shared::CreateAsImpl(
306 PP_Instance instance,
307 const PP_FontDescription_Dev& description,
308 const ::ppapi::Preferences& prefs) {
309 if (!::ppapi::PPB_Font_Shared::IsPPFontDescriptionValid(description))
310 return 0;
311 return (new PPB_Font_Shared(instance, description, prefs))->GetReference();
312 }
313
314 // static
315 PP_Resource PPB_Font_Shared::CreateAsProxy(
316 PP_Instance instance,
317 const PP_FontDescription_Dev& description,
318 const ::ppapi::Preferences& prefs) {
319 return CreateAsImpl(instance, description, prefs);
320 }
321
322 PPB_Font_Shared::PPB_Font_Shared(PP_Instance pp_instance,
323 const PP_FontDescription_Dev& desc,
324 const ::ppapi::Preferences& prefs)
325 : Resource(pp_instance) {
326 StringVar* face_name = StringVar::FromPPVar(desc.face);
327
328 font_impl_.reset(new FontImpl(
329 desc, face_name ? face_name->value() : std::string(), prefs));
330 }
331
332 PPB_Font_Shared::~PPB_Font_Shared() {
333 }
334
335 ::ppapi::thunk::PPB_Font_API* PPB_Font_Shared::AsPPB_Font_API() {
336 return this;
337 }
338
339 PP_Bool PPB_Font_Shared::Describe(PP_FontDescription_Dev* description,
340 PP_FontMetrics_Dev* metrics) {
341 std::string face;
342 PP_Bool result = PP_FALSE;
343 font_impl_->Describe(description, &face, metrics, &result);
344 if (!result)
345 return PP_FALSE;
346
347 // Convert the string.
348 description->face = StringVar::StringToPPVar(face);
349 return PP_TRUE;
350 }
351
352 PP_Bool PPB_Font_Shared::DrawTextAt(PP_Resource image_data,
353 const PP_TextRun_Dev* text,
354 const PP_Point* position,
355 uint32_t color,
356 const PP_Rect* clip,
357 PP_Bool image_data_is_opaque) {
358 PP_Bool result = PP_FALSE;
359 // Get and map the image data we're painting to.
360 EnterResource<PPB_ImageData_API> enter(image_data, true);
361 if (enter.failed())
362 return result;
363
364 // TODO(ananta)
365 // We need to remove dependency on skia from this layer.
366 PPB_ImageData_API* image = static_cast<PPB_ImageData_API*>(
367 enter.object());
368 skia::PlatformCanvas* canvas = image->GetPlatformCanvas();
369 bool needs_unmapping = false;
370 if (!canvas) {
371 needs_unmapping = true;
372 image->Map();
373 canvas = image->GetPlatformCanvas();
374 if (!canvas)
375 return result; // Failure mapping.
376 }
377
378 WebKitForwarding::Font::TextRun run;
379 if (PPTextRunToTextRun(text, &run)) {
380 font_impl_->DrawTextAt(WebKitForwarding::Font::DrawTextParams(
381 canvas, run, position, color, clip, image_data_is_opaque));
382 result = PP_TRUE;
383 }
384
385 if (needs_unmapping)
386 image->Unmap();
387 return result;
388 }
389
390 int32_t PPB_Font_Shared::MeasureText(const PP_TextRun_Dev* text) {
391 int32_t result = -1;
392 WebKitForwarding::Font::TextRun run;
393 if (PPTextRunToTextRun(text, &run))
394 font_impl_->MeasureText(run, &result);
395 return result;
396 }
397
398 uint32_t PPB_Font_Shared::CharacterOffsetForPixel(const PP_TextRun_Dev* text,
399 int32_t pixel_position) {
400 uint32_t result = -1;
401 WebKitForwarding::Font::TextRun run;
402 if (PPTextRunToTextRun(text, &run)) {
403 font_impl_->CharacterOffsetForPixel(run, pixel_position, &result);
404 }
405 return result;
406 }
407
408 int32_t PPB_Font_Shared::PixelOffsetForCharacter(const PP_TextRun_Dev* text,
409 uint32_t char_offset) {
410 int32_t result = -1;
411 WebKitForwarding::Font::TextRun run;
412 if (PPTextRunToTextRun(text, &run)) {
413 font_impl_->PixelOffsetForCharacter(run, char_offset, &result);
414 }
415 return result;
416 }
417
35 } // namespace ppapi 418 } // namespace ppapi
419
OLDNEW
« no previous file with comments | « ppapi/shared_impl/private/ppb_font_shared.h ('k') | ppapi/shared_impl/webkit_forwarding.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698