OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "skia/ext/vector_platform_device_emf_win.h" |
| 6 |
5 #include <windows.h> | 7 #include <windows.h> |
6 | 8 |
7 #include "skia/ext/vector_platform_device_emf_win.h" | 9 #include "base/logging.h" |
8 | 10 #include "base/string16.h" |
9 #include "skia/ext/bitmap_platform_device.h" | 11 #include "skia/ext/bitmap_platform_device.h" |
10 #include "skia/ext/skia_utils_win.h" | 12 #include "skia/ext/skia_utils_win.h" |
| 13 #include "third_party/skia/include/core/SkFontHost.h" |
11 #include "third_party/skia/include/core/SkPathEffect.h" | 14 #include "third_party/skia/include/core/SkPathEffect.h" |
12 #include "third_party/skia/include/core/SkTemplates.h" | 15 #include "third_party/skia/include/core/SkTemplates.h" |
13 #include "third_party/skia/include/core/SkUtils.h" | 16 #include "third_party/skia/include/core/SkUtils.h" |
14 #include "third_party/skia/include/ports/SkTypeface_win.h" | 17 #include "third_party/skia/include/ports/SkTypeface_win.h" |
15 | 18 |
16 namespace skia { | 19 namespace skia { |
17 | 20 |
18 #define CHECK_FOR_NODRAW_ANNOTATION(paint) \ | 21 #define CHECK_FOR_NODRAW_ANNOTATION(paint) \ |
19 do { if (paint.isNoDrawAnnotation()) { return; } } while (0) | 22 do { if (paint.isNoDrawAnnotation()) { return; } } while (0) |
20 | 23 |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 // encoding is not UTF8 (in which case ExtTextOut can't be used). | 362 // encoding is not UTF8 (in which case ExtTextOut can't be used). |
360 static UINT getTextOutOptions(const SkPaint& paint) { | 363 static UINT getTextOutOptions(const SkPaint& paint) { |
361 if (SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()) { | 364 if (SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()) { |
362 return ETO_GLYPH_INDEX; | 365 return ETO_GLYPH_INDEX; |
363 } else { | 366 } else { |
364 SkASSERT(SkPaint::kUTF16_TextEncoding == paint.getTextEncoding()); | 367 SkASSERT(SkPaint::kUTF16_TextEncoding == paint.getTextEncoding()); |
365 return 0; | 368 return 0; |
366 } | 369 } |
367 } | 370 } |
368 | 371 |
| 372 static SkiaEnsureTypefaceCharactersAccessible |
| 373 g_skia_ensure_typeface_characters_accessible = NULL; |
| 374 |
| 375 SK_API void SetSkiaEnsureTypefaceCharactersAccessible( |
| 376 SkiaEnsureTypefaceCharactersAccessible func) { |
| 377 // This function is supposed to be called once in process life time. |
| 378 SkASSERT(g_skia_ensure_typeface_characters_accessible == NULL); |
| 379 g_skia_ensure_typeface_characters_accessible = func; |
| 380 } |
| 381 |
| 382 void EnsureTypefaceCharactersAccessible( |
| 383 const SkTypeface& typeface, const wchar_t* text, unsigned int text_length) { |
| 384 LOGFONT lf; |
| 385 SkLOGFONTFromTypeface(&typeface, &lf); |
| 386 g_skia_ensure_typeface_characters_accessible(lf, text, text_length); |
| 387 } |
| 388 |
| 389 bool EnsureExtTextOut(HDC hdc, int x, int y, UINT options, const RECT * lprect, |
| 390 LPCWSTR text, unsigned int characters, const int * lpDx, |
| 391 SkTypeface* const typeface) { |
| 392 bool success = ExtTextOut(hdc, x, y, options, lprect, text, characters, lpDx); |
| 393 if (!success) { |
| 394 if (typeface) { |
| 395 EnsureTypefaceCharactersAccessible(*typeface, |
| 396 text, |
| 397 characters); |
| 398 success = ExtTextOut(hdc, x, y, options, lprect, text, characters, lpDx); |
| 399 if (!success) { |
| 400 LOGFONT lf; |
| 401 SkLOGFONTFromTypeface(typeface, &lf); |
| 402 VLOG(1) << "SkFontHost::EnsureTypefaceCharactersAccessible FAILED for " |
| 403 << " FaceName = " << lf.lfFaceName |
| 404 << " and characters: " << string16(text, characters); |
| 405 } |
| 406 } else { |
| 407 VLOG(1) << "ExtTextOut FAILED for default FaceName " |
| 408 << " and characters: " << string16(text, characters); |
| 409 } |
| 410 } |
| 411 return success; |
| 412 } |
| 413 |
369 void VectorPlatformDeviceEmf::drawText(const SkDraw& draw, | 414 void VectorPlatformDeviceEmf::drawText(const SkDraw& draw, |
370 const void* text, | 415 const void* text, |
371 size_t byteLength, | 416 size_t byteLength, |
372 SkScalar x, | 417 SkScalar x, |
373 SkScalar y, | 418 SkScalar y, |
374 const SkPaint& paint) { | 419 const SkPaint& paint) { |
375 SkGDIFontSetup setup; | 420 SkGDIFontSetup setup; |
| 421 bool useDrawPath = true; |
| 422 |
376 if (SkPaint::kUTF8_TextEncoding != paint.getTextEncoding() | 423 if (SkPaint::kUTF8_TextEncoding != paint.getTextEncoding() |
377 && setup.useGDI(hdc_, paint)) { | 424 && setup.useGDI(hdc_, paint)) { |
378 UINT options = getTextOutOptions(paint); | 425 UINT options = getTextOutOptions(paint); |
379 UINT count = byteLength >> 1; | 426 UINT count = byteLength >> 1; |
380 ExtTextOut(hdc_, SkScalarRound(x), SkScalarRound(y + getAscent(paint)), | 427 useDrawPath = !EnsureExtTextOut(hdc_, SkScalarRound(x), |
381 options, 0, reinterpret_cast<const wchar_t*>(text), count, NULL); | 428 SkScalarRound(y + getAscent(paint)), options, 0, |
382 } else { | 429 reinterpret_cast<const wchar_t*>(text), count, NULL, |
| 430 paint.getTypeface()); |
| 431 } |
| 432 |
| 433 if (useDrawPath) { |
383 SkPath path; | 434 SkPath path; |
384 paint.getTextPath(text, byteLength, x, y, &path); | 435 paint.getTextPath(text, byteLength, x, y, &path); |
385 drawPath(draw, path, paint); | 436 drawPath(draw, path, paint); |
386 } | 437 } |
387 } | 438 } |
388 | 439 |
389 static size_t size_utf8(const char* text) { | 440 static size_t size_utf8(const char* text) { |
390 return SkUTF8_CountUTF8Bytes(text); | 441 return SkUTF8_CountUTF8Bytes(text); |
391 } | 442 } |
392 | 443 |
393 static size_t size_utf16(const char* text) { | 444 static size_t size_utf16(const char* text) { |
394 uint16_t c = *reinterpret_cast<const uint16_t*>(text); | 445 uint16_t c = *reinterpret_cast<const uint16_t*>(text); |
395 return SkUTF16_IsHighSurrogate(c) ? 4 : 2; | 446 return SkUTF16_IsHighSurrogate(c) ? 4 : 2; |
396 } | 447 } |
397 | 448 |
398 static size_t size_glyphid(const char* text) { | 449 static size_t size_glyphid(const char* text) { |
399 return 2; | 450 return 2; |
400 } | 451 } |
401 | 452 |
402 void VectorPlatformDeviceEmf::drawPosText(const SkDraw& draw, | 453 void VectorPlatformDeviceEmf::drawPosText(const SkDraw& draw, |
403 const void* text, | 454 const void* text, |
404 size_t len, | 455 size_t len, |
405 const SkScalar pos[], | 456 const SkScalar pos[], |
406 SkScalar constY, | 457 SkScalar constY, |
407 int scalarsPerPos, | 458 int scalarsPerPos, |
408 const SkPaint& paint) { | 459 const SkPaint& paint) { |
409 SkGDIFontSetup setup; | 460 SkGDIFontSetup setup; |
| 461 bool useDrawText = true; |
| 462 |
410 if (2 == scalarsPerPos | 463 if (2 == scalarsPerPos |
411 && SkPaint::kUTF8_TextEncoding != paint.getTextEncoding() | 464 && SkPaint::kUTF8_TextEncoding != paint.getTextEncoding() |
412 && setup.useGDI(hdc_, paint)) { | 465 && setup.useGDI(hdc_, paint)) { |
413 int startX = SkScalarRound(pos[0]); | 466 int startX = SkScalarRound(pos[0]); |
414 int startY = SkScalarRound(pos[1] + getAscent(paint)); | 467 int startY = SkScalarRound(pos[1] + getAscent(paint)); |
415 const int count = len >> 1; | 468 const int count = len >> 1; |
416 SkAutoSTMalloc<64, INT> storage(count); | 469 SkAutoSTMalloc<64, INT> storage(count); |
417 INT* advances = storage.get(); | 470 INT* advances = storage.get(); |
418 for (int i = 0; i < count - 1; ++i) { | 471 for (int i = 0; i < count - 1; ++i) { |
419 advances[i] = SkScalarRound(pos[2] - pos[0]); | 472 advances[i] = SkScalarRound(pos[2] - pos[0]); |
420 pos += 2; | 473 pos += 2; |
421 } | 474 } |
422 ExtTextOut(hdc_, startX, startY, getTextOutOptions(paint), 0, | 475 useDrawText = !EnsureExtTextOut(hdc_, startX, startY, |
423 reinterpret_cast<const wchar_t*>(text), count, advances); | 476 getTextOutOptions(paint), 0, reinterpret_cast<const wchar_t*>(text), |
424 } else { | 477 count, advances, paint.getTypeface()); |
| 478 } |
| 479 |
| 480 if (useDrawText) { |
425 size_t (*bytesPerCodePoint)(const char*); | 481 size_t (*bytesPerCodePoint)(const char*); |
426 switch (paint.getTextEncoding()) { | 482 switch (paint.getTextEncoding()) { |
427 case SkPaint::kUTF8_TextEncoding: | 483 case SkPaint::kUTF8_TextEncoding: |
428 bytesPerCodePoint = size_utf8; | 484 bytesPerCodePoint = size_utf8; |
429 break; | 485 break; |
430 case SkPaint::kUTF16_TextEncoding: | 486 case SkPaint::kUTF16_TextEncoding: |
431 bytesPerCodePoint = size_utf16; | 487 bytesPerCodePoint = size_utf16; |
432 break; | 488 break; |
433 default: | 489 default: |
434 SkASSERT(SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()); | 490 SkASSERT(SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()); |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
865 pixels, | 921 pixels, |
866 reinterpret_cast<const BITMAPINFO*>(&hdr), | 922 reinterpret_cast<const BITMAPINFO*>(&hdr), |
867 DIB_RGB_COLORS, | 923 DIB_RGB_COLORS, |
868 SRCCOPY); | 924 SRCCOPY); |
869 } | 925 } |
870 EndPlatformPaint(); | 926 EndPlatformPaint(); |
871 Cleanup(); | 927 Cleanup(); |
872 } | 928 } |
873 | 929 |
874 } // namespace skia | 930 } // namespace skia |
OLD | NEW |