static void testOne(skiatest::Reporter* reporter, const SortSetTests& test) { SkTDArray<SkOpAngle> angles; bool unsortable = false; bool unorderable = false; SkTArray<SkOpSegment> segs; for (size_t idx = 0; idx < test.count; ++idx) { int ts[2]; const SortSet* set = test.set; SkOpSegment& seg = segs.push_back(); setup(set, idx, &seg, ts, test.startPt); SkOpAngle* angle = angles.append(); angle->set(&seg, ts[0], ts[1]); #if DEBUG_ANGLE angle->setID(idx); #endif if (angle->unsortable()) { #if DEBUG_ANGLE SkDebugf("%s test[%s]: angle[%d] unsortable\n", __FUNCTION__, test.name, idx); #endif unsortable = true; } if (angle->unorderable()) { #if DEBUG_ANGLE SkDebugf("%s test[%s]: angle[%d] unorderable\n", __FUNCTION__, test.name, idx); #endif unorderable = true; } reporter->bumpTestCount(); } if (unsortable || unorderable) { return; } #if DEBUG_ANGLE SkDebugf("%s test[%s]\n", __FUNCTION__, test.name); #endif for (size_t idxL = 0; idxL < test.count; ++idxL) { const SkOpAngle& first = angles[idxL]; for (size_t idxG = 0; idxG < test.count; ++idxG) { if (idxL == idxG) { continue; } const SkOpAngle& second = angles[idxG]; bool compare = first < second; if (idxL < idxG) { if (!compare) { SkDebugf("%s test[%s]: first[%d] > second[%d]\n", __FUNCTION__, test.name, idxL, idxG); compare = first < second; } REPORTER_ASSERT(reporter, compare); } else { SkASSERT(idxL > idxG); if (compare) { SkDebugf("%s test[%s]: first[%d] < second[%d]\n", __FUNCTION__, test.name, idxL, idxG); compare = first < second; } REPORTER_ASSERT(reporter, !compare); } compare = second < first; if (idxL < idxG) { if (compare) { SkDebugf("%s test[%s]: second[%d] < first[%d]\n", __FUNCTION__, test.name, idxL, idxG); compare = second < first; } REPORTER_ASSERT(reporter, !compare); } else { SkASSERT(idxL > idxG); if (!compare) { SkDebugf("%s test[%s]: second[%d] > first[%d]\n", __FUNCTION__, test.name, idxL, idxG); compare = second < first; } REPORTER_ASSERT(reporter, compare); } } } }
void* FlattenableHeap::allocThrow(size_t bytes) { void* ptr = sk_malloc_throw(bytes); *fPointers.append() = ptr; return ptr; }
void onDraw(SkCanvas* canvas) override { // We don't create pixels in an onOnceBeforeDraw() override because we want access to // GrContext. GrContext* context = canvas->getGrContext(); #if SK_SUPPORT_GPU // Workaround for SampleApp. if (GrTexture* tex = fBigTestPixels.fBitmap.getTexture()) { if (tex->wasDestroyed()) { fCreatedPixels = false; } } #endif bool madePixels = fCreatedPixels; if (!madePixels) { madePixels = gBleedRec[fBT].fPixelMaker(context, &fSmallTestPixels, kSmallTextureSize, kSmallTextureSize); madePixels &= gBleedRec[fBT].fPixelMaker(context, &fBigTestPixels, 2 * kMaxTileSize, 2 * kMaxTileSize); fCreatedPixels = madePixels; } // Assume that if we coulnd't make the bitmap/image it's because it's a GPU test on a // non-GPU backend. if (!madePixels) { skiagm::GM::DrawGpuOnlyMessage(canvas); return; } fShader = gBleedRec[fBT].fShaderMaker(); canvas->clear(SK_ColorGRAY); SkTDArray<SkMatrix> matrices; // Draw with identity *matrices.append() = SkMatrix::I(); // Draw with rotation and scale down in x, up in y. SkMatrix m; static const SkScalar kBottom = SkIntToScalar(kRow4Y + kBlockSize + kBlockSpacing); m.setTranslate(0, kBottom); m.preRotate(15.f, 0, kBottom + kBlockSpacing); m.preScale(0.71f, 1.22f); *matrices.append() = m; // Align the next set with the middle of the previous in y, translated to the right in x. SkPoint corners[] = {{0, 0}, { 0, kBottom }, { kWidth, kBottom }, {kWidth, 0} }; matrices[matrices.count()-1].mapPoints(corners, 4); SkScalar y = (corners[0].fY + corners[1].fY + corners[2].fY + corners[3].fY) / 4; SkScalar x = SkTMax(SkTMax(corners[0].fX, corners[1].fX), SkTMax(corners[2].fX, corners[3].fX)); m.setTranslate(x, y); m.preScale(0.2f, 0.2f); *matrices.append() = m; SkScalar maxX = 0; for (int antiAlias = 0; antiAlias < 2; ++antiAlias) { canvas->save(); canvas->translate(maxX, 0); for (int m = 0; m < matrices.count(); ++m) { canvas->save(); canvas->concat(matrices[m]); bool aa = SkToBool(antiAlias); // First draw a column with no bleeding and no filtering this->drawCase1(canvas, kCol0X, kRow0Y, aa, SkCanvas::kStrict_SrcRectConstraint, kNone_SkFilterQuality); this->drawCase2(canvas, kCol0X, kRow1Y, aa, SkCanvas::kStrict_SrcRectConstraint, kNone_SkFilterQuality); this->drawCase3(canvas, kCol0X, kRow2Y, aa, SkCanvas::kStrict_SrcRectConstraint, kNone_SkFilterQuality); this->drawCase4(canvas, kCol0X, kRow3Y, aa, SkCanvas::kStrict_SrcRectConstraint, kNone_SkFilterQuality); this->drawCase5(canvas, kCol0X, kRow4Y, aa, SkCanvas::kStrict_SrcRectConstraint, kNone_SkFilterQuality); // Then draw a column with no bleeding and low filtering this->drawCase1(canvas, kCol1X, kRow0Y, aa, SkCanvas::kStrict_SrcRectConstraint, kLow_SkFilterQuality); this->drawCase2(canvas, kCol1X, kRow1Y, aa, SkCanvas::kStrict_SrcRectConstraint, kLow_SkFilterQuality); this->drawCase3(canvas, kCol1X, kRow2Y, aa, SkCanvas::kStrict_SrcRectConstraint, kLow_SkFilterQuality); this->drawCase4(canvas, kCol1X, kRow3Y, aa, SkCanvas::kStrict_SrcRectConstraint, kLow_SkFilterQuality); this->drawCase5(canvas, kCol1X, kRow4Y, aa, SkCanvas::kStrict_SrcRectConstraint, kLow_SkFilterQuality); // Then draw a column with no bleeding and high filtering this->drawCase1(canvas, kCol2X, kRow0Y, aa, SkCanvas::kStrict_SrcRectConstraint, kHigh_SkFilterQuality); this->drawCase2(canvas, kCol2X, kRow1Y, aa, SkCanvas::kStrict_SrcRectConstraint, kHigh_SkFilterQuality); this->drawCase3(canvas, kCol2X, kRow2Y, aa, SkCanvas::kStrict_SrcRectConstraint, kHigh_SkFilterQuality); this->drawCase4(canvas, kCol2X, kRow3Y, aa, SkCanvas::kStrict_SrcRectConstraint, kHigh_SkFilterQuality); this->drawCase5(canvas, kCol2X, kRow4Y, aa, SkCanvas::kStrict_SrcRectConstraint, kHigh_SkFilterQuality); // Then draw a column with bleeding and no filtering (bleed should have no effect w/out blur) this->drawCase1(canvas, kCol3X, kRow0Y, aa, SkCanvas::kFast_SrcRectConstraint, kNone_SkFilterQuality); this->drawCase2(canvas, kCol3X, kRow1Y, aa, SkCanvas::kFast_SrcRectConstraint, kNone_SkFilterQuality); this->drawCase3(canvas, kCol3X, kRow2Y, aa, SkCanvas::kFast_SrcRectConstraint, kNone_SkFilterQuality); this->drawCase4(canvas, kCol3X, kRow3Y, aa, SkCanvas::kFast_SrcRectConstraint, kNone_SkFilterQuality); this->drawCase5(canvas, kCol3X, kRow4Y, aa, SkCanvas::kFast_SrcRectConstraint, kNone_SkFilterQuality); // Then draw a column with bleeding and low filtering this->drawCase1(canvas, kCol4X, kRow0Y, aa, SkCanvas::kFast_SrcRectConstraint, kLow_SkFilterQuality); this->drawCase2(canvas, kCol4X, kRow1Y, aa, SkCanvas::kFast_SrcRectConstraint, kLow_SkFilterQuality); this->drawCase3(canvas, kCol4X, kRow2Y, aa, SkCanvas::kFast_SrcRectConstraint, kLow_SkFilterQuality); this->drawCase4(canvas, kCol4X, kRow3Y, aa, SkCanvas::kFast_SrcRectConstraint, kLow_SkFilterQuality); this->drawCase5(canvas, kCol4X, kRow4Y, aa, SkCanvas::kFast_SrcRectConstraint, kLow_SkFilterQuality); // Finally draw a column with bleeding and high filtering this->drawCase1(canvas, kCol5X, kRow0Y, aa, SkCanvas::kFast_SrcRectConstraint, kHigh_SkFilterQuality); this->drawCase2(canvas, kCol5X, kRow1Y, aa, SkCanvas::kFast_SrcRectConstraint, kHigh_SkFilterQuality); this->drawCase3(canvas, kCol5X, kRow2Y, aa, SkCanvas::kFast_SrcRectConstraint, kHigh_SkFilterQuality); this->drawCase4(canvas, kCol5X, kRow3Y, aa, SkCanvas::kFast_SrcRectConstraint, kHigh_SkFilterQuality); this->drawCase5(canvas, kCol5X, kRow4Y, aa, SkCanvas::kFast_SrcRectConstraint, kHigh_SkFilterQuality); SkPoint corners[] = { { 0, 0 },{ 0, kBottom },{ kWidth, kBottom },{ kWidth, 0 } }; matrices[m].mapPoints(corners, 4); SkScalar x = kBlockSize + SkTMax(SkTMax(corners[0].fX, corners[1].fX), SkTMax(corners[2].fX, corners[3].fX)); maxX = SkTMax(maxX, x); canvas->restore(); } canvas->restore(); } }
void SkCommandLineFlags::Parse(int argc, char** argv) { // Only allow calling this function once. static bool gOnce; if (gOnce) { SkDebugf("Parse should only be called once at the beginning of main!\n"); SkASSERT(false); return; } gOnce = true; bool helpPrinted = false; bool flagsPrinted = false; // Loop over argv, starting with 1, since the first is just the name of the program. for (int i = 1; i < argc; i++) { if (0 == strcmp("-h", argv[i]) || 0 == strcmp("--help", argv[i])) { // Print help message. SkTDArray<const char*> helpFlags; for (int j = i + 1; j < argc; j++) { if (SkStrStartsWith(argv[j], '-')) { break; } helpFlags.append(1, &argv[j]); } if (0 == helpFlags.count()) { // Only print general help message if help for specific flags is not requested. SkDebugf("%s\n%s\n", argv[0], gUsage.c_str()); } if (!flagsPrinted) { SkDebugf("Flags:\n"); flagsPrinted = true; } if (0 == helpFlags.count()) { // If no flags followed --help, print them all SkTDArray<SkFlagInfo*> allFlags; for (SkFlagInfo* flag = SkCommandLineFlags::gHead; flag; flag = flag->next()) { allFlags.push(flag); } SkTQSort(&allFlags[0], &allFlags[allFlags.count() - 1], CompareFlagsByName()); for (int i = 0; i < allFlags.count(); ++i) { print_help_for_flag(allFlags[i]); if (allFlags[i]->extendedHelp().size() > 0) { SkDebugf(" Use '--help %s' for more information.\n", allFlags[i]->name().c_str()); } } } else { for (SkFlagInfo* flag = SkCommandLineFlags::gHead; flag; flag = flag->next()) { for (int k = 0; k < helpFlags.count(); k++) { if (flag->name().equals(helpFlags[k]) || flag->shortName().equals(helpFlags[k])) { print_extended_help_for_flag(flag); helpFlags.remove(k); break; } } } } if (helpFlags.count() > 0) { SkDebugf("Requested help for unrecognized flags:\n"); for (int k = 0; k < helpFlags.count(); k++) { SkDebugf(" --%s\n", helpFlags[k]); } } helpPrinted = true; } if (!helpPrinted) { SkFlagInfo* matchedFlag = nullptr; SkFlagInfo* flag = gHead; int startI = i; while (flag != nullptr) { if (flag->match(argv[startI])) { i = startI; if (matchedFlag) { // Don't redefine the same flag with different types. SkASSERT(matchedFlag->getFlagType() == flag->getFlagType()); } else { matchedFlag = flag; } switch (flag->getFlagType()) { case SkFlagInfo::kBool_FlagType: // Can be handled by match, above, but can also be set by the next // string. if (i+1 < argc && !SkStrStartsWith(argv[i+1], '-')) { i++; bool value; if (parse_bool_arg(argv[i], &value)) { flag->setBool(value); } } break; case SkFlagInfo::kString_FlagType: flag->resetStrings(); // Add all arguments until another flag is reached. while (i+1 < argc) { char* end = nullptr; // Negative numbers aren't flags. ignore_result(strtod(argv[i+1], &end)); if (end == argv[i+1] && SkStrStartsWith(argv[i+1], '-')) { break; } i++; flag->append(argv[i]); } break; case SkFlagInfo::kInt_FlagType: i++; flag->setInt(atoi(argv[i])); break; case SkFlagInfo::kDouble_FlagType: i++; flag->setDouble(atof(argv[i])); break; default: SkDEBUGFAIL("Invalid flag type"); } } flag = flag->next(); } if (!matchedFlag) { #if defined(SK_BUILD_FOR_MAC) if (SkStrStartsWith(argv[i], "NSDocumentRevisions") || SkStrStartsWith(argv[i], "-NSDocumentRevisions")) { i++; // skip YES } else #endif if (FLAGS_undefok) { SkDebugf("FYI: ignoring unknown flag '%s'.\n", argv[i]); } else { SkDebugf("Got unknown flag '%s'. Exiting.\n", argv[i]); exit(-1); } } } } // Since all of the flags have been set, release the memory used by each // flag. FLAGS_x can still be used after this. SkFlagInfo* flag = gHead; gHead = nullptr; while (flag != nullptr) { SkFlagInfo* next = flag->next(); delete flag; flag = next; } if (helpPrinted) { exit(0); } }
const SkTextBlob* makeBlob(unsigned blobIndex) { SkTextBlobBuilder builder; SkPaint font; font.setTextEncoding(SkPaint::kGlyphID_TextEncoding); font.setAntiAlias(true); font.setSubpixelText(true); font.setTypeface(fTypeface); for (unsigned l = 0; l < SK_ARRAY_COUNT(blobConfigs[blobIndex]); ++l) { unsigned currentGlyph = 0; for (unsigned c = 0; c < SK_ARRAY_COUNT(blobConfigs[blobIndex][l]); ++c) { const BlobCfg* cfg = &blobConfigs[blobIndex][l][c]; unsigned count = cfg->count; if (count > fGlyphs.count() - currentGlyph) { count = fGlyphs.count() - currentGlyph; } if (0 == count) { break; } font.setTextSize(kFontSize * cfg->scale); const SkScalar advanceX = font.getTextSize() * 0.85f; const SkScalar advanceY = font.getTextSize() * 1.5f; SkPoint offset = SkPoint::Make(currentGlyph * advanceX + c * advanceX, advanceY * l); switch (cfg->pos) { case kDefault_Pos: { const SkTextBlobBuilder::RunBuffer& buf = builder.allocRun(font, count, offset.x(), offset.y()); memcpy(buf.glyphs, fGlyphs.begin() + currentGlyph, count * sizeof(uint16_t)); } break; case kScalar_Pos: { const SkTextBlobBuilder::RunBuffer& buf = builder.allocRunPosH(font, count, offset.y()); SkTDArray<SkScalar> pos; for (unsigned i = 0; i < count; ++i) { *pos.append() = offset.x() + i * advanceX; } memcpy(buf.glyphs, fGlyphs.begin() + currentGlyph, count * sizeof(uint16_t)); memcpy(buf.pos, pos.begin(), count * sizeof(SkScalar)); } break; case kPoint_Pos: { const SkTextBlobBuilder::RunBuffer& buf = builder.allocRunPos(font, count); SkTDArray<SkScalar> pos; for (unsigned i = 0; i < count; ++i) { *pos.append() = offset.x() + i * advanceX; *pos.append() = offset.y() + i * (advanceY / count); } memcpy(buf.glyphs, fGlyphs.begin() + currentGlyph, count * sizeof(uint16_t)); memcpy(buf.pos, pos.begin(), count * sizeof(SkScalar) * 2); } break; default: SkFAIL("unhandled pos value"); } currentGlyph += count; } } return builder.build(); }