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