Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Functions
SkPDFGraphicStackState.cpp File Reference
#include "src/pdf/SkPDFGraphicStackState.h"
#include "include/core/SkStream.h"
#include "include/pathops/SkPathOps.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 108 of file SkPDFGraphicStackState.cpp.

110 {
111 // The bounds are slightly outset to ensure this is correct in the
112 // face of floating-point accuracy and possible SkRegion bitmap
113 // approximations.
114 SkRect outsetBounds = SkRect::Make(bounds.makeOutset(1, 1));
115
116 SkRect clipStackRect;
117 if (is_rect(clipStack, outsetBounds, &clipStackRect)) {
118 SkPDFUtils::AppendRectangle(clipStackRect, wStream);
119 wStream->writeText("W* n\n");
120 return;
121 }
122
123 if (is_complex_clip(clipStack)) {
125 SkClipStack_AsPath(clipStack, &clipPath);
126 if (Op(clipPath, SkPath::Rect(outsetBounds), kIntersect_SkPathOp, &clipPath)) {
127 append_clip_path(clipPath, wStream);
128 }
129 // If Op() fails (pathological case; e.g. input values are
130 // extremely large or NaN), emit no clip at all.
131 } else {
132 apply_clip(clipStack, outsetBounds, [wStream](const SkPath& path) {
133 append_clip_path(path, wStream);
134 });
135 }
136}
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
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
Definition SkPath.cpp:3518
bool writeText(const char text[])
Definition SkStream.h:247
void AppendRectangle(const SkRect &rect, SkWStream *content)
Optional< SkRect > bounds
Definition SkRecords.h:189
clipPath(r.path, r.opAA.op(), r.opAA.aa())) DRAW(ClipRRect
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 96 of file SkPDFGraphicStackState.cpp.

96 {
98 SkPathFillType clipFill = clipPath.getFillType();
101 if (clipFill == SkPathFillType::kEvenOdd) {
102 wStream->writeText("W* n\n");
103 } else {
104 wStream->writeText("W n\n");
105 }
106}
#define NOT_IMPLEMENTED(condition, assert)
Definition SkPDFUtils.h:39
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)

◆ apply_clip()

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

Definition at line 68 of file SkPDFGraphicStackState.cpp.

68 {
69 // assumes clipstack is not complex.
70 constexpr SkRect kHuge{-30000, -30000, 30000, 30000};
72 SkRect bounds = outerBounds;
73 while (const SkClipStack::Element* element = iter.next()) {
74 SkPath operand;
75 element->asDeviceSpacePath(&operand);
76 SkPathOp op;
77 switch (element->getOp()) {
80 default: SkASSERT(false); return;
81 }
82 if (op == kDifference_SkPathOp ||
83 operand.isInverseFillType() ||
84 !kHuge.contains(operand.getBounds()))
85 {
86 Op(SkPath::Rect(bounds), operand, op, &operand);
87 }
88 SkASSERT(!operand.isInverseFillType());
89 fn(operand);
90 if (!bounds.intersect(operand.getBounds())) {
91 return; // return early;
92 }
93 }
94}
#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:420

◆ emit_pdf_color()

static void emit_pdf_color ( SkColor4f  color,
SkWStream result 
)
static

Definition at line 11 of file SkPDFGraphicStackState.cpp.

11 {
12 SkASSERT(color.fA == 1); // We handle alpha elsewhere.
14 result->writeText(" ");
16 result->writeText(" ");
18 result->writeText(" ");
19}
SkColor4f color
GAsyncResult * result
void AppendColorComponentF(float value, SkWStream *wStream)
Definition SkPDFUtils.h:80

◆ is_complex_clip()

static bool is_complex_clip ( const SkClipStack stack)
static

Definition at line 55 of file SkPDFGraphicStackState.cpp.

55 {
57 while (const SkClipStack::Element* element = iter.next()) {
58 if (element->isReplaceOp() ||
59 (element->getOp() != SkClipOp::kDifference &&
60 element->getOp() != SkClipOp::kIntersect)) {
61 return true;
62 }
63 }
64 return false;
65}

◆ is_rect()

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

Definition at line 28 of file SkPDFGraphicStackState.cpp.

28 {
29 SkRect currentClip = bounds;
31 while (const SkClipStack::Element* element = iter.next()) {
32 SkRect elementRect{0, 0, 0, 0};
33 switch (element->getDeviceSpaceType()) {
35 break;
37 elementRect = element->getDeviceSpaceRect();
38 break;
39 default:
40 return false;
41 }
42 if (element->isReplaceOp()) {
43 currentClip = rect_intersect(bounds, elementRect);
44 } else if (element->getOp() == SkClipOp::kIntersect) {
45 currentClip = rect_intersect(currentClip, elementRect);
46 } else {
47 return false;
48 }
49 }
50 *dst = currentClip;
51 return true;
52}
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 21 of file SkPDFGraphicStackState.cpp.

21 {
22 if (u.isEmpty() || v.isEmpty()) { return {0, 0, 0, 0}; }
23 return u.intersect(v) ? u : SkRect{0, 0, 0, 0};
24}
bool intersect(const SkRect &r)
Definition SkRect.cpp:114
bool isEmpty() const
Definition SkRect.h:693