コード例 #1
0
 void draw(SkCanvas* canvas,
           const SkRect& rect,
           const SkSize& deviceSize,
           SkPaint::FilterLevel filterLevel,
           SkImageFilter* input = NULL) {
     SkRect dstRect;
     canvas->getTotalMatrix().mapRect(&dstRect, rect);
     canvas->save();
     SkScalar deviceScaleX = SkScalarDiv(deviceSize.width(), dstRect.width());
     SkScalar deviceScaleY = SkScalarDiv(deviceSize.height(), dstRect.height());
     canvas->translate(rect.x(), rect.y());
     canvas->scale(deviceScaleX, deviceScaleY);
     canvas->translate(-rect.x(), -rect.y());
     SkMatrix matrix;
     matrix.setScale(SkScalarInvert(deviceScaleX),
                     SkScalarInvert(deviceScaleY));
     SkAutoTUnref<SkImageFilter> imageFilter(
         SkMatrixImageFilter::Create(matrix, filterLevel, input));
     SkPaint filteredPaint;
     filteredPaint.setImageFilter(imageFilter.get());
     canvas->saveLayer(&rect, &filteredPaint);
     SkPaint paint;
     paint.setColor(0xFF00FF00);
     SkRect ovalRect = rect;
     ovalRect.inset(SkIntToScalar(4), SkIntToScalar(4));
     canvas->drawOval(ovalRect, paint);
     canvas->restore(); // for saveLayer
     canvas->restore();
 }
コード例 #2
0
ファイル: SkPerlinNoiseShader.cpp プロジェクト: THanwa/skia
    PaintingData(const SkISize& tileSize, SkScalar seed,
                 SkScalar baseFrequencyX, SkScalar baseFrequencyY,
                 const SkMatrix& matrix)
    {
        SkVector wavelength = SkVector::Make(SkScalarInvert(baseFrequencyX),
                                             SkScalarInvert(baseFrequencyY));
        matrix.mapVectors(&wavelength, 1);
        fBaseFrequency.fX = SkScalarInvert(wavelength.fX);
        fBaseFrequency.fY = SkScalarInvert(wavelength.fY);
        SkVector sizeVec = SkVector::Make(SkIntToScalar(tileSize.fWidth),
                                          SkIntToScalar(tileSize.fHeight));
        matrix.mapVectors(&sizeVec, 1);
        fTileSize.fWidth = SkScalarRoundToInt(sizeVec.fX);
        fTileSize.fHeight = SkScalarRoundToInt(sizeVec.fY);
        this->init(seed);
        if (!fTileSize.isEmpty()) {
            this->stitch();
        }

#if SK_SUPPORT_GPU
        fPermutationsBitmap.setInfo(SkImageInfo::MakeA8(kBlockSize, 1));
        fPermutationsBitmap.setPixels(fLatticeSelector);

        fNoiseBitmap.setInfo(SkImageInfo::MakeN32Premul(kBlockSize, 4));
        fNoiseBitmap.setPixels(fNoise[0][0]);
#endif
    }
コード例 #3
0
ファイル: SkPerlinNoiseShader.cpp プロジェクト: Arternis/skia
    PaintingData(const SkISize& tileSize, SkScalar seed,
                 SkScalar baseFrequencyX, SkScalar baseFrequencyY,
                 const SkMatrix& matrix)
    {
        SkVector vec[2] = {
            { SkScalarInvert(baseFrequencyX),   SkScalarInvert(baseFrequencyY)  },
            { SkIntToScalar(tileSize.fWidth),   SkIntToScalar(tileSize.fHeight) },
        };
        matrix.mapVectors(vec, 2);

        fBaseFrequency.set(SkScalarInvert(vec[0].fX), SkScalarInvert(vec[0].fY));
        fTileSize.set(SkScalarRoundToInt(vec[1].fX), SkScalarRoundToInt(vec[1].fY));
        this->init(seed);
        if (!fTileSize.isEmpty()) {
            this->stitch();
        }

#if SK_SUPPORT_GPU
        fPermutationsBitmap.setInfo(SkImageInfo::MakeA8(kBlockSize, 1));
        fPermutationsBitmap.setPixels(fLatticeSelector);

        fNoiseBitmap.setInfo(SkImageInfo::MakeN32Premul(kBlockSize, 4));
        fNoiseBitmap.setPixels(fNoise[0][0]);
#endif
    }
コード例 #4
0
ファイル: SkTileGrid.cpp プロジェクト: OS-Corp/skia
SkTileGrid::SkTileGrid(int xTiles, int yTiles, const SkTileGridFactory::TileGridInfo& info)
    : fXTiles(xTiles)
    , fYTiles(yTiles)
    , fInvWidth( SkScalarInvert(info.fTileInterval.width()))
    , fInvHeight(SkScalarInvert(info.fTileInterval.height()))
    , fMarginWidth (info.fMargin.fWidth +1)  // Margin is offset by 1 as a provision for AA and
    , fMarginHeight(info.fMargin.fHeight+1)  // to cancel the outset applied by getClipDeviceBounds.
    , fOffset(SkPoint::Make(info.fOffset.fX, info.fOffset.fY))
    , fGridBounds(SkRect::MakeWH(xTiles * info.fTileInterval.width(),
                                 yTiles * info.fTileInterval.height()))
    , fTiles(SkNEW_ARRAY(SkTDArray<unsigned>, xTiles * yTiles)) {}
コード例 #5
0
bool SkPathContainsPoint(SkPath* originalPath, const FloatPoint& point, SkPath::FillType ft)
{
    SkRegion rgn;
    SkRegion clip;

    SkPath::FillType originalFillType = originalPath->getFillType();

    const SkPath* path = originalPath;
    SkPath scaledPath;
    int scale = 1;

    SkRect bounds;
    // FIXME:  This #ifdef can go away once we're firmly using the new Skia.
    // During the transition, this makes the code compatible with both versions.
#ifdef SK_USE_OLD_255_TO_256
    bounds = originalPath->getBounds();
#else
    originalPath->computeBounds(&bounds, SkPath::kFast_BoundsType);
#endif

    // We can immediately return false if the point is outside the bounding rect
    if (!bounds.contains(SkFloatToScalar(point.x()), SkFloatToScalar(point.y())))
        return false;

    originalPath->setFillType(ft);

    // Skia has trouble with coordinates close to the max signed 16-bit values
    // If we have those, we need to scale. 
    //
    // TODO: remove this code once Skia is patched to work properly with large
    // values
    const SkScalar kMaxCoordinate = SkIntToScalar(1<<15);
    SkScalar biggestCoord = std::max(std::max(std::max(bounds.fRight, bounds.fBottom), -bounds.fLeft), -bounds.fTop);

    if (biggestCoord > kMaxCoordinate) {
        scale = SkScalarCeil(SkScalarDiv(biggestCoord, kMaxCoordinate));

        SkMatrix m;
        m.setScale(SkScalarInvert(SkIntToScalar(scale)), SkScalarInvert(SkIntToScalar(scale)));
        originalPath->transform(m, &scaledPath);
        path = &scaledPath;
    }

    int x = static_cast<int>(floorf(point.x() / scale));
    int y = static_cast<int>(floorf(point.y() / scale));
    clip.setRect(x, y, x + 1, y + 1);

    bool contains = rgn.setPath(*path, clip);

    originalPath->setFillType(originalFillType);
    return contains;
}
コード例 #6
0
/*
 *  Modulo internal errors, this should always succeed *if* the matrix is downscaling
 *  (in this case, we have the inverse, so it succeeds if fInvMatrix is upscaling)
 */
bool SkDefaultBitmapControllerState::processMediumRequest(const SkBitmapProvider& provider) {
    SkASSERT(fQuality <= kMedium_SkFilterQuality);
    if (fQuality != kMedium_SkFilterQuality) {
        return false;
    }

    // Our default return state is to downgrade the request to Low, w/ or w/o setting fBitmap
    // to a valid bitmap.
    fQuality = kLow_SkFilterQuality;

    SkSize invScaleSize;
    if (!fInvMatrix.decomposeScale(&invScaleSize, nullptr)) {
        return false;
    }

    SkDestinationSurfaceColorMode colorMode = provider.dstColorSpace()
        ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
        : SkDestinationSurfaceColorMode::kLegacy;
    if (invScaleSize.width() > SK_Scalar1 || invScaleSize.height() > SK_Scalar1) {
        fCurrMip.reset(SkMipMapCache::FindAndRef(provider.makeCacheDesc(), colorMode));
        if (nullptr == fCurrMip.get()) {
            SkBitmap orig;
            if (!provider.asBitmap(&orig)) {
                return false;
            }
            fCurrMip.reset(SkMipMapCache::AddAndRef(orig, colorMode));
            if (nullptr == fCurrMip.get()) {
                return false;
            }
        }
        // diagnostic for a crasher...
        SkASSERT_RELEASE(fCurrMip->data());

        const SkSize scale = SkSize::Make(SkScalarInvert(invScaleSize.width()),
                                          SkScalarInvert(invScaleSize.height()));
        SkMipMap::Level level;
        if (fCurrMip->extractLevel(scale, &level)) {
            const SkSize& invScaleFixup = level.fScale;
            fInvMatrix.postScale(invScaleFixup.width(), invScaleFixup.height());

            // todo: if we could wrap the fCurrMip in a pixelref, then we could just install
            //       that here, and not need to explicitly track it ourselves.
            return fResultBitmap.installPixels(level.fPixmap);
        } else {
            // failed to extract, so release the mipmap
            fCurrMip.reset(nullptr);
        }
    }
    return false;
}
コード例 #7
0
ファイル: SkiaUtils.cpp プロジェクト: eriser/kdguigl
bool SkPathContainsPoint(SkPath* originalPath, const FloatPoint& point, SkPath::FillType ft)
{
	SkRegion rgn;
	SkRegion clip;

	SkPath::FillType originalFillType = originalPath->getFillType();

	const SkPath* path = originalPath;
	SkPath scaledPath;
	int scale = 1;

	SkRect bounds = originalPath->getBounds();

	// We can immediately return false if the point is outside the bounding
	// rect.  We don't use bounds.contains() here, since it would exclude
	// points on the right and bottom edges of the bounding rect, and we want
	// to include them.
	SkScalar fX = SkFloatToScalar(point.x());
	SkScalar fY = SkFloatToScalar(point.y());
	if (fX < bounds.fLeft || fX > bounds.fRight || fY < bounds.fTop || fY > bounds.fBottom)
		return false;

	originalPath->setFillType(ft);

	// Skia has trouble with coordinates close to the max signed 16-bit values
	// If we have those, we need to scale. 
	//
	// TODO: remove this code once Skia is patched to work properly with large
	// values
	const SkScalar kMaxCoordinate = SkIntToScalar(1<<15);
	SkScalar biggestCoord = std::max(std::max(std::max(bounds.fRight, bounds.fBottom), -bounds.fLeft), -bounds.fTop);

	if (biggestCoord > kMaxCoordinate) {
		scale = SkScalarCeil(SkScalarDiv(biggestCoord, kMaxCoordinate));

		SkMatrix m;
		m.setScale(SkScalarInvert(SkIntToScalar(scale)), SkScalarInvert(SkIntToScalar(scale)));
		originalPath->transform(m, &scaledPath);
		path = &scaledPath;
	}

	int x = static_cast<int>(floorf(point.x() / scale));
	int y = static_cast<int>(floorf(point.y() / scale));
	clip.setRect(x - 1, y - 1, x + 1, y + 1);

	bool contains = rgn.setPath(*path, clip);

	originalPath->setFillType(originalFillType);
	return contains;
}
SkPathStroker::SkPathStroker(const SkPath& src,
                             SkScalar radius, SkScalar miterLimit,
                             SkPaint::Cap cap, SkPaint::Join join)
        : fRadius(radius) {

    /*  This is only used when join is miter_join, but we initialize it here
        so that it is always defined, to fis valgrind warnings.
    */
    fInvMiterLimit = 0;

    if (join == SkPaint::kMiter_Join) {
        if (miterLimit <= SK_Scalar1) {
            join = SkPaint::kBevel_Join;
        } else {
            fInvMiterLimit = SkScalarInvert(miterLimit);
        }
    }
    fCapper = SkStrokerPriv::CapFactory(cap);
    fJoiner = SkStrokerPriv::JoinFactory(join);
    fSegmentCount = -1;
    fPrevIsLine = false;

    // Need some estimate of how large our final result (fOuter)
    // and our per-contour temp (fInner) will be, so we don't spend
    // extra time repeatedly growing these arrays.
    //
    // 3x for result == inner + outer + join (swag)
    // 1x for inner == 'wag' (worst contour length would be better guess)
    fOuter.incReserve(src.countPoints() * 3);
    fInner.incReserve(src.countPoints());
}
コード例 #9
0
ファイル: SkColorCubeFilter.cpp プロジェクト: amyvmiwei/skia
void GrColorCubeEffect::GLProcessor::setData(const GrGLProgramDataManager& pdman,
                                             const GrProcessor& proc) {
    const GrColorCubeEffect& colorCube = proc.cast<GrColorCubeEffect>();
    SkScalar size = SkIntToScalar(colorCube.colorCubeSize());
    pdman.set1f(fColorCubeSizeUni, SkScalarToFloat(size));
    pdman.set1f(fColorCubeInvSizeUni, SkScalarToFloat(SkScalarInvert(size)));
}
コード例 #10
0
bool SkMagnifierImageFilter::asFragmentProcessor(GrFragmentProcessor** fp,
                                                 GrProcessorDataManager* procDataManager,
                                                 GrTexture* texture, const SkMatrix&,
                                                 const SkIRect&bounds) const {
    if (fp) {
        SkScalar yOffset = texture->origin() == kTopLeft_GrSurfaceOrigin ? fSrcRect.y() :
           texture->height() - fSrcRect.height() * texture->height() / bounds.height()
                             - fSrcRect.y();
        int boundsY = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? bounds.y() :
                      (texture->height() - bounds.height());
        SkRect effectBounds = SkRect::MakeXYWH(
            SkIntToScalar(bounds.x()) / texture->width(),
            SkIntToScalar(boundsY) / texture->height(),
            SkIntToScalar(texture->width()) / bounds.width(),
            SkIntToScalar(texture->height()) / bounds.height());
        SkScalar invInset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1;
        *fp = GrMagnifierEffect::Create(procDataManager,
                                        texture,
                                        effectBounds,
                                        fSrcRect.x() / texture->width(),
                                        yOffset / texture->height(),
                                        fSrcRect.width() / bounds.width(),
                                        fSrcRect.height() / bounds.height(),
                                        bounds.width() * invInset,
                                        bounds.height() * invInset);
    }
    return true;
}
コード例 #11
0
ファイル: SkColorCubeFilter.cpp プロジェクト: amyvmiwei/skia
void SkColorCubeFilter::ColorCubeProcesingCache::initProcessingLuts(
    SkColorCubeFilter::ColorCubeProcesingCache* cache) {
    static const SkScalar inv8bit = SkScalarInvert(SkIntToScalar(255));

    // We need 256 int * 2 for fColorToIndex, so a total of 512 int.
    // We need 256 SkScalar * 2 for fColorToFactors and 256 SkScalar
    // for fColorToScalar, so a total of 768 SkScalar.
    cache->fLutStorage.reset(512 * sizeof(int) + 768 * sizeof(SkScalar));
    uint8_t* storage = (uint8_t*)cache->fLutStorage.get();
    cache->fColorToIndex[0] = (int*)storage;
    cache->fColorToIndex[1] = cache->fColorToIndex[0] + 256;
    cache->fColorToFactors[0] = (SkScalar*)(storage + (512 * sizeof(int)));
    cache->fColorToFactors[1] = cache->fColorToFactors[0] + 256;
    cache->fColorToScalar = cache->fColorToFactors[1] + 256;

    SkScalar size = SkIntToScalar(cache->fCubeDimension);
    SkScalar scale = (size - SK_Scalar1) * inv8bit;

    for (int i = 0; i < 256; ++i) {
        SkScalar index = scale * i;
        cache->fColorToIndex[0][i] = SkScalarFloorToInt(index);
        cache->fColorToIndex[1][i] = cache->fColorToIndex[0][i] + 1;
        cache->fColorToScalar[i] = inv8bit * i;
        if (cache->fColorToIndex[1][i] < cache->fCubeDimension) {
            cache->fColorToFactors[1][i] = index - SkIntToScalar(cache->fColorToIndex[0][i]);
            cache->fColorToFactors[0][i] = SK_Scalar1 - cache->fColorToFactors[1][i];
        } else {
            cache->fColorToIndex[1][i] = cache->fColorToIndex[0][i];
            cache->fColorToFactors[0][i] = SK_Scalar1;
            cache->fColorToFactors[1][i] = 0;
        }
    }
}
コード例 #12
0
bool SkBoundaryPatch::evalPatch(SkPoint verts[], int rows, int cols) {
    if (rows < 2 || cols < 2) {
        return false;
    }

    const SkScalar invR = SkScalarInvert(SkIntToScalar(rows - 1));
    const SkScalar invC = SkScalarInvert(SkIntToScalar(cols - 1));
    
    for (int y = 0; y < cols; y++) {
        SkScalar yy = y * invC;
        for (int x = 0; x < rows; x++) {
            *verts++ = this->eval(x * invR, yy);
        }
    }
    return true;
}
コード例 #13
0
ファイル: GrCircleEffect.cpp プロジェクト: google/skia
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {
        const GrCircleEffect& _outer = _proc.cast<GrCircleEffect>();
        auto edgeType = _outer.edgeType;
        (void)edgeType;
        auto center = _outer.center;
        (void)center;
        auto radius = _outer.radius;
        (void)radius;
        UniformHandle& circle = circleVar;
        (void)circle;

        if (radius != prevRadius || center != prevCenter) {
            SkScalar effectiveRadius = radius;
            if (GrProcessorEdgeTypeIsInverseFill((GrClipEdgeType)edgeType)) {
                effectiveRadius -= 0.5f;
                // When the radius is 0.5 effectiveRadius is 0 which causes an inf * 0 in the
                // shader.
                effectiveRadius = SkTMax(0.001f, effectiveRadius);
            } else {
                effectiveRadius += 0.5f;
            }
            pdman.set4f(circle, center.fX, center.fY, effectiveRadius,
                        SkScalarInvert(effectiveRadius));
            prevCenter = center;
            prevRadius = radius;
        }
    }
コード例 #14
0
ファイル: SkPDFShader.cpp プロジェクト: Dnnono/skia
/* Generate Type 4 function code to map t=[0,1) to the passed gradient,
   clamping at the edges of the range.  The generated code will be of the form:
       if (t < 0) {
           return colorData[0][r,g,b];
       } else {
           if (t < info.fColorOffsets[1]) {
               return linearinterpolation(colorData[0][r,g,b],
                                          colorData[1][r,g,b]);
           } else {
               if (t < info.fColorOffsets[2]) {
                   return linearinterpolation(colorData[1][r,g,b],
                                              colorData[2][r,g,b]);
               } else {

                ...    } else {
                           return colorData[info.fColorCount - 1][r,g,b];
                       }
                ...
           }
       }
 */
static void gradientFunctionCode(const SkShader::GradientInfo& info,
                                 SkString* result) {
    /* We want to linearly interpolate from the previous color to the next.
       Scale the colors from 0..255 to 0..1 and determine the multipliers
       for interpolation.
       C{r,g,b}(t, section) = t - offset_(section-1) + t * Multiplier{r,g,b}.
     */
    static const int kColorComponents = 3;
    typedef SkScalar ColorTuple[kColorComponents];
    SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(info.fColorCount);
    ColorTuple *colorData = colorDataAlloc.get();
    const SkScalar scale = SkScalarInvert(SkIntToScalar(255));
    for (int i = 0; i < info.fColorCount; i++) {
        colorData[i][0] = SkScalarMul(SkColorGetR(info.fColors[i]), scale);
        colorData[i][1] = SkScalarMul(SkColorGetG(info.fColors[i]), scale);
        colorData[i][2] = SkScalarMul(SkColorGetB(info.fColors[i]), scale);
    }

    // Clamp the initial color.
    result->append("dup 0 le {pop ");
    result->appendScalar(colorData[0][0]);
    result->append(" ");
    result->appendScalar(colorData[0][1]);
    result->append(" ");
    result->appendScalar(colorData[0][2]);
    result->append(" }\n");

    // The gradient colors.
    int gradients = 0;
    for (int i = 1 ; i < info.fColorCount; i++) {
        if (info.fColorOffsets[i] == info.fColorOffsets[i - 1]) {
            continue;
        }
        gradients++;

        result->append("{dup ");
        result->appendScalar(info.fColorOffsets[i]);
        result->append(" le {");
        if (info.fColorOffsets[i - 1] != 0) {
            result->appendScalar(info.fColorOffsets[i - 1]);
            result->append(" sub\n");
        }

        interpolateColorCode(info.fColorOffsets[i] - info.fColorOffsets[i - 1],
                             colorData[i], colorData[i - 1], result);
        result->append("}\n");
    }

    // Clamp the final color.
    result->append("{pop ");
    result->appendScalar(colorData[info.fColorCount - 1][0]);
    result->append(" ");
    result->appendScalar(colorData[info.fColorCount - 1][1]);
    result->append(" ");
    result->appendScalar(colorData[info.fColorCount - 1][2]);

    for (int i = 0 ; i < gradients + 1; i++) {
        result->append("} ifelse\n");
    }
}
コード例 #15
0
void computeDisplacement(Extractor ex, const SkVector& scale, SkBitmap* dst,
                         const SkBitmap& displ, const SkIPoint& offset,
                         const SkBitmap& src,
                         const SkIRect& bounds) {
    static const SkScalar Inv8bit = SkScalarInvert(255);
    const int srcW = src.width();
    const int srcH = src.height();
    const SkVector scaleForColor = SkVector::Make(scale.fX * Inv8bit, scale.fY * Inv8bit);
    const SkVector scaleAdj = SkVector::Make(SK_ScalarHalf - scale.fX * SK_ScalarHalf,
                                             SK_ScalarHalf - scale.fY * SK_ScalarHalf);
    SkPMColor* dstPtr = dst->getAddr32(0, 0);
    for (int y = bounds.top(); y < bounds.bottom(); ++y) {
        const SkPMColor* displPtr = displ.getAddr32(bounds.left() + offset.fX, y + offset.fY);
        for (int x = bounds.left(); x < bounds.right(); ++x, ++displPtr) {
            SkPMColor c = unpremul_pm(*displPtr);

            SkScalar displX = scaleForColor.fX * ex.getX(c) + scaleAdj.fX;
            SkScalar displY = scaleForColor.fY * ex.getY(c) + scaleAdj.fY;
            // Truncate the displacement values
            const int32_t srcX = Sk32_sat_add(x, SkScalarTruncToInt(displX));
            const int32_t srcY = Sk32_sat_add(y, SkScalarTruncToInt(displY));
            *dstPtr++ = ((srcX < 0) || (srcX >= srcW) || (srcY < 0) || (srcY >= srcH)) ?
                      0 : *(src.getAddr32(srcX, srcY));
        }
    }
}
コード例 #16
0
ファイル: SkGlyphCache.cpp プロジェクト: vschs007/skia
void SkGlyphCache::dump() const {
    const SkTypeface* face = fScalerContext->getTypeface();
    const SkScalerContextRec& rec = fScalerContext->getRec();
    SkMatrix matrix;
    rec.getSingleMatrix(&matrix);
    matrix.preScale(SkScalarInvert(rec.fTextSize), SkScalarInvert(rec.fTextSize));
    SkString name;
    face->getFamilyName(&name);

    SkString msg;
    SkFontStyle style = face->fontStyle();
    msg.printf("cache typeface:%x %25s:(%d,%d,%d)\n %s glyphs:%3d",
               face->uniqueID(), name.c_str(), style.weight(), style.width(), style.slant(),
               rec.dump().c_str(), fGlyphMap.count());
    SkDebugf("%s\n", msg.c_str());
}
コード例 #17
0
ファイル: imagefiltersclipped.cpp プロジェクト: google/skia
static void draw_clipped_filter(SkCanvas* canvas, sk_sp<SkImageFilter> filter, size_t i,
                                const SkRect& primBounds, const SkRect& clipBounds) {
    SkPaint paint;
    paint.setColor(SK_ColorWHITE);
    paint.setImageFilter(std::move(filter));
    paint.setAntiAlias(true);
    canvas->save();
    canvas->clipRect(clipBounds);
    if (5 == i) {
        canvas->translate(SkIntToScalar(16), SkIntToScalar(-32));
    } else if (6 == i) {
        canvas->scale(SkScalarInvert(RESIZE_FACTOR_X), SkScalarInvert(RESIZE_FACTOR_Y));
    }
    canvas->drawCircle(primBounds.centerX(), primBounds.centerY(),
                       primBounds.width() * 2 / 5, paint);
    canvas->restore();
}
コード例 #18
0
SkScalar SkSRGBLuminance::fromLuma(SkScalar luma) const {
    //The magic numbers are derived from the sRGB specification.
    //See http://www.color.org/chardata/rgb/srgb.xalter .
    if (luma <= SkFloatToScalar(0.0031308f)) {
        return luma * SkFloatToScalar(12.92f);
    }
    return SkFloatToScalar(1.055f) * SkScalarPow(luma, SkScalarInvert(SkFloatToScalar(2.4f)))
           - SkFloatToScalar(0.055f);
}
コード例 #19
0
ファイル: SkGlyphCache.cpp プロジェクト: alphan102/gecko-dev
void SkGlyphCache::dump() const {
    const SkTypeface* face = fScalerContext->getTypeface();
    const SkScalerContextRec& rec = fScalerContext->getRec();
    SkMatrix matrix;
    rec.getSingleMatrix(&matrix);
    matrix.preScale(SkScalarInvert(rec.fTextSize), SkScalarInvert(rec.fTextSize));
    SkString name;
    face->getFamilyName(&name);

    SkString msg;
    msg.printf("cache typeface:%x %25s:%d size:%2g [%g %g %g %g] lum:%02X devG:%d pntG:%d cntr:%d glyphs:%3d",
               face->uniqueID(), name.c_str(), face->style(), rec.fTextSize,
               matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewX],
               matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMScaleY],
               rec.fLumBits & 0xFF, rec.fDeviceGamma, rec.fPaintGamma, rec.fContrast,
               fGlyphMap.count());
    SkDebugf("%s\n", msg.c_str());
}
コード例 #20
0
ファイル: SkLinearGradient.cpp プロジェクト: jiezh/h5vcc
static void pts_to_unit_matrix(const SkPoint pts[2], SkMatrix* matrix) {
    SkVector    vec = pts[1] - pts[0];
    SkScalar    mag = vec.length();
    SkScalar    inv = mag ? SkScalarInvert(mag) : 0;

    vec.scale(inv);
    matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY);
    matrix->postTranslate(-pts[0].fX, -pts[0].fY);
    matrix->postScale(inv, inv);
}
コード例 #21
0
ファイル: SkPoint.cpp プロジェクト: kenlist/miniframework
SkScalar SkPoint::Normalize(SkPoint* pt) {
    SkScalar mag = SkPoint::Length(pt->fX, pt->fY);
    if (mag > SK_ScalarNearlyZero) {
        SkScalar scale = SkScalarInvert(mag);
        pt->fX = SkScalarMul(pt->fX, scale);
        pt->fY = SkScalarMul(pt->fY, scale);
        return mag;
    }
    return 0;
}
コード例 #22
0
ファイル: SkMaskGamma.cpp プロジェクト: 03050903/skia
 SkScalar fromLuma(SkScalar SkDEBUGCODE(gamma), SkScalar luma) const override {
     SkASSERT(0 == gamma);
     //The magic numbers are derived from the sRGB specification.
     //See http://www.color.org/chardata/rgb/srgb.xalter .
     if (luma <= 0.0031308f) {
         return luma * 12.92f;
     }
     return 1.055f * SkScalarPow(luma, SkScalarInvert(2.4f))
            - 0.055f;
 }
コード例 #23
0
static void unitToPointsMatrix(const SkPoint pts[2], SkMatrix* matrix) {
    SkVector    vec = pts[1] - pts[0];
    SkScalar    mag = vec.length();
    SkScalar    inv = mag ? SkScalarInvert(mag) : 0;

    vec.scale(inv);
    matrix->setSinCos(vec.fY, vec.fX);
    matrix->preTranslate(pts[0].fX, pts[0].fY);
    matrix->preScale(mag, mag);
}
コード例 #24
0
ファイル: SkPoint.cpp プロジェクト: jamorton/blix
SkScalar SkPoint::Normalize(SkPoint* pt) {
    Sk64 mag2;
    if (!isLengthNearlyZero(pt->fX, pt->fY, &mag2)) {
        SkScalar mag = mag2.getSqrt();
        SkScalar scale = SkScalarInvert(mag);
        pt->fX = SkScalarMul(pt->fX, scale);
        pt->fY = SkScalarMul(pt->fY, scale);
        return mag;
    }
    return 0;
}
コード例 #25
0
ファイル: SkLinearGradient.cpp プロジェクト: geekygenius/skia
static SkMatrix pts_to_unit_matrix(const SkPoint pts[2]) {
    SkVector    vec = pts[1] - pts[0];
    SkScalar    mag = vec.length();
    SkScalar    inv = mag ? SkScalarInvert(mag) : 0;

    vec.scale(inv);
    SkMatrix matrix;
    matrix.setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY);
    matrix.postTranslate(-pts[0].fX, -pts[0].fY);
    matrix.postScale(inv, inv);
    return matrix;
}
コード例 #26
0
ファイル: glyph_pos.cpp プロジェクト: pcwalton/skia
    void onDraw(SkCanvas* canvas) override {

        // There's a black pixel at 40, 40 for reference.
        canvas->drawPoint(40.0f, 40.0f, SK_ColorBLACK);

        // Two reference images.
        canvas->translate(50.0f, 50.0f);
        drawTestCase(canvas, 1.0f);

        canvas->translate(0.0f, 50.0f);
        drawTestCase(canvas, 3.0f);

        // Uniform scaling test.
        canvas->translate(0.0f, 100.0f);
        canvas->save();
        canvas->scale(3.0f, 3.0f);
        drawTestCase(canvas, 1.0f);
        canvas->restore();

        // Non-uniform scaling test.
        canvas->translate(0.0f, 100.0f);
        canvas->save();
        canvas->scale(3.0f, 6.0f);
        drawTestCase(canvas, 1.0f);
        canvas->restore();

        // Skew test.
        canvas->translate(0.0f, 80.0f);
        canvas->save();
        canvas->scale(3.0f, 3.0f);
        SkMatrix skew;
        skew.setIdentity();
        skew.setSkewX(8.0f / 25.0f);
        skew.setSkewY(2.0f / 25.0f);
        canvas->concat(skew);
        drawTestCase(canvas, 1.0f);
        canvas->restore();

        // Perspective test.
        canvas->translate(0.0f, 80.0f);
        canvas->save();
        SkMatrix perspective;
        perspective.setIdentity();
        perspective.setPerspX(-SkScalarInvert(340));
        perspective.setSkewX(8.0f / 25.0f);
        perspective.setSkewY(2.0f / 25.0f);


        canvas->concat(perspective);
        drawTestCase(canvas, 1.0f);
        canvas->restore();
    }
コード例 #27
0
ファイル: SkBitmapController.cpp プロジェクト: pk359/skia
/*
 *  Modulo internal errors, this should always succeed *if* the matrix is downscaling
 *  (in this case, we have the inverse, so it succeeds if fInvMatrix is upscaling)
 */
bool SkDefaultBitmapControllerState::processMediumRequest(const SkBitmapProvider& provider) {
    SkASSERT(fQuality <= kMedium_SkFilterQuality);
    if (fQuality != kMedium_SkFilterQuality) {
        return false;
    }

    // Our default return state is to downgrade the request to Low, w/ or w/o setting fBitmap
    // to a valid bitmap.
    fQuality = kLow_SkFilterQuality;

    SkSize invScaleSize;
    if (!fInvMatrix.decomposeScale(&invScaleSize, nullptr)) {
        return false;
    }

    // Use the largest (non-inverse) scale, to ensure anisotropic consistency.
    SkASSERT(invScaleSize.width() >= 0 && invScaleSize.height() >= 0);
    const SkScalar invScale = SkTMin(invScaleSize.width(), invScaleSize.height());

    if (invScale > SK_Scalar1) {
        fCurrMip.reset(SkMipMapCache::FindAndRef(provider.makeCacheDesc()));
        if (nullptr == fCurrMip.get()) {
            SkBitmap orig;
            if (!provider.asBitmap(&orig)) {
                return false;
            }
            fCurrMip.reset(SkMipMapCache::AddAndRef(orig));
            if (nullptr == fCurrMip.get()) {
                return false;
            }
        }
        // diagnostic for a crasher...
        if (nullptr == fCurrMip->data()) {
            sk_throw();
        }

        SkScalar levelScale = SkScalarInvert(invScale);
        SkMipMap::Level level;
        if (fCurrMip->extractLevel(levelScale, &level)) {
            const SkSize& invScaleFixup = level.fScale;
            fInvMatrix.postScale(invScaleFixup.width(), invScaleFixup.height());

            // todo: if we could wrap the fCurrMip in a pixelref, then we could just install
            //       that here, and not need to explicitly track it ourselves.
            return fResultBitmap.installPixels(level.fPixmap);
        } else {
            // failed to extract, so release the mipmap
            fCurrMip.reset(nullptr);
        }
    }
    return false;
}
コード例 #28
0
ファイル: GrDashingEffect.cpp プロジェクト: 3rdexp/soui
// calculates the rotation needed to aligned pts to the x axis with pts[0] < pts[1]
// Stores the rotation matrix in rotMatrix, and the mapped points in ptsRot
static void align_to_x_axis(const SkPoint pts[2], SkMatrix* rotMatrix, SkPoint ptsRot[2] = NULL) {
    SkVector vec = pts[1] - pts[0];
    SkScalar mag = vec.length();
    SkScalar inv = mag ? SkScalarInvert(mag) : 0;

    vec.scale(inv);
    rotMatrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY);
    if (ptsRot) {
        rotMatrix->mapPoints(ptsRot, pts, 2);
        // correction for numerical issues if map doesn't make ptsRot exactly horizontal
        ptsRot[1].fY = pts[0].fY;
    }
}
コード例 #29
0
/* Assumes t + startOffset is on the stack and does a linear interpolation on t
   between startOffset and endOffset from prevColor to curColor (for each color
   component), leaving the result in component order on the stack. It assumes
   there are always 3 components per color.
   @param range                  endOffset - startOffset
   @param curColor[components]   The current color components.
   @param prevColor[components]  The previous color components.
   @param result                 The result ps function.
 */
static void interpolate_color_code(SkScalar range, const ColorTuple& curColor,
                                   const ColorTuple& prevColor,
                                   SkDynamicMemoryWStream* result) {
    SkASSERT(range != SkIntToScalar(0));

    // Figure out how to scale each color component.
    SkScalar multiplier[kColorComponents];
    for (int i = 0; i < kColorComponents; i++) {
        static const SkScalar kColorScale = SkScalarInvert(255);
        multiplier[i] = kColorScale * (curColor[i] - prevColor[i]) / range;
    }

    // Calculate when we no longer need to keep a copy of the input parameter t.
    // If the last component to use t is i, then dupInput[0..i - 1] = true
    // and dupInput[i .. components] = false.
    bool dupInput[kColorComponents];
    dupInput[kColorComponents - 1] = false;
    for (int i = kColorComponents - 2; i >= 0; i--) {
        dupInput[i] = dupInput[i + 1] || multiplier[i + 1] != 0;
    }

    if (!dupInput[0] && multiplier[0] == 0) {
        result->writeText("pop ");
    }

    for (int i = 0; i < kColorComponents; i++) {
        // If the next components needs t and this component will consume a
        // copy, make another copy.
        if (dupInput[i] && multiplier[i] != 0) {
            result->writeText("dup ");
        }

        if (multiplier[i] == 0) {
            SkPDFUtils::AppendColorComponent(prevColor[i], result);
            result->writeText(" ");
        } else {
            if (multiplier[i] != 1) {
                SkPDFUtils::AppendScalar(multiplier[i], result);
                result->writeText(" mul ");
            }
            if (prevColor[i] != 0) {
                SkPDFUtils::AppendColorComponent(prevColor[i], result);
                result->writeText(" add ");
            }
        }

        if (dupInput[i]) {
            result->writeText("exch\n");
        }
    }
}
コード例 #30
0
ファイル: GrOvalEffect.cpp プロジェクト: webbjiang/skia
void GLCircleEffect::onSetData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
    const CircleEffect& ce = processor.cast<CircleEffect>();
    if (ce.getRadius() != fPrevRadius || ce.getCenter() != fPrevCenter) {
        SkScalar radius = ce.getRadius();
        if (GrProcessorEdgeTypeIsInverseFill(ce.getEdgeType())) {
            radius -= 0.5f;
        } else {
            radius += 0.5f;
        }
        pdman.set4f(fCircleUniform, ce.getCenter().fX, ce.getCenter().fY, radius,
                    SkScalarInvert(radius));
        fPrevCenter = ce.getCenter();
        fPrevRadius = ce.getRadius();
    }
}