Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
ToolUtils.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "tools/ToolUtils.h"
9
17#include "include/core/SkFont.h"
23#include "include/core/SkPath.h"
27#include "include/core/SkPixelRef.h" // IWYU pragma: keep
41#include "src/core/SkFontPriv.h"
42#include "tools/SkMetaData.h"
43
44#include <cmath>
45#include <cstring>
46
47#ifdef SK_BUILD_FOR_WIN
49#endif
50
51using namespace skia_private;
52
53namespace ToolUtils {
54
55const char* alphatype_name(SkAlphaType at) {
56 switch (at) {
57 case kUnknown_SkAlphaType: return "Unknown";
58 case kOpaque_SkAlphaType: return "Opaque";
59 case kPremul_SkAlphaType: return "Premul";
60 case kUnpremul_SkAlphaType: return "Unpremul";
61 }
63}
64
65const char* colortype_name(SkColorType ct) {
66 switch (ct) {
67 case kUnknown_SkColorType: return "Unknown";
68 case kAlpha_8_SkColorType: return "Alpha_8";
69 case kA16_unorm_SkColorType: return "Alpha_16";
70 case kA16_float_SkColorType: return "A16_float";
71 case kRGB_565_SkColorType: return "RGB_565";
72 case kARGB_4444_SkColorType: return "ARGB_4444";
73 case kRGBA_8888_SkColorType: return "RGBA_8888";
74 case kSRGBA_8888_SkColorType: return "SRGBA_8888";
75 case kRGB_888x_SkColorType: return "RGB_888x";
76 case kBGRA_8888_SkColorType: return "BGRA_8888";
77 case kRGBA_1010102_SkColorType: return "RGBA_1010102";
78 case kBGRA_1010102_SkColorType: return "BGRA_1010102";
79 case kRGB_101010x_SkColorType: return "RGB_101010x";
80 case kBGR_101010x_SkColorType: return "BGR_101010x";
81 case kBGR_101010x_XR_SkColorType: return "BGR_101010x_XR";
82 case kRGBA_10x6_SkColorType: return "RGBA_10x6";
83 case kGray_8_SkColorType: return "Gray_8";
84 case kRGBA_F16Norm_SkColorType: return "RGBA_F16Norm";
85 case kRGBA_F16_SkColorType: return "RGBA_F16";
86 case kRGBA_F32_SkColorType: return "RGBA_F32";
87 case kR8G8_unorm_SkColorType: return "R8G8_unorm";
88 case kR16G16_unorm_SkColorType: return "R16G16_unorm";
89 case kR16G16_float_SkColorType: return "R16G16_float";
90 case kR16G16B16A16_unorm_SkColorType: return "R16G16B16A16_unorm";
91 case kR8_unorm_SkColorType: return "R8_unorm";
92 case kBGRA_10101010_XR_SkColorType: return "BGRA_10101010_XR";
93 }
95}
96
98 switch (ct) {
99 case kUnknown_SkColorType: return "Unknown";
100 case kAlpha_8_SkColorType: return "A8";
101 case kA16_unorm_SkColorType: return "A16";
102 case kA16_float_SkColorType: return "AF16";
103 case kRGB_565_SkColorType: return "565";
104 case kARGB_4444_SkColorType: return "4444";
105 case kRGBA_8888_SkColorType: return "8888";
106 case kSRGBA_8888_SkColorType: return "8888";
107 case kRGB_888x_SkColorType: return "888";
108 case kBGRA_8888_SkColorType: return "8888";
109 case kRGBA_1010102_SkColorType: return "1010102";
110 case kBGRA_1010102_SkColorType: return "1010102";
111 case kRGB_101010x_SkColorType: return "101010";
112 case kBGR_101010x_SkColorType: return "101010";
113 case kBGR_101010x_XR_SkColorType: return "101010";
114 case kBGRA_10101010_XR_SkColorType: return "10101010";
115 case kRGBA_10x6_SkColorType: return "10101010";
116 case kGray_8_SkColorType: return "G8";
117 case kRGBA_F16Norm_SkColorType: return "F16Norm";
118 case kRGBA_F16_SkColorType: return "F16";
119 case kRGBA_F32_SkColorType: return "F32";
120 case kR8G8_unorm_SkColorType: return "88";
121 case kR16G16_unorm_SkColorType: return "1616";
122 case kR16G16_float_SkColorType: return "F16F16";
123 case kR16G16B16A16_unorm_SkColorType: return "16161616";
124 case kR8_unorm_SkColorType: return "R8";
125 }
127}
128
129const char* tilemode_name(SkTileMode mode) {
130 switch (mode) {
131 case SkTileMode::kClamp: return "clamp";
132 case SkTileMode::kRepeat: return "repeat";
133 case SkTileMode::kMirror: return "mirror";
134 case SkTileMode::kDecal: return "decal";
135 }
137}
138
140 // Not a good idea to use this function for greyscale colors...
141 // it will add an obvious purple or green tint.
144
146 U16CPU color16 = SkPixel32ToPixel16(pmColor);
147 return SkPixel16ToColor(color16);
148}
149
151 SkBitmap bm;
153 bm.eraseColor(c1);
154 bm.eraseArea(SkIRect::MakeLTRB(0, 0, size, size), c2);
155 bm.eraseArea(SkIRect::MakeLTRB(size, size, 2 * size, 2 * size), c2);
157}
158
159SkBitmap create_checkerboard_bitmap(int w, int h, SkColor c1, SkColor c2, int checkSize) {
162 SkCanvas canvas(bitmap);
163
164 ToolUtils::draw_checkerboard(&canvas, c1, c2, checkSize);
165 return bitmap;
166}
167
168sk_sp<SkImage> create_checkerboard_image(int w, int h, SkColor c1, SkColor c2, int checkSize) {
170 ToolUtils::draw_checkerboard(surf->getCanvas(), c1, c2, checkSize);
171 return surf->makeImageSnapshot();
172}
173
174void draw_checkerboard(SkCanvas* canvas, SkColor c1, SkColor c2, int size) {
176 paint.setShader(create_checkerboard_shader(c1, c2, size));
177 paint.setBlendMode(SkBlendMode::kSrc);
178 canvas->drawPaint(paint);
179}
180
182 SkAlphaType at,
183 bool withMips,
184 const SkColor4f colors[6],
185 SkPixmap pixmaps[6],
186 std::unique_ptr<char[]>* mem) {
187
188 int levelSize = 32;
189 int numMipLevels = withMips ? 6 : 1;
190 size_t size = 0;
191 SkImageInfo ii[6];
192 size_t rowBytes[6];
193 for (int level = 0; level < numMipLevels; ++level) {
194 ii[level] = SkImageInfo::Make(levelSize, levelSize, ct, at);
195 rowBytes[level] = ii[level].minRowBytes();
196 // Make sure we test row bytes that aren't tight.
197 if (!(level % 2)) {
198 rowBytes[level] += (level + 1)*SkColorTypeBytesPerPixel(ii[level].colorType());
199 }
200 size += rowBytes[level]*ii[level].height();
201 levelSize /= 2;
202 }
203 mem->reset(new char[size]);
204 char* addr = mem->get();
205 for (int level = 0; level < numMipLevels; ++level) {
206 pixmaps[level].reset(ii[level], addr, rowBytes[level]);
207 addr += rowBytes[level]*ii[level].height();
208 pixmaps[level].erase(colors[level]);
209 }
210 return numMipLevels;
211}
212
214 const char* text,
215 size_t len,
216 SkTextEncoding encoding,
217 const SkFont& font,
218 SkScalar x,
219 SkScalar y) {
220 int count = font.countText(text, len, encoding);
221 if (count < 1) {
222 return;
223 }
224 auto run = builder->allocRun(font, count, x, y);
225 font.textToGlyphs(text, len, encoding, run.glyphs, count);
226}
227
229 const char* text,
230 const SkFont& font,
231 SkScalar x,
232 SkScalar y) {
233 add_to_text_blob_w_len(builder, text, strlen(text), SkTextEncoding::kUTF8, font, x, y);
234}
235
236void get_text_path(const SkFont& font,
237 const void* text,
238 size_t length,
239 SkTextEncoding encoding,
240 SkPath* dst,
241 const SkPoint pos[]) {
242 SkAutoToGlyphs atg(font, text, length, encoding);
243 const int count = atg.count();
244 AutoTArray<SkPoint> computedPos;
245 if (pos == nullptr) {
246 computedPos.reset(count);
247 font.getPos(atg.glyphs(), count, &computedPos[0]);
248 pos = computedPos.get();
249 }
250
251 struct Rec {
252 SkPath* fDst;
253 const SkPoint* fPos;
254 } rec = {dst, pos};
255 font.getPaths(atg.glyphs(),
256 atg.count(),
257 [](const SkPath* src, const SkMatrix& mx, void* ctx) {
258 Rec* rec = (Rec*)ctx;
259 if (src) {
260 SkMatrix tmp(mx);
261 tmp.postTranslate(rec->fPos->fX, rec->fPos->fY);
262 rec->fDst->addPath(*src, tmp);
263 }
264 rec->fPos += 1;
265 },
266 &rec);
267}
268
269SkPath make_star(const SkRect& bounds, int numPts, int step) {
270 SkASSERT(numPts != step);
271 SkPathBuilder builder;
272 builder.setFillType(SkPathFillType::kEvenOdd);
273 builder.moveTo(0, -1);
274 for (int i = 1; i < numPts; ++i) {
275 int idx = i * step % numPts;
276 SkScalar theta = idx * 2 * SK_ScalarPI / numPts + SK_ScalarPI / 2;
277 SkScalar x = SkScalarCos(theta);
278 SkScalar y = -SkScalarSin(theta);
279 builder.lineTo(x, y);
280 }
281 SkPath path = builder.detach();
282 path.transform(SkMatrix::RectToRect(path.getBounds(), bounds));
283 return path;
284}
285
286static inline void norm_to_rgb(SkBitmap* bm, int x, int y, const SkVector3& norm) {
287 SkASSERT(SkScalarNearlyEqual(norm.length(), 1.0f));
288 unsigned char r = static_cast<unsigned char>((0.5f * norm.fX + 0.5f) * 255);
289 unsigned char g = static_cast<unsigned char>((-0.5f * norm.fY + 0.5f) * 255);
290 unsigned char b = static_cast<unsigned char>((0.5f * norm.fZ + 0.5f) * 255);
291 *bm->getAddr32(x, y) = SkPackARGB32(0xFF, r, g, b);
292}
293
295 const SkPoint center =
296 SkPoint::Make(dst.fLeft + (dst.width() / 2.0f), dst.fTop + (dst.height() / 2.0f));
297 const SkPoint halfSize = SkPoint::Make(dst.width() / 2.0f, dst.height() / 2.0f);
298
299 SkVector3 norm;
300
301 for (int y = dst.fTop; y < dst.fBottom; ++y) {
302 for (int x = dst.fLeft; x < dst.fRight; ++x) {
303 norm.fX = (x + 0.5f - center.fX) / halfSize.fX;
304 norm.fY = (y + 0.5f - center.fY) / halfSize.fY;
305
306 SkScalar tmp = norm.fX * norm.fX + norm.fY * norm.fY;
307 if (tmp >= 1.0f) {
308 norm.set(0.0f, 0.0f, 1.0f);
309 } else {
310 norm.fZ = sqrtf(1.0f - tmp);
311 }
312
313 norm_to_rgb(bm, x, y, norm);
314 }
315 }
316}
317
319 const SkPoint center =
320 SkPoint::Make(dst.fLeft + (dst.width() / 2.0f), dst.fTop + (dst.height() / 2.0f));
321
322 SkIRect inner = dst;
323 inner.inset(dst.width() / 4, dst.height() / 4);
324
325 SkPoint3 norm;
330
331 for (int y = dst.fTop; y < dst.fBottom; ++y) {
332 for (int x = dst.fLeft; x < dst.fRight; ++x) {
333 if (inner.contains(x, y)) {
334 norm.set(0.0f, 0.0f, 1.0f);
335 } else {
336 SkScalar locX = x + 0.5f - center.fX;
337 SkScalar locY = y + 0.5f - center.fY;
338
339 if (locX >= 0.0f) {
340 if (locY > 0.0f) {
341 norm = locX >= locY ? right : down; // LR corner
342 } else {
343 norm = locX > -locY ? right : up; // UR corner
344 }
345 } else {
346 if (locY > 0.0f) {
347 norm = -locX > locY ? left : down; // LL corner
348 } else {
349 norm = locX > locY ? up : left; // UL corner
350 }
351 }
352 }
353
354 norm_to_rgb(bm, x, y, norm);
355 }
356 }
357}
358
360 const SkPoint center =
361 SkPoint::Make(dst.fLeft + (dst.width() / 2.0f), dst.fTop + (dst.height() / 2.0f));
362
363 static const SkScalar k1OverRoot3 = 0.5773502692f;
364
365 SkPoint3 norm;
366 const SkPoint3 leftUp = SkPoint3::Make(-k1OverRoot3, -k1OverRoot3, k1OverRoot3);
367 const SkPoint3 rightUp = SkPoint3::Make(k1OverRoot3, -k1OverRoot3, k1OverRoot3);
369
370 for (int y = dst.fTop; y < dst.fBottom; ++y) {
371 for (int x = dst.fLeft; x < dst.fRight; ++x) {
372 SkScalar locX = x + 0.5f - center.fX;
373 SkScalar locY = y + 0.5f - center.fY;
374
375 if (locX >= 0.0f) {
376 if (locY > 0.0f) {
377 norm = locX >= locY ? rightUp : down; // LR corner
378 } else {
379 norm = rightUp;
380 }
381 } else {
382 if (locY > 0.0f) {
383 norm = -locX > locY ? leftUp : down; // LL corner
384 } else {
385 norm = leftUp;
386 }
387 }
388
389 norm_to_rgb(bm, x, y, norm);
390 }
391 }
392}
393
394bool copy_to(SkBitmap* dst, SkColorType dstColorType, const SkBitmap& src) {
395 SkPixmap srcPM;
396 if (!src.peekPixels(&srcPM)) {
397 return false;
398 }
399
400 SkBitmap tmpDst;
401 SkImageInfo dstInfo = srcPM.info().makeColorType(dstColorType);
402 if (!tmpDst.setInfo(dstInfo)) {
403 return false;
404 }
405
406 if (!tmpDst.tryAllocPixels()) {
407 return false;
408 }
409
410 SkPixmap dstPM;
411 if (!tmpDst.peekPixels(&dstPM)) {
412 return false;
413 }
414
415 if (!srcPM.readPixels(dstPM)) {
416 return false;
417 }
418
419 dst->swap(tmpDst);
420 return true;
421}
422
423void copy_to_g8(SkBitmap* dst, const SkBitmap& src) {
424 SkASSERT(kBGRA_8888_SkColorType == src.colorType() ||
425 kRGBA_8888_SkColorType == src.colorType());
426
427 SkImageInfo grayInfo = src.info().makeColorType(kGray_8_SkColorType);
428 dst->allocPixels(grayInfo);
429 uint8_t* dst8 = (uint8_t*)dst->getPixels();
430 const uint32_t* src32 = (const uint32_t*)src.getPixels();
431
432 const int w = src.width();
433 const int h = src.height();
434 const bool isBGRA = (kBGRA_8888_SkColorType == src.colorType());
435 for (int y = 0; y < h; ++y) {
436 if (isBGRA) {
437 // BGRA
438 for (int x = 0; x < w; ++x) {
439 uint32_t s = src32[x];
440 dst8[x] = SkComputeLuminance((s >> 16) & 0xFF, (s >> 8) & 0xFF, s & 0xFF);
441 }
442 } else {
443 // RGBA
444 for (int x = 0; x < w; ++x) {
445 uint32_t s = src32[x];
446 dst8[x] = SkComputeLuminance(s & 0xFF, (s >> 8) & 0xFF, (s >> 16) & 0xFF);
447 }
448 }
449 src32 = (const uint32_t*)((const char*)src32 + src.rowBytes());
450 dst8 += dst->rowBytes();
451 }
452}
453
454//////////////////////////////////////////////////////////////////////////////////////////////
455
456bool equal_pixels(const SkPixmap& a, const SkPixmap& b) {
457 if (a.width() != b.width() || a.height() != b.height()) {
458 SkDebugf("[ToolUtils::equal_pixels] Dimensions do not match (%d x %d) != (%d x %d)\n",
459 a.width(), a.height(), b.width(), b.height());
460 return false;
461 }
462
463 if (a.colorType() != b.colorType()) {
464 SkDebugf("[ToolUtils::equal_pixels] colorType does not match %d != %d\n",
465 (int) a.colorType(), (int) b.colorType());
466 return false;
467 }
468
469 for (int y = 0; y < a.height(); ++y) {
470 const char* aptr = (const char*)a.addr(0, y);
471 const char* bptr = (const char*)b.addr(0, y);
472 if (0 != memcmp(aptr, bptr, a.width() * a.info().bytesPerPixel())) {
473 SkDebugf("[ToolUtils::equal_pixels] row %d does not match byte for byte\n", y);
474 return false;
475 }
476 }
477 return true;
478}
479
480bool equal_pixels(const SkBitmap& bm0, const SkBitmap& bm1) {
481 SkPixmap pm0, pm1;
482 if (!bm0.peekPixels(&pm0)) {
483 SkDebugf("Could not read pixels from A\n");
484 return false;
485 }
486 if (!bm1.peekPixels(&pm1)) {
487 SkDebugf("Could not read pixels from B\n");
488 return false;
489 }
490 return equal_pixels(pm0, pm1);
491}
492
493bool equal_pixels(const SkImage* a, const SkImage* b) {
496 // ensure that peekPixels will succeed
497 auto imga = a->makeRasterImage();
498 auto imgb = b->makeRasterImage();
499
500 SkPixmap pm0, pm1;
501 if (!imga->peekPixels(&pm0)) {
502 SkDebugf("Could not read pixels from A\n");
503 return false;
504 }
505 if (!imgb->peekPixels(&pm1)) {
506 SkDebugf("Could not read pixels from B\n");
507 return false;
508 }
509 return equal_pixels(pm0, pm1);
510}
511
513 const SkImageInfo& info,
514 const SkSurfaceProps* props) {
515 auto surf = canvas->makeSurface(info, props);
516 if (!surf) {
517 surf = SkSurfaces::Raster(info, props);
518 }
519 return surf;
520}
521
522VariationSliders::VariationSliders(SkTypeface* typeface,
523 SkFontArguments::VariationPosition variationPosition) {
524 if (!typeface) {
525 return;
526 }
527
528 int numAxes = typeface->getVariationDesignParameters(nullptr, 0);
529 if (numAxes < 0) {
530 return;
531 }
532
533 std::unique_ptr<SkFontParameters::Variation::Axis[]> copiedAxes =
534 std::make_unique<SkFontParameters::Variation::Axis[]>(numAxes);
535
536 numAxes = typeface->getVariationDesignParameters(copiedAxes.get(), numAxes);
537 if (numAxes < 0) {
538 return;
539 }
540
541 auto argVariationPositionOrDefault = [&variationPosition](SkFourByteTag tag,
542 SkScalar defaultValue) -> SkScalar {
543 for (int i = 0; i < variationPosition.coordinateCount; ++i) {
544 if (variationPosition.coordinates[i].axis == tag) {
545 return variationPosition.coordinates[i].value;
546 }
547 }
548 return defaultValue;
549 };
550
551 fAxisSliders.resize(numAxes);
552 fCoords = std::make_unique<SkFontArguments::VariationPosition::Coordinate[]>(numAxes);
553 for (int i = 0; i < numAxes; ++i) {
554 fAxisSliders[i].axis = copiedAxes[i];
555 fAxisSliders[i].current =
556 argVariationPositionOrDefault(copiedAxes[i].tag, copiedAxes[i].def);
557 fAxisSliders[i].name = tagToString(fAxisSliders[i].axis.tag);
558 fCoords[i] = { fAxisSliders[i].axis.tag, fAxisSliders[i].current };
559 }
560}
561
562/* static */
563SkString VariationSliders::tagToString(SkFourByteTag tag) {
564 char tagAsString[5];
565 tagAsString[4] = 0;
566 tagAsString[0] = (char)(uint8_t)(tag >> 24);
567 tagAsString[1] = (char)(uint8_t)(tag >> 16);
568 tagAsString[2] = (char)(uint8_t)(tag >> 8);
569 tagAsString[3] = (char)(uint8_t)(tag >> 0);
570 return SkString(tagAsString);
571}
572
573bool VariationSliders::writeControls(SkMetaData* controls) {
574 for (size_t i = 0; i < fAxisSliders.size(); ++i) {
575 SkScalar axisVars[kAxisVarsSize];
576
577 axisVars[0] = fAxisSliders[i].current;
578 axisVars[1] = fAxisSliders[i].axis.min;
579 axisVars[2] = fAxisSliders[i].axis.max;
580 controls->setScalars(fAxisSliders[i].name.c_str(), kAxisVarsSize, axisVars);
581 }
582 return true;
583}
584
585void VariationSliders::readControls(const SkMetaData& controls, bool* changed) {
586 for (size_t i = 0; i < fAxisSliders.size(); ++i) {
587 SkScalar axisVars[kAxisVarsSize] = {0};
588 int resultAxisVarsSize = 0;
590 tagToString(fAxisSliders[i].axis.tag).c_str(), &resultAxisVarsSize, axisVars));
591 SkASSERT_RELEASE(resultAxisVarsSize == kAxisVarsSize);
592 if (changed) {
593 *changed |= fAxisSliders[i].current != axisVars[0];
594 }
595 fAxisSliders[i].current = axisVars[0];
596 fCoords[i] = { fAxisSliders[i].axis.tag, fAxisSliders[i].current };
597 }
598}
599
602 fAxisSliders.size()};
603}
604
605////////////////////////////////////////////////////////////////////////////////////////////////////
606HilbertGenerator::HilbertGenerator(float desiredSize, float desiredLineWidth, int desiredDepth)
607 : fDesiredSize(desiredSize)
608 , fDesiredDepth(desiredDepth)
609 , fSegmentLength(fDesiredSize / ((0x1 << fDesiredDepth) - 1.0f))
610 , fDesiredLineWidth(desiredLineWidth)
611 , fActualBounds(SkRect::MakeEmpty())
612 , fCurPos(SkPoint::Make(0.0f, 0.0f))
613 , fCurDir(0)
614 , fExpectedLen(fSegmentLength * ((0x1 << (2*fDesiredDepth)) - 1.0f))
615 , fCurLen(0.0f) {
616}
617
619 this->recursiveDraw(canvas, /* curDepth= */ 0, /* turnLeft= */ true);
620
621 SkScalarNearlyEqual(fExpectedLen, fCurLen, 0.01f);
622 SkScalarNearlyEqual(fDesiredSize, fActualBounds.width(), 0.01f);
623 SkScalarNearlyEqual(fDesiredSize, fActualBounds.height(), 0.01f);
624}
625
626void HilbertGenerator::turn90(bool turnLeft) {
627 fCurDir += turnLeft ? 90 : -90;
628 if (fCurDir >= 360) {
629 fCurDir = 0;
630 } else if (fCurDir < 0) {
631 fCurDir = 270;
632 }
633
634 SkASSERT(fCurDir == 0 || fCurDir == 90 || fCurDir == 180 || fCurDir == 270);
635}
636
637void HilbertGenerator::line(SkCanvas* canvas) {
638
639 SkPoint before = fCurPos;
640
641 SkRect r;
642 switch (fCurDir) {
643 case 0:
644 r.fLeft = fCurPos.fX;
645 r.fTop = fCurPos.fY - fDesiredLineWidth / 2.0f;
646 r.fRight = fCurPos.fX + fSegmentLength;
647 r.fBottom = fCurPos.fY + fDesiredLineWidth / 2.0f;
648 fCurPos.fX += fSegmentLength;
649 break;
650 case 90:
651 r.fLeft = fCurPos.fX - fDesiredLineWidth / 2.0f;
652 r.fTop = fCurPos.fY - fSegmentLength;
653 r.fRight = fCurPos.fX + fDesiredLineWidth / 2.0f;
654 r.fBottom = fCurPos.fY;
655 fCurPos.fY -= fSegmentLength;
656 break;
657 case 180:
658 r.fLeft = fCurPos.fX - fSegmentLength;
659 r.fTop = fCurPos.fY - fDesiredLineWidth / 2.0f;
660 r.fRight = fCurPos.fX;
661 r.fBottom = fCurPos.fY + fDesiredLineWidth / 2.0f;
662 fCurPos.fX -= fSegmentLength;
663 break;
664 case 270:
665 r.fLeft = fCurPos.fX - fDesiredLineWidth / 2.0f;
666 r.fTop = fCurPos.fY;
667 r.fRight = fCurPos.fX + fDesiredLineWidth / 2.0f;
668 r.fBottom = fCurPos.fY + fSegmentLength;
669 fCurPos.fY += fSegmentLength;
670 break;
671 default:
672 return;
673 }
674
675 SkPoint pts[2] = { before, fCurPos };
676
677 SkColor4f colors[2] = {
678 this->getColor(fCurLen),
679 this->getColor(fCurLen + fSegmentLength),
680 };
681
682 fCurLen += fSegmentLength;
683 if (fActualBounds.isEmpty()) {
684 fActualBounds = r;
685 } else {
686 fActualBounds.join(r);
687 }
688
690 paint.setShader(SkGradientShader::MakeLinear(pts, colors, /* colorSpace= */ nullptr,
691 /* pos= */ nullptr, 2, SkTileMode::kClamp));
692 canvas->drawRect(r, paint);
693}
694
695void HilbertGenerator::recursiveDraw(SkCanvas* canvas, int curDepth, bool turnLeft) {
696 if (curDepth >= fDesiredDepth) {
697 return;
698 }
699
700 this->turn90(turnLeft);
701 this->recursiveDraw(canvas, curDepth + 1, !turnLeft);
702 this->line(canvas);
703 this->turn90(!turnLeft);
704 this->recursiveDraw(canvas, curDepth + 1, turnLeft);
705 this->line(canvas);
706 this->recursiveDraw(canvas, curDepth + 1, turnLeft);
707 this->turn90(!turnLeft);
708 this->line(canvas);
709 this->recursiveDraw(canvas, curDepth + 1, !turnLeft);
710 this->turn90(turnLeft);
711}
712
713SkColor4f HilbertGenerator::getColor(float curLen) {
714 static const SkColor4f kColors[] = {
722 };
723
724 static const float kStops[] = {
725 0.0f,
726 1.0f/6.0f,
727 2.0f/6.0f,
728 0.5f,
729 4.0f/6.0f,
730 5.0f/6.0f,
731 1.0f,
732 };
733 static_assert(std::size(kColors) == std::size(kStops));
734
735 float t = curLen / fExpectedLen;
736 if (t <= 0.0f) {
737 return kColors[0];
738 } else if (t >= 1.0f) {
739 return kColors[std::size(kColors)-1];
740 }
741
742 for (unsigned int i = 0; i < std::size(kColors)-1; ++i) {
743 if (kStops[i] <= t && t <= kStops[i+1]) {
744 t = (t - kStops[i]) / (kStops[i+1] - kStops[i]);
745 SkASSERT(0.0f <= t && t <= 1.0f);
746 return { kColors[i].fR * (1 - t) + kColors[i+1].fR * t,
747 kColors[i].fG * (1 - t) + kColors[i+1].fG * t,
748 kColors[i].fB * (1 - t) + kColors[i+1].fB * t,
749 kColors[i].fA * (1 - t) + kColors[i+1].fA * t };
750
751 }
752 }
753
754 return SkColors::kBlack;
755}
756
757void ExtractPathsFromSKP(const char filepath[], std::function<PathSniffCallback> callback) {
758 SkFILEStream stream(filepath);
759 if (!stream.isValid()) {
760 SkDebugf("ExtractPaths: invalid input file at \"%s\"\n", filepath);
761 return;
762 }
763
764 class PathSniffer : public SkCanvas {
765 public:
766 PathSniffer(std::function<PathSniffCallback> callback)
767 : SkCanvas(4096, 4096, nullptr)
768 , fPathSniffCallback(callback) {}
769 private:
770 void onDrawPath(const SkPath& path, const SkPaint& paint) override {
771 fPathSniffCallback(this->getTotalMatrix(), path, paint);
772 }
773 std::function<PathSniffCallback> fPathSniffCallback;
774 };
775
777 if (!skp) {
778 SkDebugf("ExtractPaths: couldn't load skp at \"%s\"\n", filepath);
779 return;
780 }
781 PathSniffer pathSniffer(callback);
782 skp->playback(&pathSniffer);
783}
784
785} // namespace ToolUtils
static int step(int x, SkScalar min, SkScalar max)
Definition BlurTest.cpp:215
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
int count
SkPoint pos
SkColor4f color
kUnpremul_SkAlphaType
SkAlphaType
Definition SkAlphaType.h:26
@ kUnknown_SkAlphaType
uninitialized
Definition SkAlphaType.h:27
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define SkUNREACHABLE
Definition SkAssert.h:135
#define SkASSERT_RELEASE(cond)
Definition SkAssert.h:100
#define SkASSERT(cond)
Definition SkAssert.h:116
unsigned U16CPU
Definition SkCPUTypes.h:23
static U8CPU SkComputeLuminance(U8CPU r, U8CPU g, U8CPU b)
static U16CPU SkPixel32ToPixel16(SkPMColor c)
static SkColor SkPixel16ToColor(U16CPU src)
static SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
SkColorType
Definition SkColorType.h:19
@ kR16G16B16A16_unorm_SkColorType
pixel with a little endian uint16_t for red, green, blue
Definition SkColorType.h:50
@ kRGBA_10x6_SkColorType
pixel with 10 used bits (most significant) followed by 6 unused
Definition SkColorType.h:33
@ kR8_unorm_SkColorType
Definition SkColorType.h:54
@ kBGR_101010x_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word
Definition SkColorType.h:30
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
Definition SkColorType.h:23
@ kR8G8_unorm_SkColorType
pixel with a uint8_t for red and green
Definition SkColorType.h:43
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition SkColorType.h:26
@ kA16_unorm_SkColorType
pixel with a little endian uint16_t for alpha
Definition SkColorType.h:48
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition SkColorType.h:38
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition SkColorType.h:21
@ kRGB_101010x_SkColorType
pixel with 10 bits each for red, green, blue; in 32-bit word
Definition SkColorType.h:29
@ kSRGBA_8888_SkColorType
Definition SkColorType.h:53
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition SkColorType.h:35
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition SkColorType.h:22
@ kBGRA_10101010_XR_SkColorType
pixel with 10 bits each for blue, green, red, alpha; in 64-bit word, extended range
Definition SkColorType.h:32
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
Definition SkColorType.h:25
@ kBGRA_1010102_SkColorType
10 bits for blue, green, red; 2 bits for alpha; in 32-bit word
Definition SkColorType.h:28
@ kA16_float_SkColorType
pixel with a half float for alpha
Definition SkColorType.h:45
@ kRGBA_F32_SkColorType
pixel using C float for red, green, blue, alpha; in 128-bit word
Definition SkColorType.h:40
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
Definition SkColorType.h:27
@ kBGR_101010x_XR_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word, extended range
Definition SkColorType.h:31
@ kR16G16_unorm_SkColorType
pixel with a little endian uint16_t for red and green
Definition SkColorType.h:49
@ kRGBA_F16Norm_SkColorType
pixel with half floats in [0,1] for red, green, blue, alpha;
Definition SkColorType.h:36
@ kUnknown_SkColorType
uninitialized
Definition SkColorType.h:20
@ kR16G16_float_SkColorType
pixel with a half float for red and green
Definition SkColorType.h:46
#define SkColorGetR(color)
Definition SkColor.h:65
#define SkColorGetG(color)
Definition SkColor.h:69
SK_API SkPMColor SkPreMultiplyColor(SkColor c)
Definition SkColor.cpp:21
uint32_t SkColor
Definition SkColor.h:37
uint32_t SkPMColor
Definition SkColor.h:205
#define SkColorGetB(color)
Definition SkColor.h:73
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
SkTextEncoding
Definition SkFontTypes.h:11
@ kUTF8
uses bytes to represent UTF-8 or ASCII
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
SK_API int SkColorTypeBytesPerPixel(SkColorType ct)
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define SkScalarSin(radians)
Definition SkScalar.h:45
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:107
#define SkScalarCos(radians)
Definition SkScalar.h:46
#define SK_ScalarRoot2Over2
Definition SkScalar.h:23
#define SK_ScalarPI
Definition SkScalar.h:21
SkTileMode
Definition SkTileMode.h:13
uint32_t SkFourByteTag
Definition SkTypes.h:166
static SkScalar center(float pos0, float pos1)
int count() const
Definition SkFontPriv.h:110
const uint16_t * glyphs() const
Definition SkFontPriv.h:111
void allocPixels(const SkImageInfo &info, size_t rowBytes)
Definition SkBitmap.cpp:258
void eraseArea(const SkIRect &area, SkColor c) const
Definition SkBitmap.h:854
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition SkBitmap.cpp:669
bool peekPixels(SkPixmap *pixmap) const
Definition SkBitmap.cpp:635
bool setInfo(const SkImageInfo &imageInfo, size_t rowBytes=0)
Definition SkBitmap.cpp:114
uint32_t * getAddr32(int x, int y) const
Definition SkBitmap.h:1260
bool tryAllocPixels(const SkImageInfo &info, size_t rowBytes)
Definition SkBitmap.cpp:271
void eraseColor(SkColor4f) const
Definition SkBitmap.cpp:442
void drawRect(const SkRect &rect, const SkPaint &paint)
sk_sp< SkSurface > makeSurface(const SkImageInfo &info, const SkSurfaceProps *props=nullptr)
void drawPaint(const SkPaint &paint)
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
Definition SkMatrix.h:157
const SkScalar * findScalars(const char name[], int *count, SkScalar values[]=nullptr) const
SkScalar * setScalars(const char name[], int count, const SkScalar values[]=nullptr)
static sk_sp< SkPicture > MakeFromStream(SkStream *stream, const SkDeserialProcs *procs=nullptr)
bool erase(SkColor color, const SkIRect &subset) const
Definition SkPixmap.cpp:742
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes) const
Definition SkPixmap.h:592
const SkImageInfo & info() const
Definition SkPixmap.h:135
void reset()
Definition SkPixmap.cpp:32
constexpr size_t size() const
Definition SkSpan_impl.h:95
int getVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], int parameterCount) const
void draw(SkCanvas *canvas)
void reset(size_t count=0)
const Paint & paint
float SkScalar
Definition extension.cpp:12
static bool b
struct MyStruct s
struct MyStruct a[10]
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const char * name
Definition fuchsia.cc:50
size_t length
std::u16string text
double y
double x
constexpr SkColor4f kGreen
Definition SkColor.h:441
constexpr SkColor4f kRed
Definition SkColor.h:440
constexpr SkColor4f kWhite
Definition SkColor.h:439
constexpr SkColor4f kCyan
Definition SkColor.h:444
constexpr SkColor4f kBlack
Definition SkColor.h:435
constexpr SkColor4f kBlue
Definition SkColor.h:442
constexpr SkColor4f kYellow
Definition SkColor.h:443
PODArray< SkColor > colors
Definition SkRecords.h:276
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
void draw_checkerboard(SkCanvas *canvas, SkColor c1, SkColor c2, int size)
sk_sp< SkSurface > makeSurface(SkCanvas *canvas, const SkImageInfo &info, const SkSurfaceProps *props)
sk_sp< SkShader > create_checkerboard_shader(SkColor c1, SkColor c2, int size)
void copy_to_g8(SkBitmap *dst, const SkBitmap &src)
bool copy_to(SkBitmap *dst, SkColorType dstColorType, const SkBitmap &src)
int make_pixmaps(SkColorType ct, SkAlphaType at, bool withMips, const SkColor4f colors[6], SkPixmap pixmaps[6], std::unique_ptr< char[]> *mem)
const char * colortype_depth(SkColorType ct)
Definition ToolUtils.cpp:97
void add_to_text_blob_w_len(SkTextBlobBuilder *builder, const char *text, size_t len, SkTextEncoding encoding, const SkFont &font, SkScalar x, SkScalar y)
void add_to_text_blob(SkTextBlobBuilder *builder, const char *text, const SkFont &font, SkScalar x, SkScalar y)
void create_frustum_normal_map(SkBitmap *bm, const SkIRect &dst)
void get_text_path(const SkFont &font, const void *text, size_t length, SkTextEncoding encoding, SkPath *dst, const SkPoint pos[])
const char * colortype_name(SkColorType ct)
Definition ToolUtils.cpp:65
void ExtractPathsFromSKP(const char filepath[], std::function< PathSniffCallback > callback)
SkBitmap create_checkerboard_bitmap(int w, int h, SkColor c1, SkColor c2, int checkSize)
const char * alphatype_name(SkAlphaType at)
Definition ToolUtils.cpp:55
bool equal_pixels(const SkPixmap &a, const SkPixmap &b)
const char * tilemode_name(SkTileMode mode)
static void norm_to_rgb(SkBitmap *bm, int x, int y, const SkVector3 &norm)
sk_sp< SkImage > create_checkerboard_image(int w, int h, SkColor c1, SkColor c2, int checkSize)
void create_tetra_normal_map(SkBitmap *bm, const SkIRect &dst)
void create_hemi_normal_map(SkBitmap *bm, const SkIRect &dst)
SkColor color_to_565(SkColor color)
constexpr float kStops[]
const DlColor kColors[]
Definition run.py:1
Definition __init__.py:1
static PathDY make_star(int n)
Definition pathfill.cpp:136
SkScalar w
SkScalar h
void inset(int32_t dx, int32_t dy)
Definition SkRect.h:411
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
Definition SkRect.h:91
bool contains(int32_t x, int32_t y) const
Definition SkRect.h:463
static SkImageInfo MakeN32Premul(int width, int height)
size_t minRowBytes() const
static SkImageInfo MakeS32(int width, int height, SkAlphaType at)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
int height() const
SkImageInfo makeColorType(SkColorType newColorType) const
SkScalar fX
Definition SkPoint3.h:16
static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z)
Definition SkPoint3.h:18
SkScalar length() const
Definition SkPoint3.h:44
SkScalar fZ
Definition SkPoint3.h:16
void set(SkScalar x, SkScalar y, SkScalar z)
Definition SkPoint3.h:28
SkScalar fY
Definition SkPoint3.h:16
float fX
x-axis value
static constexpr SkPoint Make(float x, float y)
float fY
y-axis value
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
constexpr float height() const
Definition SkRect.h:769
constexpr float width() const
Definition SkRect.h:762
bool isEmpty() const
Definition SkRect.h:693
void join(const SkRect &r)
Definition SkRect.cpp:126
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15