Flutter Engine
The Flutter Engine
Functions
SkPDFGraphicStackState.cpp File Reference
#include "src/pdf/SkPDFGraphicStackState.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkRect.h"
#include "include/core/SkStream.h"
#include "include/pathops/SkPathOps.h"
#include "include/private/base/SkAssert.h"
#include "src/pdf/SkPDFUtils.h"
#include "src/utils/SkClipStackUtils.h"

Go to the source code of this file.

Functions

static void emit_pdf_color (SkColor4f color, SkWStream *result)
 
static SkRect rect_intersect (SkRect u, SkRect v)
 
static bool is_rect (const SkClipStack &clipStack, const SkRect &bounds, SkRect *dst)
 
static bool is_complex_clip (const SkClipStack &stack)
 
template<typename F >
static void apply_clip (const SkClipStack &stack, const SkRect &outerBounds, F fn)
 
static void append_clip_path (const SkPath &clipPath, SkWStream *wStream)
 
static void append_clip (const SkClipStack &clipStack, const SkIRect &bounds, SkWStream *wStream)
 

Function Documentation

◆ append_clip()

static void append_clip ( const SkClipStack clipStack,
const SkIRect bounds,
SkWStream wStream 
)
static

Definition at line 114 of file SkPDFGraphicStackState.cpp.

116 {
117 // The bounds are slightly outset to ensure this is correct in the
118 // face of floating-point accuracy and possible SkRegion bitmap
119 // approximations.
120 SkRect outsetBounds = SkRect::Make(bounds.makeOutset(1, 1));
121
122 SkRect clipStackRect;
123 if (is_rect(clipStack, outsetBounds, &clipStackRect)) {
124 SkPDFUtils::AppendRectangle(clipStackRect, wStream);
125 wStream->writeText("W* n\n");
126 return;
127 }
128
129 if (is_complex_clip(clipStack)) {
131 SkClipStack_AsPath(clipStack, &clipPath);
132 if (Op(clipPath, SkPath::Rect(outsetBounds), kIntersect_SkPathOp, &clipPath)) {
133 append_clip_path(clipPath, wStream);
134 }
135 // If Op() fails (pathological case; e.g. input values are
136 // extremely large or NaN), emit no clip at all.
137 } else {
138 apply_clip(clipStack, outsetBounds, [wStream](const SkPath& path) {
139 append_clip_path(path, wStream);
140 });
141 }
142}
void SkClipStack_AsPath(const SkClipStack &cs, SkPath *path)
static void apply_clip(const SkClipStack &stack, const SkRect &outerBounds, F fn)
static bool is_rect(const SkClipStack &clipStack, const SkRect &bounds, SkRect *dst)
static bool is_complex_clip(const SkClipStack &stack)
static void append_clip_path(const SkPath &clipPath, SkWStream *wStream)
@ kIntersect_SkPathOp
intersect the two paths
Definition: SkPathOps.h:24
Definition: SkPath.h:59
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
Definition: SkPath.cpp:3586
bool writeText(const char text[])
Definition: SkStream.h:247
void AppendRectangle(const SkRect &rect, SkWStream *content)
Definition: SkPDFUtils.cpp:118
Optional< SkRect > bounds
Definition: SkRecords.h:189
clipPath(r.path, r.opAA.op(), r.opAA.aa())) DRAW(ClipRRect
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669

◆ append_clip_path()

static void append_clip_path ( const SkPath clipPath,
SkWStream wStream 
)
static

Definition at line 102 of file SkPDFGraphicStackState.cpp.

102 {
104 SkPathFillType clipFill = clipPath.getFillType();
107 if (clipFill == SkPathFillType::kEvenOdd) {
108 wStream->writeText("W* n\n");
109 } else {
110 wStream->writeText("W n\n");
111 }
112}
#define NOT_IMPLEMENTED(condition, assertion)
Definition: SkPDFUtils.h:51
SkPathFillType
Definition: SkPathTypes.h:11
@ kFill_Style
set to fill geometry
Definition: SkPaint.h:193
void EmitPath(const SkPath &path, SkPaint::Style paintStyle, bool doConsumeDegerates, SkWStream *content, SkScalar tolerance=0.25f)
Definition: SkPDFUtils.cpp:132

◆ apply_clip()

template<typename F >
static void apply_clip ( const SkClipStack stack,
const SkRect outerBounds,
F  fn 
)
static

Definition at line 74 of file SkPDFGraphicStackState.cpp.

74 {
75 // assumes clipstack is not complex.
76 constexpr SkRect kHuge{-30000, -30000, 30000, 30000};
78 SkRect bounds = outerBounds;
79 while (const SkClipStack::Element* element = iter.next()) {
80 SkPath operand;
81 element->asDeviceSpacePath(&operand);
82 SkPathOp op;
83 switch (element->getOp()) {
86 default: SkASSERT(false); return;
87 }
88 if (op == kDifference_SkPathOp ||
89 operand.isInverseFillType() ||
90 !kHuge.contains(operand.getBounds()))
91 {
92 Op(SkPath::Rect(bounds), operand, op, &operand);
93 }
94 SkASSERT(!operand.isInverseFillType());
95 fn(operand);
96 if (!bounds.intersect(operand.getBounds())) {
97 return; // return early;
98 }
99 }
100}
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkPathOp
Definition: SkPathOps.h:22
@ kDifference_SkPathOp
subtract the op path from the first path
Definition: SkPathOps.h:23
bool isInverseFillType() const
Definition: SkPath.h:244
const SkRect & getBounds() const
Definition: SkPath.cpp:430

◆ emit_pdf_color()

static void emit_pdf_color ( SkColor4f  color,
SkWStream result 
)
static

Definition at line 17 of file SkPDFGraphicStackState.cpp.

17 {
18 SkASSERT(color.fA == 1); // We handle alpha elsewhere.
20 result->writeText(" ");
22 result->writeText(" ");
24 result->writeText(" ");
25}
DlColor color
GAsyncResult * result
void AppendColorComponentF(float value, SkWStream *wStream)
Definition: SkPDFUtils.h:92

◆ is_complex_clip()

static bool is_complex_clip ( const SkClipStack stack)
static

Definition at line 61 of file SkPDFGraphicStackState.cpp.

61 {
63 while (const SkClipStack::Element* element = iter.next()) {
64 if (element->isReplaceOp() ||
65 (element->getOp() != SkClipOp::kDifference &&
66 element->getOp() != SkClipOp::kIntersect)) {
67 return true;
68 }
69 }
70 return false;
71}

◆ is_rect()

static bool is_rect ( const SkClipStack clipStack,
const SkRect bounds,
SkRect dst 
)
static

Definition at line 34 of file SkPDFGraphicStackState.cpp.

34 {
35 SkRect currentClip = bounds;
37 while (const SkClipStack::Element* element = iter.next()) {
38 SkRect elementRect{0, 0, 0, 0};
39 switch (element->getDeviceSpaceType()) {
41 break;
43 elementRect = element->getDeviceSpaceRect();
44 break;
45 default:
46 return false;
47 }
48 if (element->isReplaceOp()) {
49 currentClip = rect_intersect(bounds, elementRect);
50 } else if (element->getOp() == SkClipOp::kIntersect) {
51 currentClip = rect_intersect(currentClip, elementRect);
52 } else {
53 return false;
54 }
55 }
56 *dst = currentClip;
57 return true;
58}
static SkRect rect_intersect(SkRect u, SkRect v)
@ kEmpty
This element makes the clip empty (regardless of previous elements).
@ kRect
This element combines a device space round-rect with the current clip.
dst
Definition: cp.py:12

◆ rect_intersect()

static SkRect rect_intersect ( SkRect  u,
SkRect  v 
)
static

Definition at line 27 of file SkPDFGraphicStackState.cpp.

27 {
28 if (u.isEmpty() || v.isEmpty()) { return {0, 0, 0, 0}; }
29 return u.intersect(v) ? u : SkRect{0, 0, 0, 0};
30}
bool intersect(const SkRect &r)
Definition: SkRect.cpp:114
bool isEmpty() const
Definition: SkRect.h:693