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