bool GrSWMaskHelper::init(const GrIRect& pathDevBounds, const GrPoint* translate) { fMatrix = fContext->getMatrix(); if (NULL != translate) { fMatrix.postTranslate(translate->fX, translate->fY); } fMatrix.postTranslate(-pathDevBounds.fLeft * SK_Scalar1, -pathDevBounds.fTop * SK_Scalar1); GrIRect bounds = GrIRect::MakeWH(pathDevBounds.width(), pathDevBounds.height()); fBM.setConfig(SkBitmap::kA8_Config, bounds.fRight, bounds.fBottom); if (!fBM.allocPixels()) { return false; } sk_bzero(fBM.getPixels(), fBM.getSafeSize()); sk_bzero(&fDraw, sizeof(fDraw)); fRasterClip.setRect(bounds); fDraw.fRC = &fRasterClip; fDraw.fClip = &fRasterClip.bwRgn(); fDraw.fMatrix = &fMatrix; fDraw.fBitmap = &fBM; return true; }
bool GrSWMaskHelper::init(const SkIRect& resultBounds, const SkMatrix* matrix) { if (NULL != matrix) { fMatrix = *matrix; } else { fMatrix.setIdentity(); } // Now translate so the bound's UL corner is at the origin fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, -resultBounds.fTop * SK_Scalar1); SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), resultBounds.height()); if (!fBM.allocPixels(SkImageInfo::MakeA8(bounds.fRight, bounds.fBottom))) { return false; } sk_bzero(fBM.getPixels(), fBM.getSafeSize()); sk_bzero(&fDraw, sizeof(fDraw)); fRasterClip.setRect(bounds); fDraw.fRC = &fRasterClip; fDraw.fClip = &fRasterClip.bwRgn(); fDraw.fMatrix = &fMatrix; fDraw.fBitmap = &fBM; return true; }
void init(int dirNo) { fResult.init(dirNo); fFoundCount = 0; fSmallestError = 0; sk_bzero(fFilesFound, sizeof(fFilesFound)); sk_bzero(fDirsFound, sizeof(fDirsFound)); sk_bzero(fError, sizeof(fError)); }
virtual void generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) { if (mx) { sk_bzero(mx, sizeof(*mx)); } if (my) { sk_bzero(my, sizeof(*my)); } }
void init(int dirNo, skiatest::Reporter* reporter) { fReporter = reporter; fResult.init(dirNo); fFoundCount = 0; TestState::fSmallCount = 0; fSmallestError = 0; sk_bzero(fFilesFound, sizeof(fFilesFound)); sk_bzero(fDirsFound, sizeof(fDirsFound)); sk_bzero(fError, sizeof(fError)); }
SkTestFont::SkTestFont(const SkTestFontData& fontData) : INHERITED() , fCharCodes(fontData.fCharCodes) , fCharCodesCount(fontData.fCharCodes ? fontData.fCharCodesCount : 0) , fWidths(fontData.fWidths) , fMetrics(fontData.fMetrics) , fName(fontData.fName) , fPaths(nullptr) { init(fontData.fPoints, fontData.fVerbs); #ifdef SK_DEBUG sk_bzero(fDebugBits, sizeof(fDebugBits)); sk_bzero(fDebugOverage, sizeof(fDebugOverage)); #endif }
static void testLineIntersect(skiatest::Reporter* reporter, const SkDQuad& quad, const SkDLine& line, const double x, const double y) { char pathStr[1024]; sk_bzero(pathStr, sizeof(pathStr)); char* str = pathStr; str += sprintf(str, " path.moveTo(%1.9g, %1.9g);\n", quad[0].fX, quad[0].fY); str += sprintf(str, " path.quadTo(%1.9g, %1.9g, %1.9g, %1.9g);\n", quad[1].fX, quad[1].fY, quad[2].fX, quad[2].fY); str += sprintf(str, " path.moveTo(%1.9g, %1.9g);\n", line[0].fX, line[0].fY); str += sprintf(str, " path.lineTo(%1.9g, %1.9g);\n", line[1].fX, line[1].fY); SkIntersections intersections; bool flipped = false; int result = doIntersect(intersections, quad, line, flipped); bool found = false; for (int index = 0; index < result; ++index) { double quadT = intersections[0][index]; SkDPoint quadXY = quad.ptAtT(quadT); double lineT = intersections[1][index]; SkDPoint lineXY = line.ptAtT(lineT); if (quadXY.approximatelyEqual(lineXY)) { found = true; } } REPORTER_ASSERT(reporter, found); }
sk_sp<GrTextBlob> GrTextBlob::Make(int glyphCount, int runCount) { // We allocate size for the GrTextBlob itself, plus size for the vertices array, // and size for the glyphIds array. size_t verticesCount = glyphCount * kVerticesPerGlyph * kMaxVASize; size_t blob = 0; size_t vertex = sk_align<alignof(char)> (blob + sizeof(GrTextBlob) * 1); size_t glyphs = sk_align<alignof(GrGlyph*)> (vertex + sizeof(char) * verticesCount); size_t runs = sk_align<alignof(GrTextBlob::Run)>(glyphs + sizeof(GrGlyph*) * glyphCount); size_t size = (runs + sizeof(GrTextBlob::Run) * runCount); void* allocation = ::operator new (size); if (CACHE_SANITY_CHECK) { sk_bzero(allocation, size); } sk_sp<GrTextBlob> cacheBlob(new (allocation) GrTextBlob); cacheBlob->fSize = size; // setup offsets for vertices / glyphs cacheBlob->fVertices = SkTAddOffset<char>(cacheBlob.get(), vertex); cacheBlob->fGlyphs = SkTAddOffset<GrGlyph*>(cacheBlob.get(), glyphs); cacheBlob->fRuns = SkTAddOffset<GrTextBlob::Run>(cacheBlob.get(), runs); // Initialize runs for (int i = 0; i < runCount; i++) { new (&cacheBlob->fRuns[i]) GrTextBlob::Run; } cacheBlob->fRunCount = runCount; return cacheBlob; }
void SkTypefacePlayback::setCount(int count) { this->reset(nullptr); fCount = count; fArray = new SkRefCnt* [count]; sk_bzero(fArray, count * sizeof(SkRefCnt*)); }
/* * Return a valid set of output dimensions for this decoder, given an input scale */ SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const { // libjpeg supports scaling by 1/1, 1/2, 1/4, and 1/8, so we will support these as well long scale; if (desiredScale > 0.75f) { scale = 1; } else if (desiredScale > 0.375f) { scale = 2; } else if (desiredScale > 0.1875f) { scale = 4; } else { scale = 8; } // Set up a fake decompress struct in order to use libjpeg to calculate output dimensions jpeg_decompress_struct dinfo; sk_bzero(&dinfo, sizeof(dinfo)); dinfo.image_width = this->getInfo().width(); dinfo.image_height = this->getInfo().height(); dinfo.global_state = DSTATE_READY; dinfo.num_components = 0; dinfo.scale_num = 1; dinfo.scale_denom = scale; jpeg_calc_output_dimensions(&dinfo); // Return the calculated output dimensions for the given scale return SkISize::Make(dinfo.output_width, dinfo.output_height); }
static void test_font(skiatest::Reporter* reporter) { uint32_t flags = 0; SkAutoTUnref<SkFont> font(SkFont::Create(nullptr, 24, SkFont::kA8_MaskType, flags)); REPORTER_ASSERT(reporter, font->getTypeface()); REPORTER_ASSERT(reporter, 24 == font->getSize()); REPORTER_ASSERT(reporter, 1 == font->getScaleX()); REPORTER_ASSERT(reporter, 0 == font->getSkewX()); REPORTER_ASSERT(reporter, SkFont::kA8_MaskType == font->getMaskType()); uint16_t glyphs[5]; sk_bzero(glyphs, sizeof(glyphs)); int count = font->textToGlyphs("Hello", 5, kUTF8_SkTextEncoding, glyphs, SK_ARRAY_COUNT(glyphs)); REPORTER_ASSERT(reporter, 5 == count); for (int i = 0; i < count; ++i) { REPORTER_ASSERT(reporter, 0 != glyphs[i]); } REPORTER_ASSERT(reporter, glyphs[0] != glyphs[1]); // 'h' != 'e' REPORTER_ASSERT(reporter, glyphs[2] == glyphs[3]); // 'l' == 'l' SkAutoTUnref<SkFont> newFont(font->cloneWithSize(36)); REPORTER_ASSERT(reporter, newFont.get()); REPORTER_ASSERT(reporter, font->getTypeface() == newFont->getTypeface()); REPORTER_ASSERT(reporter, 36 == newFont->getSize()); // double check we haven't changed REPORTER_ASSERT(reporter, 24 == font->getSize()); // double check we haven't changed SkPaint paint; paint.setTextSize(18); font.reset(SkFont::Testing_CreateFromPaint(paint)); REPORTER_ASSERT(reporter, font.get()); REPORTER_ASSERT(reporter, font->getSize() == paint.getTextSize()); REPORTER_ASSERT(reporter, SkFont::kBW_MaskType == font->getMaskType()); }
static void testSimplifyQuadralateralsMain(PathOpsThreadState* data) { SkASSERT(data); PathOpsThreadState& state = *data; char pathStr[1024]; sk_bzero(pathStr, sizeof(pathStr)); int ax = state.fA & 0x03; int ay = state.fA >> 2; int bx = state.fB & 0x03; int by = state.fB >> 2; int cx = state.fC & 0x03; int cy = state.fC >> 2; int dx = state.fD & 0x03; int dy = state.fD >> 2; for (int e = 0 ; e < 16; ++e) { int ex = e & 0x03; int ey = e >> 2; for (int f = e ; f < 16; ++f) { int fx = f & 0x03; int fy = f >> 2; for (int g = f ; g < 16; ++g) { int gx = g & 0x03; int gy = g >> 2; for (int h = g ; h < 16; ++h) { int hx = h & 0x03; int hy = h >> 2; SkPath path, out; path.setFillType(SkPath::kWinding_FillType); path.moveTo(SkIntToScalar(ax), SkIntToScalar(ay)); path.lineTo(SkIntToScalar(bx), SkIntToScalar(by)); path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy)); path.lineTo(SkIntToScalar(dx), SkIntToScalar(dy)); path.close(); path.moveTo(SkIntToScalar(ex), SkIntToScalar(ey)); path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy)); path.lineTo(SkIntToScalar(gx), SkIntToScalar(gy)); path.lineTo(SkIntToScalar(hx), SkIntToScalar(hy)); path.close(); // gdb: set print elements 400 char* str = pathStr; str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay); str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by); str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy); str += sprintf(str, " path.lineTo(%d, %d);\n", dx, dy); str += sprintf(str, " path.close();\n"); str += sprintf(str, " path.moveTo(%d, %d);\n", ex, ey); str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy); str += sprintf(str, " path.lineTo(%d, %d);\n", gx, gy); str += sprintf(str, " path.lineTo(%d, %d);\n", hx, hy); str += sprintf(str, " path.close();\n"); outputProgress(state.fPathStr, pathStr, SkPath::kWinding_FillType); testSimplify(path, false, out, state, pathStr); path.setFillType(SkPath::kEvenOdd_FillType); outputProgress(state.fPathStr, pathStr, SkPath::kEvenOdd_FillType); testSimplify(path, true, out, state, pathStr); } } } } }
virtual int onCharsToGlyphs(const void* chars, Encoding encoding, uint16_t glyphs[], int glyphCount) const override { if (glyphs && glyphCount > 0) { sk_bzero(glyphs, glyphCount * sizeof(glyphs[0])); } return 0; }
static void copyToMask(const SkRegion& rgn, SkMask* mask) { mask->fFormat = SkMask::kA8_Format; if (rgn.isEmpty()) { mask->fBounds.setEmpty(); mask->fRowBytes = 0; mask->fImage = nullptr; return; } mask->fBounds = rgn.getBounds(); mask->fRowBytes = mask->fBounds.width(); mask->fImage = SkMask::AllocImage(mask->computeImageSize()); sk_bzero(mask->fImage, mask->computeImageSize()); SkImageInfo info = SkImageInfo::Make(mask->fBounds.width(), mask->fBounds.height(), kAlpha_8_SkColorType, kPremul_SkAlphaType); SkBitmap bitmap; bitmap.installPixels(info, mask->fImage, mask->fRowBytes); // canvas expects its coordinate system to always be 0,0 in the top/left // so we translate the rgn to match that before drawing into the mask. // SkRegion tmpRgn(rgn); tmpRgn.translate(-rgn.getBounds().fLeft, -rgn.getBounds().fTop); SkCanvas canvas(bitmap); canvas.clipRegion(tmpRgn); canvas.drawColor(SK_ColorBLACK); }
// We use this static factory function instead of the regular constructor so // that we can create the pixel data before calling the constructor. This is // required so that we can call the base class' constructor with the pixel // data. static bool Create(int width, int height, bool is_opaque, SkRasterHandleAllocator::Rec* rec) { BITMAPINFOHEADER hdr = { 0 }; hdr.biSize = sizeof(BITMAPINFOHEADER); hdr.biWidth = width; hdr.biHeight = -height; // Minus means top-down bitmap. hdr.biPlanes = 1; hdr.biBitCount = 32; hdr.biCompression = BI_RGB; // No compression. hdr.biSizeImage = 0; hdr.biXPelsPerMeter = 1; hdr.biYPelsPerMeter = 1; void* pixels; HBITMAP hbitmap = CreateDIBSection(nullptr, (const BITMAPINFO*)&hdr, 0, &pixels, 0, 0); if (!hbitmap) { return false; } size_t row_bytes = width * sizeof(SkPMColor); sk_bzero(pixels, row_bytes * height); HDC hdc = CreateCompatibleDC(nullptr); if (!hdc) { DeleteObject(hbitmap); return false; } SetGraphicsMode(hdc, GM_ADVANCED); SelectObject(hdc, hbitmap); rec->fReleaseProc = DeleteHDCCallback; rec->fReleaseCtx = hdc; rec->fPixels = pixels; rec->fRowBytes = row_bytes; rec->fHandle = hdc; return true; }
GrAtlasTextBlob* GrAtlasTextBlob::Create(GrMemoryPool* pool, int glyphCount, int runCount) { // We allocate size for the GrAtlasTextBlob itself, plus size for the vertices array, // and size for the glyphIds array. size_t verticesCount = glyphCount * kVerticesPerGlyph * kMaxVASize; size_t size = sizeof(GrAtlasTextBlob) + verticesCount + glyphCount * sizeof(GrGlyph**) + sizeof(GrAtlasTextBlob::Run) * runCount; void* allocation = pool->allocate(size); if (CACHE_SANITY_CHECK) { sk_bzero(allocation, size); } GrAtlasTextBlob* cacheBlob = new (allocation) GrAtlasTextBlob; cacheBlob->fSize = size; // setup offsets for vertices / glyphs cacheBlob->fVertices = sizeof(GrAtlasTextBlob) + reinterpret_cast<unsigned char*>(cacheBlob); cacheBlob->fGlyphs = reinterpret_cast<GrGlyph**>(cacheBlob->fVertices + verticesCount); cacheBlob->fRuns = reinterpret_cast<GrAtlasTextBlob::Run*>(cacheBlob->fGlyphs + glyphCount); // Initialize runs for (int i = 0; i < runCount; i++) { new (&cacheBlob->fRuns[i]) GrAtlasTextBlob::Run; } cacheBlob->fRunCount = runCount; cacheBlob->fPool = pool; return cacheBlob; }
void SkMatrix44::setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) { sk_bzero(fMat, sizeof(fMat)); fMat[0][0] = sx; fMat[1][1] = sy; fMat[2][2] = sz; fMat[3][3] = 1; }
SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller, SkWriter32* writer, uint32_t flags, uint32_t width, uint32_t height) : SkCanvas(width, height) , fFactorySet(is_cross_process(flags) ? SkNEW(SkNamedFactorySet) : NULL) , fWriter(*writer) , fFlags(flags) , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, is_cross_process(flags)) , fFlatDictionary(&fFlattenableHeap) { fController = controller; fDone = false; fBlockSize = 0; // need first block from controller fBytesNotified = 0; sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex)); // Tell the reader the appropriate flags to use. if (this->needOpBytes()) { this->writeOp(kReportFlags_DrawOp, fFlags, 0); } if (shouldFlattenBitmaps(flags)) { fBitmapShuttle.reset(SkNEW_ARGS(BitmapShuttle, (this))); fBitmapHeap = SkNEW_ARGS(SkBitmapHeap, (fBitmapShuttle.get(), BITMAPS_TO_KEEP)); } else { fBitmapHeap = SkNEW_ARGS(SkBitmapHeap, (BITMAPS_TO_KEEP, controller->numberOfReaders())); if (this->needOpBytes(sizeof(void*))) { this->writeOp(kShareBitmapHeap_DrawOp); fWriter.writePtr(static_cast<void*>(fBitmapHeap)); } } fFlattenableHeap.setBitmapStorage(fBitmapHeap); this->doNotify(); }
/* * Return a valid set of output dimensions for this decoder, given an input scale */ SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const { // libjpeg-turbo supports scaling by 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, and 1/1, so we will // support these as well unsigned int num; unsigned int denom = 8; if (desiredScale >= 0.9375) { num = 8; } else if (desiredScale >= 0.8125) { num = 7; } else if (desiredScale >= 0.6875f) { num = 6; } else if (desiredScale >= 0.5625f) { num = 5; } else if (desiredScale >= 0.4375f) { num = 4; } else if (desiredScale >= 0.3125f) { num = 3; } else if (desiredScale >= 0.1875f) { num = 2; } else { num = 1; } // Set up a fake decompress struct in order to use libjpeg to calculate output dimensions jpeg_decompress_struct dinfo; sk_bzero(&dinfo, sizeof(dinfo)); dinfo.image_width = this->getInfo().width(); dinfo.image_height = this->getInfo().height(); dinfo.global_state = fReadyState; calc_output_dimensions(&dinfo, num, denom); // Return the calculated output dimensions for the given scale return SkISize::Make(dinfo.output_width, dinfo.output_height); }
DEF_TEST(WriteBuffer_storage, reporter) { enum { kSize = 32 }; int32_t storage[kSize/4]; char src[kSize]; sk_bzero(src, kSize); SkBinaryWriteBuffer writer(storage, kSize); REPORTER_ASSERT(reporter, writer.usingInitialStorage()); REPORTER_ASSERT(reporter, writer.bytesWritten() == 0); writer.write(src, kSize - 4); REPORTER_ASSERT(reporter, writer.usingInitialStorage()); REPORTER_ASSERT(reporter, writer.bytesWritten() == kSize - 4); writer.writeInt(0); REPORTER_ASSERT(reporter, writer.usingInitialStorage()); REPORTER_ASSERT(reporter, writer.bytesWritten() == kSize); writer.reset(storage, kSize-4); REPORTER_ASSERT(reporter, writer.usingInitialStorage()); REPORTER_ASSERT(reporter, writer.bytesWritten() == 0); writer.write(src, kSize - 4); REPORTER_ASSERT(reporter, writer.usingInitialStorage()); REPORTER_ASSERT(reporter, writer.bytesWritten() == kSize - 4); writer.writeInt(0); REPORTER_ASSERT(reporter, !writer.usingInitialStorage()); // this is the change REPORTER_ASSERT(reporter, writer.bytesWritten() == kSize); }
bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state, const char* pathStr) { SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType; path.setFillType(fillType); state.fReporter->bumpTestCount(); if (!Simplify(path, &out)) { SkDebugf("%s did not expect failure\n", __FUNCTION__); REPORTER_ASSERT(state.fReporter, 0); return false; } if (!state.fReporter->verbose()) { return true; } int result = comparePaths(state.fReporter, nullptr, path, out, *state.fBitmap); if (result) { SkAutoMutexAcquire autoM(simplifyDebugOut); char temp[8192]; sk_bzero(temp, sizeof(temp)); SkMemoryWStream stream(temp, sizeof(temp)); const char* pathPrefix = nullptr; const char* nameSuffix = nullptr; if (fillType == SkPath::kEvenOdd_FillType) { pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n"; nameSuffix = "x"; } const char testFunction[] = "testSimplify(reporter, path);"; outputToStream(pathStr, pathPrefix, nameSuffix, testFunction, false, stream); SkDebugf("%s", temp); REPORTER_ASSERT(state.fReporter, 0); } state.fReporter->bumpTestCount(); return result == 0; }
bool GrSWMaskHelper::init(const SkIRect& resultBounds, const SkMatrix* matrix) { if (NULL != matrix) { fMatrix = *matrix; } else { fMatrix.setIdentity(); } // Now translate so the bound's UL corner is at the origin fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1, -resultBounds.fTop * SK_Scalar1); SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), resultBounds.height()); #if GR_COMPRESS_ALPHA_MASK fCompressMask = choose_compressed_fmt(fContext->getGpu()->caps(), &fCompressedFormat); #else fCompressMask = false; #endif // Make sure that the width is a multiple of 16 so that we can use // specialized SIMD instructions that compress 4 blocks at a time. int cmpWidth, cmpHeight; if (fCompressMask) { int dimX, dimY; SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY); cmpWidth = dimX * ((bounds.fRight + (dimX - 1)) / dimX); cmpHeight = dimY * ((bounds.fBottom + (dimY - 1)) / dimY); } else { cmpWidth = bounds.fRight; cmpHeight = bounds.fBottom; } if (!fBM.allocPixels(SkImageInfo::MakeA8(cmpWidth, cmpHeight))) { return false; } sk_bzero(fBM.getPixels(), fBM.getSafeSize()); sk_bzero(&fDraw, sizeof(fDraw)); fRasterClip.setRect(bounds); fDraw.fRC = &fRasterClip; fDraw.fClip = &fRasterClip.bwRgn(); fDraw.fMatrix = &fMatrix; fDraw.fBitmap = &fBM; return true; }
void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* metrics) { if (NULL == metrics) { return; } sk_bzero(metrics, sizeof(*metrics)); DWRITE_FONT_METRICS dwfm; if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode || DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode) { fTypeface->fDWriteFontFace->GetGdiCompatibleMetrics( fTextSizeRender, 1.0f, // pixelsPerDip &fXform, &dwfm); } else { fTypeface->fDWriteFontFace->GetMetrics(&dwfm); } SkScalar upem = SkIntToScalar(dwfm.designUnitsPerEm); metrics->fAscent = -fTextSizeRender * SkIntToScalar(dwfm.ascent) / upem; metrics->fDescent = fTextSizeRender * SkIntToScalar(dwfm.descent) / upem; metrics->fLeading = fTextSizeRender * SkIntToScalar(dwfm.lineGap) / upem; metrics->fXHeight = fTextSizeRender * SkIntToScalar(dwfm.xHeight) / upem; metrics->fUnderlineThickness = fTextSizeRender * SkIntToScalar(dwfm.underlineThickness) / upem; metrics->fUnderlinePosition = -(fTextSizeRender * SkIntToScalar(dwfm.underlinePosition) / upem); metrics->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; if (fTypeface->fDWriteFontFace1.get()) { DWRITE_FONT_METRICS1 dwfm1; fTypeface->fDWriteFontFace1->GetMetrics(&dwfm1); metrics->fTop = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxTop) / upem; metrics->fBottom = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxBottom) / upem; metrics->fXMin = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxLeft) / upem; metrics->fXMax = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxRight) / upem; metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin; } else { AutoTDWriteTable<SkOTTableHead> head(fTypeface->fDWriteFontFace.get()); if (head.fExists && head.fSize >= sizeof(SkOTTableHead) && head->version == SkOTTableHead::version1) { metrics->fTop = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMax) / upem; metrics->fBottom = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMin) / upem; metrics->fXMin = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMin) / upem; metrics->fXMax = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMax) / upem; metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin; } else { metrics->fTop = metrics->fAscent; metrics->fBottom = metrics->fDescent; } } }
static void testSimplifyDegeneratesMain(PathOpsThreadState* data) { SkASSERT(data); PathOpsThreadState& state = *data; char pathStr[1024]; bool progress = state.fReporter->verbose(); // FIXME: break out into its own parameter? if (progress) { sk_bzero(pathStr, sizeof(pathStr)); } int ax = state.fA & 0x03; int ay = state.fA >> 2; int bx = state.fB & 0x03; int by = state.fB >> 2; int cx = state.fC & 0x03; int cy = state.fC >> 2; for (int d = 0; d < 16; ++d) { int dx = d & 0x03; int dy = d >> 2; for (int e = d ; e < 16; ++e) { int ex = e & 0x03; int ey = e >> 2; for (int f = d ; f < 16; ++f) { int fx = f & 0x03; int fy = f >> 2; if (state.fD && (ex - dx) * (fy - dy) != (ey - dy) * (fx - dx)) { continue; } SkPath path, out; path.setFillType(SkPath::kWinding_FillType); path.moveTo(SkIntToScalar(ax), SkIntToScalar(ay)); path.lineTo(SkIntToScalar(bx), SkIntToScalar(by)); path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy)); path.close(); path.moveTo(SkIntToScalar(dx), SkIntToScalar(dy)); path.lineTo(SkIntToScalar(ex), SkIntToScalar(ey)); path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy)); path.close(); if (progress) { char* str = pathStr; str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay); str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by); str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy); str += sprintf(str, " path.close();\n"); str += sprintf(str, " path.moveTo(%d, %d);\n", dx, dy); str += sprintf(str, " path.lineTo(%d, %d);\n", ex, ey); str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy); str += sprintf(str, " path.close();\n"); outputProgress(state.fPathStr, pathStr, SkPath::kWinding_FillType); } testSimplify(path, false, out, state, pathStr); path.setFillType(SkPath::kEvenOdd_FillType); if (progress) { outputProgress(state.fPathStr, pathStr, SkPath::kEvenOdd_FillType); } testSimplify(path, true, out, state, pathStr); } } } }
SkTextureCache::SkTextureCache(size_t countMax, size_t sizeMax) : fHead(NULL), fTail(NULL), fTexCountMax(countMax), fTexSizeMax(sizeMax), fTexCount(0), fTexSize(0) { sk_bzero(fHash, sizeof(fHash)); this->validate(); }
int SkTypeface::onCharsToGlyphs(const void* chars, Encoding encoding, uint16_t glyphs[], int glyphCount) const { SkDebugf("onCharsToGlyphs unimplemented\n"); if (glyphs && glyphCount > 0) { sk_bzero(glyphs, glyphCount * sizeof(glyphs[0])); } return 0; }
static void testPathOpsRectsMain(PathOpsThreadState* data) { SkASSERT(data); PathOpsThreadState& state = *data; char pathStr[1024]; // gdb: set print elements 400 bool progress = state.fReporter->verbose(); // FIXME: break out into its own parameter? if (progress) { sk_bzero(pathStr, sizeof(pathStr)); } for (int a = 0 ; a < 6; ++a) { for (int b = a + 1 ; b < 7; ++b) { for (int c = 0 ; c < 6; ++c) { for (int d = c + 1 ; d < 7; ++d) { for (int e = SkPath::kWinding_FillType ; e <= SkPath::kEvenOdd_FillType; ++e) { for (int f = SkPath::kWinding_FillType ; f <= SkPath::kEvenOdd_FillType; ++f) { if (progress) { char* str = pathStr; str += sprintf(str, " path.setFillType(SkPath::k%s_FillType);\n", e == SkPath::kWinding_FillType ? "Winding" : e == SkPath::kEvenOdd_FillType ? "EvenOdd" : "?UNDEFINED"); str += sprintf(str, " path.addRect(%d, %d, %d, %d," " SkPath::kCW_Direction);\n", state.fA, state.fA, state.fB, state.fB); str += sprintf(str, " path.addRect(%d, %d, %d, %d," " SkPath::kCW_Direction);\n", state.fC, state.fC, state.fD, state.fD); str += sprintf(str, " pathB.setFillType(SkPath::k%s_FillType);\n", f == SkPath::kWinding_FillType ? "Winding" : f == SkPath::kEvenOdd_FillType ? "EvenOdd" : "?UNDEFINED"); str += sprintf(str, " pathB.addRect(%d, %d, %d, %d," " SkPath::kCW_Direction);\n", a, a, b, b); str += sprintf(str, " pathB.addRect(%d, %d, %d, %d," " SkPath::kCW_Direction);\n", c, c, d, d); } SkPath pathA, pathB; pathA.setFillType((SkPath::FillType) e); pathA.addRect(SkIntToScalar(state.fA), SkIntToScalar(state.fA), SkIntToScalar(state.fB), SkIntToScalar(state.fB), SkPath::kCW_Direction); pathA.addRect(SkIntToScalar(state.fC), SkIntToScalar(state.fC), SkIntToScalar(state.fD), SkIntToScalar(state.fD), SkPath::kCW_Direction); pathA.close(); pathB.setFillType((SkPath::FillType) f); pathB.addRect(SkIntToScalar(a), SkIntToScalar(a), SkIntToScalar(b), SkIntToScalar(b), SkPath::kCW_Direction); pathB.addRect(SkIntToScalar(c), SkIntToScalar(c), SkIntToScalar(d), SkIntToScalar(d), SkPath::kCW_Direction); pathB.close(); for (int op = 0 ; op <= kXOR_PathOp; ++op) { if (progress) { outputProgress(state.fPathStr, pathStr, (SkPathOp) op); } testThreadedPathOp(state.fReporter, pathA, pathB, (SkPathOp) op, "rects"); } } } } } } } }
static void testOpLoopsMain(PathOpsThreadState* data) { #if DEBUG_SHOW_TEST_NAME strncpy(DEBUG_FILENAME_STRING, "", DEBUG_FILENAME_STRING_LENGTH); #endif SkASSERT(data); PathOpsThreadState& state = *data; char pathStr[1024]; // gdb: set print elements 400 bool progress = state.fReporter->verbose(); // FIXME: break out into its own parameter? if (progress) { sk_bzero(pathStr, sizeof(pathStr)); } for (int a = 0 ; a < 6; ++a) { for (int b = a + 1 ; b < 7; ++b) { for (int c = 0 ; c < 6; ++c) { for (int d = c + 1 ; d < 7; ++d) { // define 4 points that form two lines that often cross; one line is (a, b) (c, d) SkVector v = {SkIntToScalar(a - c), SkIntToScalar(b - d)}; SkPoint midA = { SkIntToScalar(a * state.fA + c * (6 - state.fA)) / 6, SkIntToScalar(b * state.fA + d * (6 - state.fA)) / 6 }; SkPoint midB = { SkIntToScalar(a * state.fB + c * (6 - state.fB)) / 6, SkIntToScalar(b * state.fB + d * (6 - state.fB)) / 6 }; SkPoint endC = { midA.fX + v.fY * state.fC / 3, midA.fY + v.fX * state.fC / 3 }; SkPoint endD = { midB.fX - v.fY * state.fD / 3, midB.fY + v.fX * state.fD / 3 }; SkPath pathA, pathB; if (progress) { char* str = pathStr; str += sprintf(str, " path.moveTo(%d,%d);\n", a, b); str += sprintf(str, " path.cubicTo(%d,%d, %1.9gf,%1.9gf, %1.9gf,%1.9gf);\n", c, d, endC.fX, endC.fY, endD.fX, endD.fY); str += sprintf(str, " path.close();\n"); str += sprintf(str, " pathB.moveTo(%d,%d);\n", c, d); str += sprintf(str, " pathB.cubicTo(%1.9gf,%1.9gf, %1.9gf,%1.9gf, %d,%d);\n", endC.fX, endC.fY, endD.fX, endD.fY, a, b); str += sprintf(str, " pathB.close();\n"); } pathA.moveTo(SkIntToScalar(a), SkIntToScalar(b)); pathA.cubicTo(SkIntToScalar(c), SkIntToScalar(d), endC.fX, endC.fY, endD.fX, endD.fY); pathA.close(); pathB.moveTo(SkIntToScalar(c), SkIntToScalar(d)); pathB.cubicTo(endC.fX, endC.fY, endD.fX, endD.fY, SkIntToScalar(a), SkIntToScalar(b)); pathB.close(); // SkDebugf("%s\n", pathStr); if (progress) { outputProgress(state.fPathStr, pathStr, kIntersect_PathOp); } testThreadedPathOp(state.fReporter, pathA, pathB, kIntersect_PathOp, "loops"); } } } } }
void SkMatrix44::set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, SkMScalar m10, SkMScalar m11, SkMScalar m12, SkMScalar m20, SkMScalar m21, SkMScalar m22) { sk_bzero(fMat, sizeof(fMat)); fMat[0][0] = m00; fMat[0][1] = m01; fMat[0][2] = m02; fMat[0][3] = 0; fMat[1][0] = m10; fMat[1][1] = m11; fMat[1][2] = m12; fMat[1][3] = 0; fMat[2][0] = m20; fMat[2][1] = m21; fMat[2][2] = m22; fMat[2][3] = 0; fMat[3][0] = 0; fMat[3][1] = 0; fMat[3][2] = 0; fMat[3][3] = 1; }
void onDraw(SkCanvas* canvas) override { drawJpeg(canvas, this->getISize()); canvas->scale(2, 2); static const char* kLabel1 = "Original Img"; static const char* kLabel2 = "Modified Img"; static const char* kLabel3 = "Cur Surface"; static const char* kLabel4 = "Full Crop"; static const char* kLabel5 = "Over-crop"; static const char* kLabel6 = "Upper-left"; static const char* kLabel7 = "No Crop"; static const char* kLabel8 = "Pre-Alloc Img"; static const char* kLabel9 = "New Alloc Img"; static const char* kLabel10 = "GPU"; SkPaint textPaint; textPaint.setAntiAlias(true); sk_tool_utils::set_portable_typeface(&textPaint); textPaint.setTextSize(8); canvas->drawText(kLabel1, strlen(kLabel1), 10, 60, textPaint); canvas->drawText(kLabel2, strlen(kLabel2), 10, 140, textPaint); canvas->drawText(kLabel3, strlen(kLabel3), 10, 220, textPaint); canvas->drawText(kLabel4, strlen(kLabel4), 10, 300, textPaint); canvas->drawText(kLabel5, strlen(kLabel5), 10, 380, textPaint); canvas->drawText(kLabel6, strlen(kLabel6), 10, 460, textPaint); canvas->drawText(kLabel7, strlen(kLabel7), 10, 540, textPaint); canvas->drawText(kLabel8, strlen(kLabel8), 80, 10, textPaint); canvas->drawText(kLabel9, strlen(kLabel9), 160, 10, textPaint); canvas->drawText(kLabel10, strlen(kLabel10), 265, 10, textPaint); canvas->translate(80, 20); // since we draw into this directly, we need to start fresh sk_bzero(fBuffer, fBufferSize); SkImageInfo info = SkImageInfo::MakeN32Premul(W, H); SkAutoTUnref<SkSurface> surf0(SkSurface::NewRasterDirect(info, fBuffer, RB)); SkAutoTUnref<SkSurface> surf1(SkSurface::NewRaster(info)); SkAutoTUnref<SkSurface> surf2; // gpu #if SK_SUPPORT_GPU surf2.reset(SkSurface::NewRenderTarget(canvas->getGrContext(), SkSurface::kNo_Budgeted, info)); #endif test_surface(canvas, surf0, true); canvas->translate(80, 0); test_surface(canvas, surf1, true); if (surf2) { canvas->translate(80, 0); test_surface(canvas, surf2, true); } }