Chromium Code Reviews| 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 |