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