OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium 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 "core/fxge/include/fx_ge.h" | |
6 | |
7 #if defined(_SKIA_SUPPORT_) | 5 #if defined(_SKIA_SUPPORT_) |
8 #include <algorithm> | 6 #include <algorithm> |
9 #include <vector> | 7 #include <vector> |
10 | 8 |
11 #include "core/fxcodec/include/fx_codec.h" | 9 #include "core/fxcodec/include/fx_codec.h" |
12 | 10 |
13 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" | 11 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" |
14 #include "core/fpdfapi/fpdf_page/pageint.h" | 12 #include "core/fpdfapi/fpdf_page/pageint.h" |
15 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 13 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
16 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" | 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
17 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" | 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" |
18 #include "core/fxge/skia/fx_skia_device.h" | 16 #include "core/fxge/skia/fx_skia_device.h" |
19 | 17 |
20 #include "third_party/skia/include/core/SkCanvas.h" | 18 #include "third_party/skia/include/core/SkCanvas.h" |
21 #include "third_party/skia/include/core/SkColorFilter.h" | 19 #include "third_party/skia/include/core/SkColorFilter.h" |
22 #include "third_party/skia/include/core/SkColorPriv.h" | 20 #include "third_party/skia/include/core/SkColorPriv.h" |
23 #include "third_party/skia/include/core/SkPaint.h" | 21 #include "third_party/skia/include/core/SkPaint.h" |
24 #include "third_party/skia/include/core/SkPath.h" | 22 #include "third_party/skia/include/core/SkPath.h" |
25 #include "third_party/skia/include/core/SkPictureRecorder.h" | 23 #include "third_party/skia/include/core/SkPictureRecorder.h" |
26 #include "third_party/skia/include/core/SkStream.h" | 24 #include "third_party/skia/include/core/SkStream.h" |
27 #include "third_party/skia/include/core/SkTypeface.h" | 25 #include "third_party/skia/include/core/SkTypeface.h" |
28 #include "third_party/skia/include/effects/SkDashPathEffect.h" | 26 #include "third_party/skia/include/effects/SkDashPathEffect.h" |
29 #include "third_party/skia/include/effects/SkGradientShader.h" | 27 #include "third_party/skia/include/effects/SkGradientShader.h" |
30 #include "third_party/skia/include/pathops/SkPathOps.h" | 28 #include "third_party/skia/include/pathops/SkPathOps.h" |
31 | 29 |
| 30 #ifdef SK_DEBUG |
| 31 #include "third_party/skia/include/core/SkClipStack.h" |
| 32 #endif |
| 33 |
32 namespace { | 34 namespace { |
33 | 35 |
34 #define SHOW_SKIA_PATH 0 // set to 1 to print the path contents | 36 #define SHOW_SKIA_PATH 0 // set to 1 to print the path contents |
35 #define DRAW_SKIA_CLIP 0 // set to 1 to draw a green rectangle around the clip | 37 #define DRAW_SKIA_CLIP 0 // set to 1 to draw a green rectangle around the clip |
36 | 38 |
37 void DebugShowSkiaPath(const SkPath& path) { | 39 void DebugShowSkiaPath(const SkPath& path) { |
38 #if SHOW_SKIA_PATH | 40 #if SHOW_SKIA_PATH |
39 char buffer[4096]; | 41 char buffer[4096]; |
40 sk_bzero(buffer, sizeof(buffer)); | 42 sk_bzero(buffer, sizeof(buffer)); |
41 SkMemoryWStream stream(buffer, sizeof(buffer)); | 43 SkMemoryWStream stream(buffer, sizeof(buffer)); |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 // rectPts[minBounds] and rectPts[maxBounds] and perpendicular to the | 471 // rectPts[minBounds] and rectPts[maxBounds] and perpendicular to the |
470 // gradient that goes through startEdgePt, endEdgePt. | 472 // gradient that goes through startEdgePt, endEdgePt. |
471 clip->moveTo(IntersectSides(rectPts[minBounds], slope, startEdgePt)); | 473 clip->moveTo(IntersectSides(rectPts[minBounds], slope, startEdgePt)); |
472 clip->lineTo(IntersectSides(rectPts[minBounds], slope, endEdgePt)); | 474 clip->lineTo(IntersectSides(rectPts[minBounds], slope, endEdgePt)); |
473 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, endEdgePt)); | 475 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, endEdgePt)); |
474 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, startEdgePt)); | 476 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, startEdgePt)); |
475 } | 477 } |
476 | 478 |
477 } // namespace | 479 } // namespace |
478 | 480 |
| 481 // Encapsulate the state used for successive text and path draws so that |
| 482 // they can be combined. |
| 483 class SkiaState { |
| 484 public: |
| 485 enum class Clip { |
| 486 kSave, |
| 487 kPath, |
| 488 }; |
| 489 |
| 490 // mark all cached state as uninitialized |
| 491 SkiaState() |
| 492 : m_pFont(nullptr), |
| 493 m_pCache(nullptr), |
| 494 m_fontSize(0), |
| 495 m_fillColor(0), |
| 496 m_strokeColor(0), |
| 497 m_blendType(0), |
| 498 m_commandIndex(0), |
| 499 m_drawText(false), |
| 500 m_drawPath(false), |
| 501 m_fillPath(false), |
| 502 m_debugDisable(false) {} |
| 503 |
| 504 bool DrawPath(const CFX_PathData* pPathData, |
| 505 const CFX_Matrix* pMatrix, |
| 506 const CFX_GraphStateData* pDrawState, |
| 507 uint32_t fill_color, |
| 508 uint32_t stroke_color, |
| 509 int fill_mode, |
| 510 int blend_type, |
| 511 CFX_SkiaDeviceDriver* pDriver) { |
| 512 if (m_debugDisable) |
| 513 return false; |
| 514 if (m_commandIndex < m_commands.count()) |
| 515 FlushCommands(pDriver); |
| 516 if (m_drawText) |
| 517 FlushText(pDriver); |
| 518 if (m_drawPath && DrawChanged(pMatrix, pDrawState, fill_color, stroke_color, |
| 519 fill_mode, blend_type)) { |
| 520 FlushPath(pDriver); |
| 521 } |
| 522 if (!m_drawPath) { |
| 523 m_skPath.reset(); |
| 524 m_fillPath = (fill_mode & 3) && fill_color; |
| 525 m_skPath.setFillType((fill_mode & 3) == FXFILL_ALTERNATE |
| 526 ? SkPath::kEvenOdd_FillType |
| 527 : SkPath::kWinding_FillType); |
| 528 m_drawState = *pDrawState; |
| 529 m_fillColor = fill_color; |
| 530 m_strokeColor = stroke_color; |
| 531 m_blendType = blend_type; |
| 532 m_drawMatrix = *pMatrix; |
| 533 } |
| 534 SkPath skPath = BuildPath(pPathData); |
| 535 SkPoint delta; |
| 536 if (MatrixOffset(pMatrix, &delta)) |
| 537 skPath.offset(delta.fX, delta.fY); |
| 538 m_skPath.addPath(skPath); |
| 539 m_drawPath = true; |
| 540 return true; |
| 541 } |
| 542 |
| 543 void FlushPath(CFX_SkiaDeviceDriver* pDriver) { |
| 544 SkMatrix skMatrix = ToSkMatrix(m_drawMatrix); |
| 545 SkPaint skPaint; |
| 546 skPaint.setAntiAlias(true); |
| 547 int stroke_alpha = FXARGB_A(m_strokeColor); |
| 548 if (stroke_alpha) |
| 549 pDriver->PaintStroke(&skPaint, &m_drawState, skMatrix); |
| 550 SkCanvas* skCanvas = pDriver->SkiaCanvas(); |
| 551 skCanvas->save(); |
| 552 skCanvas->concat(skMatrix); |
| 553 if (m_fillPath) { |
| 554 SkPath strokePath; |
| 555 const SkPath* fillPath = &m_skPath; |
| 556 if (stroke_alpha) { |
| 557 SkAlpha fillA = SkColorGetA(m_fillColor); |
| 558 SkAlpha strokeA = SkColorGetA(m_strokeColor); |
| 559 if (fillA && fillA < 0xFF && strokeA && strokeA < 0xFF) { |
| 560 skPaint.getFillPath(m_skPath, &strokePath); |
| 561 if (Op(m_skPath, strokePath, SkPathOp::kDifference_SkPathOp, |
| 562 &strokePath)) { |
| 563 fillPath = &strokePath; |
| 564 } |
| 565 } |
| 566 } |
| 567 skPaint.setStyle(SkPaint::kFill_Style); |
| 568 skPaint.setColor(m_fillColor); |
| 569 skCanvas->drawPath(*fillPath, skPaint); |
| 570 } |
| 571 if (stroke_alpha) { |
| 572 DebugShowSkiaPath(m_skPath); |
| 573 DebugShowCanvasMatrix(skCanvas); |
| 574 skPaint.setStyle(SkPaint::kStroke_Style); |
| 575 skPaint.setColor(m_strokeColor); |
| 576 skCanvas->drawPath(m_skPath, skPaint); |
| 577 } |
| 578 skCanvas->restore(); |
| 579 m_drawPath = false; |
| 580 } |
| 581 |
| 582 bool DrawText(int nChars, |
| 583 const FXTEXT_CHARPOS* pCharPos, |
| 584 CFX_Font* pFont, |
| 585 CFX_FontCache* pCache, |
| 586 const CFX_Matrix* pMatrix, |
| 587 FX_FLOAT font_size, |
| 588 uint32_t color, |
| 589 CFX_SkiaDeviceDriver* pDriver) { |
| 590 if (m_debugDisable) |
| 591 return false; |
| 592 if (m_commandIndex < m_commands.count()) |
| 593 FlushCommands(pDriver); |
| 594 if (m_drawPath) |
| 595 FlushPath(pDriver); |
| 596 if (m_drawText && FontChanged(pFont, pCache, pMatrix, font_size, color)) |
| 597 FlushText(pDriver); |
| 598 if (!m_drawText) { |
| 599 m_positions.setCount(0); |
| 600 m_glyphs.setCount(0); |
| 601 m_pFont = pFont; |
| 602 m_pCache = pCache; |
| 603 m_fontSize = font_size; |
| 604 m_fillColor = color; |
| 605 m_drawMatrix = *pMatrix; |
| 606 } |
| 607 int count = m_positions.count(); |
| 608 m_positions.setCount(nChars + count); |
| 609 m_glyphs.setCount(nChars + count); |
| 610 for (int index = 0; index < nChars; ++index) { |
| 611 const FXTEXT_CHARPOS& cp = pCharPos[index]; |
| 612 m_positions[index + count] = {cp.m_OriginX, cp.m_OriginY}; |
| 613 m_glyphs[index + count] = (uint16_t)cp.m_GlyphIndex; |
| 614 } |
| 615 SkPoint delta; |
| 616 if (MatrixOffset(pMatrix, &delta)) { |
| 617 for (int index = 0; index < nChars; ++index) |
| 618 m_positions[index + count].offset(delta.fX, -delta.fY); |
| 619 } |
| 620 m_drawText = true; |
| 621 return true; |
| 622 } |
| 623 |
| 624 void FlushText(CFX_SkiaDeviceDriver* pDriver) { |
| 625 SkMatrix skMatrix = ToFlippedSkMatrix(m_drawMatrix); |
| 626 SkPaint skPaint; |
| 627 skPaint.setAntiAlias(true); |
| 628 skPaint.setColor(m_fillColor); |
| 629 if (m_pFont->GetFace()) { // exclude placeholder test fonts |
| 630 sk_sp<SkTypeface> typeface(SkSafeRef(m_pCache->GetDeviceCache(m_pFont))); |
| 631 skPaint.setTypeface(typeface); |
| 632 } |
| 633 skPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| 634 skPaint.setTextSize(m_fontSize); |
| 635 skPaint.setSubpixelText(true); |
| 636 SkCanvas* skCanvas = pDriver->SkiaCanvas(); |
| 637 skCanvas->save(); |
| 638 skCanvas->concat(skMatrix); |
| 639 skCanvas->drawPosText(m_glyphs.begin(), m_glyphs.count() * 2, |
| 640 m_positions.begin(), skPaint); |
| 641 skCanvas->restore(); |
| 642 m_drawText = false; |
| 643 } |
| 644 |
| 645 bool SetClipFill(const CFX_PathData* pPathData, |
| 646 const CFX_Matrix* pMatrix, |
| 647 int fill_mode, |
| 648 CFX_SkiaDeviceDriver* pDriver) { |
| 649 if (m_debugDisable) |
| 650 return false; |
| 651 SkPath skClipPath = BuildPath(pPathData); |
| 652 skClipPath.setFillType((fill_mode & 3) == FXFILL_ALTERNATE |
| 653 ? SkPath::kEvenOdd_FillType |
| 654 : SkPath::kWinding_FillType); |
| 655 SkMatrix skMatrix = ToSkMatrix(*pMatrix); |
| 656 skClipPath.transform(skMatrix); |
| 657 return SetClip(skClipPath, pDriver); |
| 658 } |
| 659 |
| 660 bool SetClip(const SkPath& skClipPath, CFX_SkiaDeviceDriver* pDriver) { |
| 661 if (m_commandIndex < m_commands.count()) { |
| 662 if (m_commands[m_commandIndex] == Clip::kPath && |
| 663 m_clips[m_commandIndex] == skClipPath) { |
| 664 ++m_commandIndex; |
| 665 return true; |
| 666 } |
| 667 FlushCommands(pDriver); |
| 668 } |
| 669 Flush(pDriver); |
| 670 m_commands.push(Clip::kPath); |
| 671 ++m_commandIndex; |
| 672 m_clips.push_back(skClipPath); |
| 673 return false; |
| 674 } |
| 675 |
| 676 bool SetClipStroke(const CFX_PathData* pPathData, |
| 677 const CFX_Matrix* pMatrix, |
| 678 const CFX_GraphStateData* pGraphState, |
| 679 CFX_SkiaDeviceDriver* pDriver) { |
| 680 if (m_debugDisable) |
| 681 return false; |
| 682 SkPath skPath = BuildPath(pPathData); |
| 683 SkMatrix skMatrix = ToSkMatrix(*pMatrix); |
| 684 SkPaint skPaint; |
| 685 pDriver->PaintStroke(&skPaint, pGraphState, skMatrix); |
| 686 SkPath dst_path; |
| 687 skPaint.getFillPath(skPath, &dst_path); |
| 688 dst_path.transform(skMatrix); |
| 689 return SetClip(dst_path, pDriver); |
| 690 } |
| 691 |
| 692 bool MatrixOffset(const CFX_Matrix* pMatrix, SkPoint* delta) { |
| 693 delta->set(pMatrix->e - m_drawMatrix.e, pMatrix->f - m_drawMatrix.f); |
| 694 if (!delta->fX && !delta->fY) |
| 695 return true; |
| 696 SkMatrix drawMatrix = ToSkMatrix(m_drawMatrix); |
| 697 if (!(drawMatrix.getType() & ~SkMatrix::kTranslate_Mask)) |
| 698 return true; |
| 699 SkMatrix invDrawMatrix; |
| 700 if (!drawMatrix.invert(&invDrawMatrix)) |
| 701 return false; |
| 702 SkMatrix invNewMatrix; |
| 703 SkMatrix newMatrix = ToSkMatrix(*pMatrix); |
| 704 if (!newMatrix.invert(&invNewMatrix)) |
| 705 return false; |
| 706 delta->set(invDrawMatrix.getTranslateX() - invNewMatrix.getTranslateX(), |
| 707 invDrawMatrix.getTranslateY() - invNewMatrix.getTranslateY()); |
| 708 return true; |
| 709 } |
| 710 |
| 711 void FlushCommands(CFX_SkiaDeviceDriver* pDriver) { |
| 712 if (m_commandIndex == m_commands.count()) |
| 713 return; |
| 714 if (m_commandIndex < m_commands.count()) |
| 715 pDriver->SkiaCanvas()->restore(); |
| 716 int index = m_commands.count() - 1; |
| 717 if (m_commandIndex == index && m_commands[index] == Clip::kSave) |
| 718 return; |
| 719 for (; index > m_commandIndex; --index) { |
| 720 if (m_commands[index] == Clip::kSave) |
| 721 pDriver->SkiaCanvas()->restore(); |
| 722 } |
| 723 |
| 724 if (m_commandIndex > 0) |
| 725 pDriver->SkiaCanvas()->save(); |
| 726 while (index > 0 && m_commands[index] != Clip::kSave) |
| 727 --index; |
| 728 while (++index < m_commandIndex) { |
| 729 SkASSERT(m_commands[index] == Clip::kPath); |
| 730 pDriver->SkiaCanvas()->clipPath(m_clips[index], SkRegion::kIntersect_Op, |
| 731 true); |
| 732 } |
| 733 m_commands.setCount(m_commandIndex); |
| 734 m_clips.resize_back(m_commandIndex); |
| 735 } |
| 736 |
| 737 // returns true if caller should apply command to skia canvas |
| 738 bool ClipSave(CFX_SkiaDeviceDriver* pDriver) { |
| 739 if (m_debugDisable) |
| 740 return false; |
| 741 int count = m_commands.count(); |
| 742 if (m_commandIndex < count) { |
| 743 if (m_commands[m_commandIndex] == Clip::kSave) { |
| 744 ++m_commandIndex; |
| 745 return true; |
| 746 } |
| 747 FlushCommands(pDriver); |
| 748 } |
| 749 Flush(pDriver); |
| 750 m_commands.push(Clip::kSave); |
| 751 ++m_commandIndex; |
| 752 m_clips.push_back(m_skEmptyPath); |
| 753 return false; |
| 754 } |
| 755 |
| 756 bool ClipRestore(CFX_SkiaDeviceDriver* pDriver) { |
| 757 if (m_debugDisable) |
| 758 return false; |
| 759 while (m_commandIndex > 0) { |
| 760 if (m_commands[--m_commandIndex] == Clip::kSave) |
| 761 return true; |
| 762 } |
| 763 Flush(pDriver); |
| 764 return false; |
| 765 } |
| 766 |
| 767 bool DrawChanged(const CFX_Matrix* pMatrix, |
| 768 const CFX_GraphStateData* pState, |
| 769 uint32_t fill_color, |
| 770 uint32_t stroke_color, |
| 771 int fill_mode, |
| 772 int blend_type) { |
| 773 return MatrixChanged(pMatrix, m_drawMatrix) || |
| 774 StateChanged(pState, m_drawState) || fill_color != m_fillColor || |
| 775 stroke_color != m_strokeColor || |
| 776 ((fill_mode & 3) == FXFILL_ALTERNATE) != |
| 777 (m_skPath.getFillType() == SkPath::kEvenOdd_FillType) || |
| 778 blend_type != m_blendType; |
| 779 } |
| 780 |
| 781 bool FontChanged(CFX_Font* pFont, |
| 782 CFX_FontCache* pCache, |
| 783 const CFX_Matrix* pMatrix, |
| 784 FX_FLOAT font_size, |
| 785 uint32_t color) { |
| 786 return pFont != m_pFont || pCache != m_pCache || |
| 787 MatrixChanged(pMatrix, m_drawMatrix) || font_size != m_fontSize || |
| 788 color != m_fillColor; |
| 789 } |
| 790 |
| 791 bool MatrixChanged(const CFX_Matrix* pMatrix, const CFX_Matrix& refMatrix) { |
| 792 return pMatrix->a != refMatrix.a || pMatrix->b != refMatrix.b || |
| 793 pMatrix->c != refMatrix.c || pMatrix->d != refMatrix.d; |
| 794 } |
| 795 |
| 796 bool StateChanged(const CFX_GraphStateData* pState, |
| 797 const CFX_GraphStateData& refState) { |
| 798 return pState->m_LineWidth != refState.m_LineWidth || |
| 799 pState->m_LineCap != refState.m_LineCap || |
| 800 pState->m_LineJoin != refState.m_LineJoin || |
| 801 pState->m_MiterLimit != refState.m_MiterLimit || |
| 802 DashChanged(pState, refState); |
| 803 } |
| 804 |
| 805 bool DashChanged(const CFX_GraphStateData* pState, |
| 806 const CFX_GraphStateData& refState) { |
| 807 if (!pState->m_DashArray && !refState.m_DashArray) |
| 808 return false; |
| 809 if (!pState->m_DashArray || !refState.m_DashArray) |
| 810 return true; |
| 811 if (pState->m_DashPhase != refState.m_DashPhase || |
| 812 pState->m_DashCount != refState.m_DashCount) { |
| 813 return true; |
| 814 } |
| 815 for (int index = 0; index < pState->m_DashCount; ++index) { |
| 816 if (pState->m_DashArray[index] != refState.m_DashArray[index]) |
| 817 return false; |
| 818 } |
| 819 return true; |
| 820 } |
| 821 |
| 822 void Flush(CFX_SkiaDeviceDriver* pDriver) { |
| 823 if (m_drawPath) |
| 824 FlushPath(pDriver); |
| 825 if (m_drawText) |
| 826 FlushText(pDriver); |
| 827 } |
| 828 |
| 829 #ifdef SK_DEBUG |
| 830 void Dump(const CFX_SkiaDeviceDriver* pDriver) const { |
| 831 SkDebugf("\n\nSkia Save Count %d:\n", pDriver->m_pCanvas->getSaveCount()); |
| 832 pDriver->m_pCanvas->getClipStack()->dump(); |
| 833 SkDebugf("Cache:\n"); |
| 834 for (int index = 0; index < m_commands.count(); ++index) { |
| 835 SkDebugf("%s ", m_commandIndex == index ? "-->" : " "); |
| 836 switch (m_commands[index]) { |
| 837 case Clip::kSave: |
| 838 SkDebugf("Save\n"); |
| 839 break; |
| 840 case Clip::kPath: |
| 841 m_clips[index].dump(); |
| 842 break; |
| 843 default: |
| 844 SkDebugf("unknown\n"); |
| 845 } |
| 846 } |
| 847 if (m_commandIndex == m_commands.count()) |
| 848 SkDebugf("-->\n"); |
| 849 } |
| 850 #endif |
| 851 |
| 852 private: |
| 853 SkTArray<SkPath> m_clips; // stack of clips that may be reused |
| 854 SkTDArray<Clip> m_commands; // stack of clip-related commands |
| 855 SkTDArray<SkPoint> m_positions; // accumulator for text positions |
| 856 SkTDArray<uint16_t> m_glyphs; // accumulator for text glyphs |
| 857 SkPath m_skPath; // accumulator for path contours |
| 858 SkPath m_skEmptyPath; // used as placehold in the clips array |
| 859 CFX_Matrix m_drawMatrix; |
| 860 CFX_GraphStateData m_clipState; |
| 861 CFX_GraphStateData m_drawState; |
| 862 CFX_Matrix m_clipMatrix; |
| 863 CFX_Font* m_pFont; |
| 864 CFX_FontCache* m_pCache; |
| 865 FX_FLOAT m_fontSize; |
| 866 uint32_t m_fillColor; |
| 867 uint32_t m_strokeColor; |
| 868 int m_blendType; |
| 869 int m_commandIndex; // active position in clip command stack |
| 870 bool m_drawText; |
| 871 bool m_drawPath; |
| 872 bool m_fillPath; |
| 873 bool m_debugDisable; // turn off cache for debugging |
| 874 }; |
| 875 |
479 // convert a stroking path to scanlines | 876 // convert a stroking path to scanlines |
480 void CFX_SkiaDeviceDriver::PaintStroke(SkPaint* spaint, | 877 void CFX_SkiaDeviceDriver::PaintStroke(SkPaint* spaint, |
481 const CFX_GraphStateData* pGraphState, | 878 const CFX_GraphStateData* pGraphState, |
482 const SkMatrix& matrix) { | 879 const SkMatrix& matrix) { |
483 SkPaint::Cap cap; | 880 SkPaint::Cap cap; |
484 switch (pGraphState->m_LineCap) { | 881 switch (pGraphState->m_LineCap) { |
485 case CFX_GraphStateData::LineCapRound: | 882 case CFX_GraphStateData::LineCapRound: |
486 cap = SkPaint::kRound_Cap; | 883 cap = SkPaint::kRound_Cap; |
487 break; | 884 break; |
488 case CFX_GraphStateData::LineCapSquare: | 885 case CFX_GraphStateData::LineCapSquare: |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 spaint->setStrokeJoin(join); | 938 spaint->setStrokeJoin(join); |
542 } | 939 } |
543 | 940 |
544 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap, | 941 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap, |
545 FX_BOOL bRgbByteOrder, | 942 FX_BOOL bRgbByteOrder, |
546 CFX_DIBitmap* pOriDevice, | 943 CFX_DIBitmap* pOriDevice, |
547 FX_BOOL bGroupKnockout) | 944 FX_BOOL bGroupKnockout) |
548 : m_pBitmap(pBitmap), | 945 : m_pBitmap(pBitmap), |
549 m_pOriDevice(pOriDevice), | 946 m_pOriDevice(pOriDevice), |
550 m_pRecorder(nullptr), | 947 m_pRecorder(nullptr), |
| 948 m_pCache(new SkiaState), |
551 m_bRgbByteOrder(bRgbByteOrder), | 949 m_bRgbByteOrder(bRgbByteOrder), |
552 m_bGroupKnockout(bGroupKnockout) { | 950 m_bGroupKnockout(bGroupKnockout) { |
553 SkBitmap skBitmap; | 951 SkBitmap skBitmap; |
554 SkASSERT(pBitmap->GetBPP() == 8 || pBitmap->GetBPP() == 32); | 952 SkASSERT(pBitmap->GetBPP() == 8 || pBitmap->GetBPP() == 32); |
555 SkImageInfo imageInfo = SkImageInfo::Make( | 953 SkImageInfo imageInfo = SkImageInfo::Make( |
556 pBitmap->GetWidth(), pBitmap->GetHeight(), | 954 pBitmap->GetWidth(), pBitmap->GetHeight(), |
557 pBitmap->GetBPP() == 8 ? kAlpha_8_SkColorType : kN32_SkColorType, | 955 pBitmap->GetBPP() == 8 ? kAlpha_8_SkColorType : kN32_SkColorType, |
558 kOpaque_SkAlphaType); | 956 kOpaque_SkAlphaType); |
559 skBitmap.installPixels(imageInfo, pBitmap->GetBuffer(), pBitmap->GetPitch(), | 957 skBitmap.installPixels(imageInfo, pBitmap->GetBuffer(), pBitmap->GetPitch(), |
560 nullptr, /* to do : set color table */ | 958 nullptr, /* to do : set color table */ |
561 nullptr, nullptr); | 959 nullptr, nullptr); |
562 m_pCanvas = new SkCanvas(skBitmap); | 960 m_pCanvas = new SkCanvas(skBitmap); |
563 if (m_bGroupKnockout) | 961 if (m_bGroupKnockout) |
564 SkDebugf(""); // FIXME(caryclark) suppress 'm_bGroupKnockout is unused' | 962 SkDebugf(""); // FIXME(caryclark) suppress 'm_bGroupKnockout is unused' |
565 } | 963 } |
566 | 964 |
567 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(int size_x, int size_y) | 965 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(int size_x, int size_y) |
568 : m_pBitmap(nullptr), | 966 : m_pBitmap(nullptr), |
569 m_pOriDevice(nullptr), | 967 m_pOriDevice(nullptr), |
570 m_pRecorder(new SkPictureRecorder), | 968 m_pRecorder(new SkPictureRecorder), |
| 969 m_pCache(new SkiaState), |
571 m_bRgbByteOrder(FALSE), | 970 m_bRgbByteOrder(FALSE), |
572 m_bGroupKnockout(FALSE) { | 971 m_bGroupKnockout(FALSE) { |
573 m_pRecorder->beginRecording(SkIntToScalar(size_x), SkIntToScalar(size_y)); | 972 m_pRecorder->beginRecording(SkIntToScalar(size_x), SkIntToScalar(size_y)); |
574 m_pCanvas = m_pRecorder->getRecordingCanvas(); | 973 m_pCanvas = m_pRecorder->getRecordingCanvas(); |
575 } | 974 } |
576 | 975 |
577 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(SkPictureRecorder* recorder) | 976 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(SkPictureRecorder* recorder) |
578 : m_pBitmap(nullptr), | 977 : m_pBitmap(nullptr), |
579 m_pOriDevice(nullptr), | 978 m_pOriDevice(nullptr), |
580 m_pRecorder(recorder), | 979 m_pRecorder(recorder), |
| 980 m_pCache(new SkiaState), |
581 m_bRgbByteOrder(FALSE), | 981 m_bRgbByteOrder(FALSE), |
582 m_bGroupKnockout(FALSE) { | 982 m_bGroupKnockout(FALSE) { |
583 m_pCanvas = m_pRecorder->getRecordingCanvas(); | 983 m_pCanvas = m_pRecorder->getRecordingCanvas(); |
584 } | 984 } |
585 | 985 |
586 CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() { | 986 CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() { |
| 987 Flush(); |
587 if (!m_pRecorder) | 988 if (!m_pRecorder) |
588 delete m_pCanvas; | 989 delete m_pCanvas; |
589 } | 990 } |
590 | 991 |
| 992 void CFX_SkiaDeviceDriver::Flush() { |
| 993 m_pCache->Flush(this); |
| 994 m_pCache->FlushCommands(this); |
| 995 } |
| 996 |
591 FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, | 997 FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, |
592 const FXTEXT_CHARPOS* pCharPos, | 998 const FXTEXT_CHARPOS* pCharPos, |
593 CFX_Font* pFont, | 999 CFX_Font* pFont, |
594 CFX_FontCache* pCache, | 1000 CFX_FontCache* pCache, |
595 const CFX_Matrix* pObject2Device, | 1001 const CFX_Matrix* pObject2Device, |
596 FX_FLOAT font_size, | 1002 FX_FLOAT font_size, |
597 uint32_t color) { | 1003 uint32_t color) { |
| 1004 if (m_pCache->DrawText(nChars, pCharPos, pFont, pCache, pObject2Device, |
| 1005 font_size, color, this)) { |
| 1006 return TRUE; |
| 1007 } |
598 sk_sp<SkTypeface> typeface(SkSafeRef(pCache->GetDeviceCache(pFont))); | 1008 sk_sp<SkTypeface> typeface(SkSafeRef(pCache->GetDeviceCache(pFont))); |
599 SkPaint paint; | 1009 SkPaint paint; |
600 paint.setAntiAlias(true); | 1010 paint.setAntiAlias(true); |
601 paint.setColor(color); | 1011 paint.setColor(color); |
602 paint.setTypeface(typeface); | 1012 paint.setTypeface(typeface); |
603 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 1013 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
604 paint.setTextSize(font_size); | 1014 paint.setTextSize(font_size); |
605 paint.setSubpixelText(true); | 1015 paint.setSubpixelText(true); |
606 m_pCanvas->save(); | 1016 m_pCanvas->save(); |
607 SkMatrix skMatrix = ToFlippedSkMatrix(*pObject2Device); | 1017 SkMatrix skMatrix = ToFlippedSkMatrix(*pObject2Device); |
(...skipping 27 matching lines...) Expand all Loading... |
635 return 0; | 1045 return 0; |
636 case FXDC_RENDER_CAPS: | 1046 case FXDC_RENDER_CAPS: |
637 return FXRC_GET_BITS | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | | 1047 return FXRC_GET_BITS | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | |
638 FXRC_BLEND_MODE | FXRC_SOFT_CLIP | FXRC_ALPHA_OUTPUT | | 1048 FXRC_BLEND_MODE | FXRC_SOFT_CLIP | FXRC_ALPHA_OUTPUT | |
639 FXRC_FILLSTROKE_PATH | FXRC_SHADING; | 1049 FXRC_FILLSTROKE_PATH | FXRC_SHADING; |
640 } | 1050 } |
641 return 0; | 1051 return 0; |
642 } | 1052 } |
643 | 1053 |
644 void CFX_SkiaDeviceDriver::SaveState() { | 1054 void CFX_SkiaDeviceDriver::SaveState() { |
645 m_pCanvas->save(); | 1055 if (!m_pCache->ClipSave(this)) |
| 1056 m_pCanvas->save(); |
646 } | 1057 } |
647 | 1058 |
648 void CFX_SkiaDeviceDriver::RestoreState(bool bKeepSaved) { | 1059 void CFX_SkiaDeviceDriver::RestoreState(bool bKeepSaved) { |
649 m_pCanvas->restore(); | 1060 if (!m_pCache->ClipRestore(this)) |
| 1061 m_pCanvas->restore(); |
650 if (bKeepSaved) | 1062 if (bKeepSaved) |
651 m_pCanvas->save(); | 1063 SaveState(); |
652 } | 1064 } |
653 | 1065 |
654 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill( | 1066 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill( |
655 const CFX_PathData* pPathData, // path info | 1067 const CFX_PathData* pPathData, // path info |
656 const CFX_Matrix* pObject2Device, // flips object's y-axis | 1068 const CFX_Matrix* pObject2Device, // flips object's y-axis |
657 int fill_mode // fill mode, WINDING or ALTERNATE | 1069 int fill_mode // fill mode, WINDING or ALTERNATE |
658 ) { | 1070 ) { |
| 1071 CFX_Matrix identity; |
| 1072 const CFX_Matrix* deviceMatrix = pObject2Device ? pObject2Device : &identity; |
| 1073 if (m_pCache->SetClipFill(pPathData, deviceMatrix, fill_mode, this)) |
| 1074 return TRUE; |
659 if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { | 1075 if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { |
660 CFX_FloatRect rectf; | 1076 CFX_FloatRect rectf; |
661 if (pPathData->IsRect(pObject2Device, &rectf)) { | 1077 if (pPathData->IsRect(deviceMatrix, &rectf)) { |
662 rectf.Intersect( | 1078 rectf.Intersect( |
663 CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), | 1079 CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), |
664 (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); | 1080 (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); |
665 // note that PDF's y-axis goes up; Skia's y-axis goes down | 1081 // note that PDF's y-axis goes up; Skia's y-axis goes down |
666 SkRect skClipRect = | 1082 SkRect skClipRect = |
667 SkRect::MakeLTRB(rectf.left, rectf.bottom, rectf.right, rectf.top); | 1083 SkRect::MakeLTRB(rectf.left, rectf.bottom, rectf.right, rectf.top); |
668 DebugDrawSkiaClipRect(m_pCanvas, skClipRect); | 1084 DebugDrawSkiaClipRect(m_pCanvas, skClipRect); |
669 m_pCanvas->clipRect(skClipRect); | 1085 m_pCanvas->clipRect(skClipRect, SkRegion::kIntersect_Op, true); |
670 return TRUE; | 1086 return TRUE; |
671 } | 1087 } |
672 } | 1088 } |
673 SkPath skClipPath = BuildPath(pPathData); | 1089 SkPath skClipPath = BuildPath(pPathData); |
674 skClipPath.setFillType((fill_mode & 3) == FXFILL_WINDING | 1090 skClipPath.setFillType((fill_mode & 3) == FXFILL_ALTERNATE |
675 ? SkPath::kWinding_FillType | 1091 ? SkPath::kEvenOdd_FillType |
676 : SkPath::kEvenOdd_FillType); | 1092 : SkPath::kWinding_FillType); |
677 SkMatrix skMatrix = ToSkMatrix(*pObject2Device); | 1093 SkMatrix skMatrix = ToSkMatrix(*deviceMatrix); |
678 skClipPath.transform(skMatrix); | 1094 skClipPath.transform(skMatrix); |
679 DebugShowSkiaPath(skClipPath); | 1095 DebugShowSkiaPath(skClipPath); |
680 DebugDrawSkiaClipPath(m_pCanvas, skClipPath); | 1096 DebugDrawSkiaClipPath(m_pCanvas, skClipPath); |
681 m_pCanvas->clipPath(skClipPath); | 1097 m_pCanvas->clipPath(skClipPath, SkRegion::kIntersect_Op, true); |
682 | 1098 |
683 return TRUE; | 1099 return TRUE; |
684 } | 1100 } |
685 | 1101 |
686 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathStroke( | 1102 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathStroke( |
687 const CFX_PathData* pPathData, // path info | 1103 const CFX_PathData* pPathData, // path info |
688 const CFX_Matrix* pObject2Device, // optional transformation | 1104 const CFX_Matrix* pObject2Device, // optional transformation |
689 const CFX_GraphStateData* pGraphState // graphic state, for pen attributes | 1105 const CFX_GraphStateData* pGraphState // graphic state, for pen attributes |
690 ) { | 1106 ) { |
| 1107 if (m_pCache->SetClipStroke(pPathData, pObject2Device, pGraphState, this)) |
| 1108 return TRUE; |
691 // build path data | 1109 // build path data |
692 SkPath skPath = BuildPath(pPathData); | 1110 SkPath skPath = BuildPath(pPathData); |
693 skPath.setFillType(SkPath::kWinding_FillType); | |
694 | |
695 SkMatrix skMatrix = ToSkMatrix(*pObject2Device); | 1111 SkMatrix skMatrix = ToSkMatrix(*pObject2Device); |
696 SkPaint spaint; | 1112 SkPaint skPaint; |
697 PaintStroke(&spaint, pGraphState, skMatrix); | 1113 PaintStroke(&skPaint, pGraphState, skMatrix); |
698 SkPath dst_path; | 1114 SkPath dst_path; |
699 spaint.getFillPath(skPath, &dst_path); | 1115 skPaint.getFillPath(skPath, &dst_path); |
700 dst_path.transform(skMatrix); | 1116 dst_path.transform(skMatrix); |
701 DebugDrawSkiaClipPath(m_pCanvas, dst_path); | 1117 DebugDrawSkiaClipPath(m_pCanvas, dst_path); |
702 m_pCanvas->clipPath(dst_path); | 1118 m_pCanvas->clipPath(dst_path, SkRegion::kIntersect_Op, true); |
703 return TRUE; | 1119 return TRUE; |
704 } | 1120 } |
705 | 1121 |
706 FX_BOOL CFX_SkiaDeviceDriver::DrawPath( | 1122 FX_BOOL CFX_SkiaDeviceDriver::DrawPath( |
707 const CFX_PathData* pPathData, // path info | 1123 const CFX_PathData* pPathData, // path info |
708 const CFX_Matrix* pObject2Device, // optional transformation | 1124 const CFX_Matrix* pObject2Device, // optional transformation |
709 const CFX_GraphStateData* pGraphState, // graphic state, for pen attributes | 1125 const CFX_GraphStateData* pGraphState, // graphic state, for pen attributes |
710 uint32_t fill_color, // fill color | 1126 uint32_t fill_color, // fill color |
711 uint32_t stroke_color, // stroke color | 1127 uint32_t stroke_color, // stroke color |
712 int fill_mode, // fill mode, WINDING or ALTERNATE. 0 for not filled | 1128 int fill_mode, // fill mode, WINDING or ALTERNATE. 0 for not filled |
713 int blend_type) { | 1129 int blend_type) { |
| 1130 if (m_pCache->DrawPath(pPathData, pObject2Device, pGraphState, fill_color, |
| 1131 stroke_color, fill_mode, blend_type, this)) { |
| 1132 return TRUE; |
| 1133 } |
714 SkIRect rect; | 1134 SkIRect rect; |
715 rect.set(0, 0, GetDeviceCaps(FXDC_PIXEL_WIDTH), | 1135 rect.set(0, 0, GetDeviceCaps(FXDC_PIXEL_WIDTH), |
716 GetDeviceCaps(FXDC_PIXEL_HEIGHT)); | 1136 GetDeviceCaps(FXDC_PIXEL_HEIGHT)); |
717 SkMatrix skMatrix; | 1137 SkMatrix skMatrix; |
718 if (pObject2Device) | 1138 if (pObject2Device) |
719 skMatrix = ToSkMatrix(*pObject2Device); | 1139 skMatrix = ToSkMatrix(*pObject2Device); |
720 else | 1140 else |
721 skMatrix.setIdentity(); | 1141 skMatrix.setIdentity(); |
722 SkPaint skPaint; | 1142 SkPaint skPaint; |
723 skPaint.setAntiAlias(true); | 1143 skPaint.setAntiAlias(true); |
724 int stroke_alpha = FXARGB_A(stroke_color); | 1144 int stroke_alpha = FXARGB_A(stroke_color); |
725 if (pGraphState && stroke_alpha) | 1145 if (pGraphState && stroke_alpha) |
726 PaintStroke(&skPaint, pGraphState, skMatrix); | 1146 PaintStroke(&skPaint, pGraphState, skMatrix); |
727 SkPath skPath = BuildPath(pPathData); | 1147 SkPath skPath = BuildPath(pPathData); |
728 m_pCanvas->save(); | 1148 m_pCanvas->save(); |
729 m_pCanvas->concat(skMatrix); | 1149 m_pCanvas->concat(skMatrix); |
730 if ((fill_mode & 3) && fill_color) { | 1150 if ((fill_mode & 3) && fill_color) { |
731 skPath.setFillType((fill_mode & 3) == FXFILL_WINDING | 1151 skPath.setFillType((fill_mode & 3) == FXFILL_ALTERNATE |
732 ? SkPath::kWinding_FillType | 1152 ? SkPath::kEvenOdd_FillType |
733 : SkPath::kEvenOdd_FillType); | 1153 : SkPath::kWinding_FillType); |
734 SkPath strokePath; | 1154 SkPath strokePath; |
735 const SkPath* fillPath = &skPath; | 1155 const SkPath* fillPath = &skPath; |
736 if (pGraphState && stroke_alpha) { | 1156 if (pGraphState && stroke_alpha) { |
737 SkAlpha fillA = SkColorGetA(fill_color); | 1157 SkAlpha fillA = SkColorGetA(fill_color); |
738 SkAlpha strokeA = SkColorGetA(stroke_color); | 1158 SkAlpha strokeA = SkColorGetA(stroke_color); |
739 if (fillA && fillA < 0xFF && strokeA && strokeA < 0xFF) { | 1159 if (fillA && fillA < 0xFF && strokeA && strokeA < 0xFF) { |
740 skPaint.getFillPath(skPath, &strokePath); | 1160 skPaint.getFillPath(skPath, &strokePath); |
741 if (Op(skPath, strokePath, SkPathOp::kDifference_SkPathOp, | 1161 if (Op(skPath, strokePath, SkPathOp::kDifference_SkPathOp, |
742 &strokePath)) { | 1162 &strokePath)) { |
743 fillPath = &strokePath; | 1163 fillPath = &strokePath; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 skClip.transform(skMatrix); | 1322 skClip.transform(skMatrix); |
903 } | 1323 } |
904 SkMatrix inverse; | 1324 SkMatrix inverse; |
905 if (!skMatrix.invert(&inverse)) | 1325 if (!skMatrix.invert(&inverse)) |
906 return false; | 1326 return false; |
907 skPath.addRect(skRect); | 1327 skPath.addRect(skRect); |
908 skPath.transform(inverse); | 1328 skPath.transform(inverse); |
909 } | 1329 } |
910 m_pCanvas->save(); | 1330 m_pCanvas->save(); |
911 if (!skClip.isEmpty()) | 1331 if (!skClip.isEmpty()) |
912 m_pCanvas->clipPath(skClip); | 1332 m_pCanvas->clipPath(skClip, SkRegion::kIntersect_Op, true); |
913 m_pCanvas->concat(skMatrix); | 1333 m_pCanvas->concat(skMatrix); |
914 m_pCanvas->drawPath(skPath, paint); | 1334 m_pCanvas->drawPath(skPath, paint); |
915 m_pCanvas->restore(); | 1335 m_pCanvas->restore(); |
916 return true; | 1336 return true; |
917 } | 1337 } |
918 | 1338 |
919 uint8_t* CFX_SkiaDeviceDriver::GetBuffer() const { | 1339 uint8_t* CFX_SkiaDeviceDriver::GetBuffer() const { |
920 return m_pBitmap->GetBuffer(); | 1340 return m_pBitmap->GetBuffer(); |
921 } | 1341 } |
922 | 1342 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 uint32_t flags, | 1413 uint32_t flags, |
994 int blend_type) { | 1414 int blend_type) { |
995 if (!m_pBitmap->GetBuffer()) | 1415 if (!m_pBitmap->GetBuffer()) |
996 return TRUE; | 1416 return TRUE; |
997 CFX_Matrix m(dest_width, 0, 0, -dest_height, dest_left, | 1417 CFX_Matrix m(dest_width, 0, 0, -dest_height, dest_left, |
998 dest_top + dest_height); | 1418 dest_top + dest_height); |
999 | 1419 |
1000 m_pCanvas->save(); | 1420 m_pCanvas->save(); |
1001 SkRect skClipRect = SkRect::MakeLTRB(pClipRect->left, pClipRect->bottom, | 1421 SkRect skClipRect = SkRect::MakeLTRB(pClipRect->left, pClipRect->bottom, |
1002 pClipRect->right, pClipRect->top); | 1422 pClipRect->right, pClipRect->top); |
1003 m_pCanvas->clipRect(skClipRect); | 1423 m_pCanvas->clipRect(skClipRect, SkRegion::kIntersect_Op, true); |
1004 void* dummy; | 1424 void* dummy; |
1005 FX_BOOL result = StartDIBits(pSource, 0xFF, argb, &m, 0, dummy, blend_type); | 1425 FX_BOOL result = StartDIBits(pSource, 0xFF, argb, &m, 0, dummy, blend_type); |
1006 m_pCanvas->restore(); | 1426 m_pCanvas->restore(); |
1007 | 1427 |
1008 return result; | 1428 return result; |
1009 } | 1429 } |
1010 | 1430 |
1011 FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, | 1431 FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, |
1012 int bitmap_alpha, | 1432 int bitmap_alpha, |
1013 uint32_t argb, | 1433 uint32_t argb, |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1118 SkImageInfo unpremultipliedInfo = | 1538 SkImageInfo unpremultipliedInfo = |
1119 SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType); | 1539 SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType); |
1120 SkPixmap unpremultiplied(unpremultipliedInfo, buffer, rowBytes); | 1540 SkPixmap unpremultiplied(unpremultipliedInfo, buffer, rowBytes); |
1121 SkImageInfo premultipliedInfo = | 1541 SkImageInfo premultipliedInfo = |
1122 SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType); | 1542 SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType); |
1123 SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes); | 1543 SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes); |
1124 unpremultiplied.readPixels(premultiplied); | 1544 unpremultiplied.readPixels(premultiplied); |
1125 DebugVerifyBitmapIsPreMultiplied(buffer, width, height); | 1545 DebugVerifyBitmapIsPreMultiplied(buffer, width, height); |
1126 } | 1546 } |
1127 | 1547 |
| 1548 void CFX_SkiaDeviceDriver::Dump() const { |
| 1549 #ifdef SK_DEBUG |
| 1550 if (m_pCache) |
| 1551 m_pCache->Dump(this); |
| 1552 #endif |
| 1553 } |
| 1554 |
1128 CFX_FxgeDevice::CFX_FxgeDevice() { | 1555 CFX_FxgeDevice::CFX_FxgeDevice() { |
1129 m_bOwnedBitmap = FALSE; | 1556 m_bOwnedBitmap = FALSE; |
1130 } | 1557 } |
1131 | 1558 |
1132 SkPictureRecorder* CFX_FxgeDevice::CreateRecorder(int size_x, int size_y) { | 1559 SkPictureRecorder* CFX_FxgeDevice::CreateRecorder(int size_x, int size_y) { |
1133 CFX_SkiaDeviceDriver* skDriver = new CFX_SkiaDeviceDriver(size_x, size_y); | 1560 CFX_SkiaDeviceDriver* skDriver = new CFX_SkiaDeviceDriver(size_x, size_y); |
1134 SetDeviceDriver(skDriver); | 1561 SetDeviceDriver(skDriver); |
1135 return skDriver->GetRecorder(); | 1562 return skDriver->GetRecorder(); |
1136 } | 1563 } |
1137 | 1564 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1174 CFX_FxgeDevice::~CFX_FxgeDevice() { | 1601 CFX_FxgeDevice::~CFX_FxgeDevice() { |
1175 if (m_bOwnedBitmap && GetBitmap()) | 1602 if (m_bOwnedBitmap && GetBitmap()) |
1176 delete GetBitmap(); | 1603 delete GetBitmap(); |
1177 } | 1604 } |
1178 | 1605 |
1179 void CFX_FxgeDevice::PreMultiply() { | 1606 void CFX_FxgeDevice::PreMultiply() { |
1180 (static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()))->PreMultiply(); | 1607 (static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()))->PreMultiply(); |
1181 } | 1608 } |
1182 | 1609 |
1183 #endif | 1610 #endif |
OLD | NEW |