52 matrix->setSinCos(vec.
fY, vec.
fX);
53 matrix->preScale(mag, mag);
54 matrix->postTranslate(pts[0].fX, pts[0].fY);
90 multiplier[i] = kColorScale * (curColor[i] - prevColor[i]) / range;
99 dupInput[i] = dupInput[i + 1] || multiplier[i + 1] != 0;
102 if (!dupInput[0] && multiplier[0] == 0) {
103 result->writeText(
"pop ");
109 if (dupInput[i] && multiplier[i] != 0) {
110 result->writeText(
"dup ");
113 if (multiplier[i] == 0) {
117 if (multiplier[i] != 1) {
119 result->writeText(
" mul ");
121 if (prevColor[i] != 0) {
123 result->writeText(
" add ");
128 result->writeText(
"exch ");
137 size_t rangeEndIndex = rangeEnds[rangeEnds.
size() - 1];
144 result->writeText(
"dup dup 0 gt exch ");
146 result->writeText(
" le and {\n");
149 result->writeText(
"dup ");
151 result->writeText(
" le {\n");
157 if (rangeEnds.
size() == 1) {
159 size_t rangeBeginIndex = rangeEndIndex - 1;
160 SkScalar rangeBegin =
info.fColorOffsets[rangeBeginIndex];
162 result->writeText(
" sub ");
164 info.fColors[rangeBeginIndex],
info.fColors[rangeEndIndex],
result);
167 size_t loCount = rangeEnds.
size() / 2;
177 result->writeText(
"0} if\n");
181 result->writeText(
"} ifelse\n");
243 result->writeText(
"dup 0 le {pop ");
249 result->writeText(
" 0} if\n");
253 size_t rangeEndsCount = 0;
254 for (
int i = 1; i <
info.fColorCount; ++i) {
260 bool constantColorBothSides =
261 eqIgnoringAlpha(
info.fColors[i-1],
info.fColors[i]) &&
262 i !=
info.fColorCount-1 &&
263 eqIgnoringAlpha(
info.fColors[i],
info.fColors[i+1]);
266 bool degenerateRange =
info.fColorOffsets[i-1] ==
info.fColorOffsets[i];
268 if (!degenerateRange && !constantColorBothSides) {
269 rangeEnds[rangeEndsCount] = i;
278 result->writeText(
"0 gt {");
284 result->writeText(
"} if\n");
292 c0->appendColorComponent(color1[0]);
293 c0->appendColorComponent(color1[1]);
294 c0->appendColorComponent(color1[2]);
295 retval->insertObject(
"C0", std::move(c0));
298 c1->appendColorComponent(color2[0]);
299 c1->appendColorComponent(color2[1]);
300 c1->appendColorComponent(color2[2]);
301 retval->insertObject(
"C1", std::move(c1));
305 retval->insertInt(
"FunctionType", 2);
306 retval->insertScalar(
"N", 1.0f);
315 int colorCount =
info.fColorCount;
316 std::vector<SkColor> colors(
info.fColors,
info.fColors + colorCount);
317 std::vector<SkScalar> colorOffsets(
info.fColorOffsets,
info.fColorOffsets + colorCount);
320 while (i < colorCount - 1) {
322 if (colorOffsets[i - 1] > colorOffsets[i]) {
323 colorOffsets[i] = colorOffsets[i - 1];
327 if ((colorOffsets[i - 1] == colorOffsets[i]) && (colorOffsets[i] == colorOffsets[i + 1])) {
329 colors.erase(colors.begin() + i);
330 colorOffsets.erase(colorOffsets.begin() + i);
336 for (i = 1; i < colorCount - 1; i++) {
337 if (colorOffsets[i - 1] == colorOffsets[i]) {
338 colorOffsets[i] += 0.00001f;
342 if (colorOffsets[i - 1] == colorOffsets[i]) {
343 colorOffsets[i - 1] -= 0.00001f;
348 for (
int idx = 0; idx < colorCount; idx++) {
363 retval->insertInt(
"FunctionType", 3);
365 for (
int idx = 1; idx < colorCount; idx++) {
367 bounds->appendScalar(colorOffsets[idx-1]);
371 encode->appendScalar(1.0f);
376 retval->insertObject(
"Encode", std::move(
encode));
377 retval->insertObject(
"Bounds", std::move(bounds));
378 retval->insertObject(
"Functions", std::move(functions));
386 result->writeText(
"dup truncate sub\n");
387 result->writeText(
"dup 0 le {1 add} if\n");
408 "{1 exch sub} if\n");
440 code->writeText(
" dup ");
442 code->writeText(
" mul "
445 code->writeText(
" mul ");
447 code->writeText(
" add "
521 function->writeText(
" add -2 mul dup dup mul\n");
524 function->writeText(
"4 2 roll dup mul exch dup mul add ");
526 function->writeText(
" sub dup 4 1 roll\n");
534 function->writeText(
"pop pop div neg dup ");
543 function->writeText(
"0 lt {pop false} {true} ifelse\n");
552 function->writeText(
" mul sub dup\n");
559 function->writeText(
"sqrt exch dup 0 lt {exch -1 mul} if");
560 function->writeText(
" add -0.5 mul dup\n");
567 function->writeText(
"3 1 roll div\n");
570 function->writeText(
"2 copy gt {exch} if\n");
580 function->writeText(
" 0 gt {exch pop true}\n");
590 function->writeText(
"0 le {pop false} {true} ifelse\n");
594 function->writeText(
"} {pop pop pop false} ifelse\n");
603 function->writeText(
"} {0 0 0} ifelse }");
609 function->writeText(
"{exch atan 360 div\n");
621 SkScalar subtractRadii = fabs(r1 - r2);
622 if (fabs(distance - subtractRadii) < 0.002f) {
658 perspectiveInverse->
setAll(one, zero, zero,
660 -p0/p2, -p1/p2, 1/p2);
662 affine->
setAll(sx - p0 * tx / p2, kx - p1 * tx / p2, tx / p2,
663 ky - p0 * ty / p2, sy - p1 * ty / p2, ty / p2,
670 std::unique_ptr<SkPDFArray> domain,
671 std::unique_ptr<SkPDFObject> range,
674 dict->insertInt(
"FunctionType", 4);
675 dict->insertObject(
"Domain", std::move(domain));
676 dict->insertObject(
"Range", std::move(range));
687 bool doStitchFunctions = (
state.fType == SkShaderBase::GradientType::kLinear ||
688 state.fType == SkShaderBase::GradientType::kRadial ||
689 state.fType == SkShaderBase::GradientType::kConical) &&
693 int32_t shadingType = 1;
699 if (doStitchFunctions) {
701 shadingType = (
state.fType == SkShaderBase::GradientType::kLinear) ? 2 : 3;
705 extend->appendBool(
true);
706 extend->appendBool(
true);
707 pdfShader->insertObject(
"Extend", std::move(extend));
709 std::unique_ptr<SkPDFArray> coords;
710 if (
state.fType == SkShaderBase::GradientType::kConical) {
723 }
else if (
state.fType == SkShaderBase::GradientType::kRadial) {
740 pdfShader->insertObject(
"Coords", std::move(coords));
744 transformPoints[0] =
info.fPoint[0];
745 transformPoints[1] =
info.fPoint[1];
746 switch (
state.fType) {
747 case SkShaderBase::GradientType::kLinear:
749 case SkShaderBase::GradientType::kRadial:
750 transformPoints[1] = transformPoints[0];
751 transformPoints[1].
fX +=
info.fRadius[0];
753 case SkShaderBase::GradientType::kConical: {
754 transformPoints[1] = transformPoints[0];
758 case SkShaderBase::GradientType::kSweep:
759 transformPoints[1] = transformPoints[0];
784 &finalMatrix, &perspectiveInverseOnly)) {
798 if (
state.fType == SkShaderBase::GradientType::kConical) {
800 if (!mapperMatrix.
invert(&inverseMapperMatrix)) {
807 switch (
state.fType) {
808 case SkShaderBase::GradientType::kLinear:
809 linearCode(infoCopy, perspectiveInverseOnly, &functionCode);
811 case SkShaderBase::GradientType::kRadial:
812 radialCode(infoCopy, perspectiveInverseOnly, &functionCode);
814 case SkShaderBase::GradientType::kConical:
817 case SkShaderBase::GradientType::kSweep:
818 sweepCode(infoCopy, perspectiveInverseOnly, &functionCode);
823 pdfShader->insertObject(
827 std::unique_ptr<SkPDFArray> rangeObject =
SkPDFMakeArray(0, 1, 0, 1, 0, 1);
828 pdfShader->insertRef(
"Function",
830 std::move(rangeObject), doc));
833 pdfShader->insertInt(
"ShadingType", shadingType);
834 pdfShader->insertName(
"ColorSpace",
"DeviceRGB");
837 pdfFunctionShader.
insertInt(
"PatternType", 2);
839 pdfFunctionShader.
insertObject(
"Shading", std::move(pdfShader));
840 return doc->
emit(pdfFunctionShader);
849 std::vector<SkPDFIndirectReference> patternShaders;
851 patternShaders.push_back(functionShader);
853 std::vector<SkPDFIndirectReference> graphicStates;
855 graphicStates.push_back(gState);
858 std::move(patternShaders),
859 std::vector<SkPDFIndirectReference>(),
860 std::vector<SkPDFIndirectReference>());
876 return content.detachAsStream();
881 for (
int i = 0; i <
key.fInfo.fColorCount; i++) {
916 luminosityState.
fHash =
hash(luminosityState);
927 std::move(resources),
931 alphaMask,
false, SkPDFGraphicState::kLuminosity_SMaskMode, doc);
955 std::unique_ptr<SkStreamAsset> colorStream =
957 std::unique_ptr<SkPDFDict> alphaFunctionShader =
SkPDFMakeDict();
960 return SkPDFStreamOut(std::move(alphaFunctionShader), std::move(colorStream), doc);
968 {0,
nullptr,
nullptr, {{0, 0}, {0, 0}}, {0, 0},
SkTileMode::kClamp, 0},
979 key.fInfo.fColors =
key.fColors.get();
980 key.fInfo.fColorOffsets =
key.fStops.get();
1000 gradientPatternMap.set(std::move(
key), pdfShader);
static SkM44 inv(const SkM44 &m)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
#define SkColorGetR(color)
#define SkColorGetG(color)
static constexpr SkColor SkColorSetA(SkColor c, U8CPU a)
constexpr SkAlpha SK_AlphaOPAQUE
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
#define SkColorGetA(color)
#define SkColorGetB(color)
static void encode(uint8_t output[16], const uint32_t input[4])
static std::unique_ptr< SkPDFDict > get_gradient_resource_dict(SkPDFIndirectReference functionShader, SkPDFIndirectReference gState)
static SkPDFGradientShader::Key clone_key(const SkPDFGradientShader::Key &k)
static SkPDFIndirectReference make_function_shader(SkPDFDocument *doc, const SkPDFGradientShader::Key &state)
static void gradient_function_code(const SkShaderBase::GradientInfo &info, SkDynamicMemoryWStream *result)
static void radialCode(const SkShaderBase::GradientInfo &info, const SkMatrix &perspectiveRemover, SkDynamicMemoryWStream *function)
static void tileModeCode(SkTileMode mode, SkDynamicMemoryWStream *result)
static std::unique_ptr< SkPDFDict > createInterpolationFunction(const ColorTuple &color1, const ColorTuple &color2)
static std::unique_ptr< SkPDFDict > gradientStitchCode(const SkShaderBase::GradientInfo &info)
static void write_gradient_ranges(const SkShaderBase::GradientInfo &info, SkSpan< size_t > rangeEnds, bool top, bool first, SkDynamicMemoryWStream *result)
static void sweepCode(const SkShaderBase::GradientInfo &info, const SkMatrix &perspectiveRemover, SkDynamicMemoryWStream *function)
static SkPDFIndirectReference make_alpha_function_shader(SkPDFDocument *doc, const SkPDFGradientShader::Key &state)
static void linearCode(const SkShaderBase::GradientInfo &info, const SkMatrix &perspectiveRemover, SkDynamicMemoryWStream *function)
static SkPDFIndirectReference create_smask_graphic_state(SkPDFDocument *doc, const SkPDFGradientShader::Key &state)
static void interpolate_color_code(SkScalar range, SkColor beginColor, SkColor endColor, SkDynamicMemoryWStream *result)
static SkPDFIndirectReference find_pdf_shader(SkPDFDocument *doc, SkPDFGradientShader::Key key, bool keyHasAlpha)
static bool split_perspective(const SkMatrix in, SkMatrix *affine, SkMatrix *perspectiveInverse)
static bool gradient_has_alpha(const SkPDFGradientShader::Key &key)
static const int kColorComponents
static void apply_perspective_to_coordinates(const SkMatrix &inversePerspectiveMatrix, SkDynamicMemoryWStream *code)
static uint32_t hash(const SkShaderBase::GradientInfo &v)
static void twoPointConicalCode(const SkShaderBase::GradientInfo &info, const SkMatrix &perspectiveRemover, SkDynamicMemoryWStream *function)
static SkPDFIndirectReference make_ps_function(std::unique_ptr< SkStreamAsset > psCode, std::unique_ptr< SkPDFArray > domain, std::unique_ptr< SkPDFObject > range, SkPDFDocument *doc)
uint8_t ColorTuple[kColorComponents]
static void unit_to_points_matrix(const SkPoint pts[2], SkMatrix *matrix)
static std::unique_ptr< SkStreamAsset > create_pattern_fill_content(int gsIndex, int patternIndex, SkRect &bounds)
static void FixUpRadius(const SkPoint &p1, SkScalar &r1, const SkPoint &p2, SkScalar &r2)
static SkPDFGradientShader::Key make_key(const SkShader *shader, const SkMatrix &canvasTransform, const SkIRect &bbox)
std::unique_ptr< SkPDFDict > SkPDFMakeResourceDict(const std::vector< SkPDFIndirectReference > &graphicStateResources, const std::vector< SkPDFIndirectReference > &shaderResources, const std::vector< SkPDFIndirectReference > &xObjectResources, const std::vector< SkPDFIndirectReference > &fontResources)
SkPDFIndirectReference SkPDFStreamOut(std::unique_ptr< SkPDFDict > dict, std::unique_ptr< SkStreamAsset > content, SkPDFDocument *doc, SkPDFSteamCompressionEnabled compress)
static std::unique_ptr< SkPDFDict > SkPDFMakeDict(const char *type=nullptr)
static std::unique_ptr< SkPDFArray > SkPDFMakeArray(Args... args)
#define SkScalarInvert(x)
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
SkShaderBase * as_SB(SkShader *shader)
std::unique_ptr< SkStreamAsset > detachAsStream()
SkScalar mapRadius(SkScalar radius) const
static constexpr int kMScaleX
horizontal scale factor
static constexpr int kMTransY
vertical translation
static constexpr int kMPersp1
input y perspective factor
SkMatrix & setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar persp0, SkScalar persp1, SkScalar persp2)
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
bool invert(SkMatrix *inverse) const
static const SkMatrix & I()
SkMatrix & preConcat(const SkMatrix &other)
static constexpr int kMPersp0
input x perspective factor
static constexpr int kMPersp2
perspective bias
static constexpr int kMTransX
horizontal translation
bool hasPerspective() const
static constexpr int kMSkewY
vertical skew factor
static constexpr int kMScaleY
vertical scale factor
static constexpr int kMSkewX
horizontal skew factor
void insertObject(const char key[], std::unique_ptr< SkPDFObject > &&)
void insertInt(const char key[], int32_t value)
SkPDFIndirectReference emit(const SkPDFObject &, SkPDFIndirectReference)
skia_private::THashMap< SkPDFGradientShader::Key, SkPDFIndirectReference, SkPDFGradientShader::KeyHash > fGradientPatternMap
@ kFill_Style
set to fill geometry
virtual GradientType asGradient(GradientInfo *info=nullptr, SkMatrix *localMatrix=nullptr) const
constexpr SkSpan< T > subspan(size_t offset) const
constexpr bool empty() const
constexpr size_t size() const
static const uint8_t buffer[]
Dart_NativeFunction function
union flutter::testing::@2838::KeyboardChange::@76 content
uint32_t Hash32(const void *data, size_t bytes, uint32_t seed)
SkPDFIndirectReference Make(SkPDFDocument *doc, SkShader *shader, const SkMatrix &matrix, const SkIRect &surfaceBBox)
SkPDFIndirectReference GetSMaskGraphicState(SkPDFIndirectReference sMask, bool invert, SkPDFSMaskMode sMaskMode, SkPDFDocument *doc)
void ApplyGraphicState(int objectIndex, SkWStream *content)
void PopulateTilingPatternDict(SkPDFDict *pattern, SkRect &bbox, std::unique_ptr< SkPDFDict > resources, const SkMatrix &matrix)
void AppendColorComponent(uint8_t value, SkWStream *wStream)
std::unique_ptr< SkPDFArray > MatrixToArray(const SkMatrix &matrix)
void AppendRectangle(const SkRect &rect, SkWStream *content)
void PaintPath(SkPaint::Style style, SkPathFillType fill, SkWStream *content)
void AppendScalar(SkScalar value, SkWStream *stream)
SkMatrix GetShaderLocalMatrix(const SkShader *shader)
void ApplyPattern(int objectIndex, SkWStream *content)
bool InverseTransformBBox(const SkMatrix &matrix, SkRect *bbox)
std::unique_ptr< SkPDFArray > RectToArray(const SkRect &rect)
SkShaderBase::GradientType fType
std::unique_ptr< SkScalar[]> fStops
SkMatrix fShaderTransform
std::unique_ptr< SkColor[]> fColors
SkShaderBase::GradientInfo fInfo
SkMatrix fCanvasTransform
static float Distance(const SkPoint &a, const SkPoint &b)
void scale(float scale, SkPoint *dst) const
constexpr float y() const
constexpr float x() const
static SkRect Make(const SkISize &size)
constexpr float left() const
constexpr float top() const
constexpr float right() const
void set(const SkIRect &src)
constexpr float bottom() const
uint32_t fGradientFlags
see SkGradientShader::Flags
SkPoint fPoint[2]
Type specific, see above.
SkColor * fColors
The colors in the gradient.
int fColorCount
In-out parameter, specifies passed size.
SkScalar fRadius[2]
Type specific, see above.
SkScalar * fColorOffsets
The unit offset for color transitions.