Exemplo n.º 1
0
static SkShader* make_radial_gradient(const SkPoint pts[2], const SkMatrix& localMatrix) {
    SkPoint center;
    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
               SkScalarAve(pts[0].fY, pts[1].fY));
    float radius = (center - pts[0]).length();
    return SkGradientShader::CreateRadial(center, radius, gColors, NULL, SK_ARRAY_COUNT(gColors),
                                          SkShader::kClamp_TileMode, 0, &localMatrix);
}
Exemplo n.º 2
0
void SkAnnotateNamedDestination(SkCanvas* canvas, const SkPoint& point, SkData* name) {
    if (nullptr == name) {
        return;
    }
    SkPaint paint;
    annotate_paint(paint, SkAnnotationKeys::Define_Named_Dest_Key(), name);
    canvas->drawPoint(point.x(), point.y(), paint);
}
Exemplo n.º 3
0
static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
                           SkShader::TileMode, const SkMatrix& localMatrix) {
    SkPoint center;
    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
               SkScalarAve(pts[0].fY, pts[1].fY));
    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
                                         data.fPos, data.fCount, 0, &localMatrix);
}
Exemplo n.º 4
0
    virtual void onDraw(SkCanvas* canvas) {
        SkMatrix m;
        m.reset();
        m.setRotate(33 * SK_Scalar1);
        m.postScale(3000 * SK_Scalar1, 3000 * SK_Scalar1);
        m.postTranslate(6000 * SK_Scalar1, -5000 * SK_Scalar1);
        canvas->concat(m);

        SkPaint paint;
        paint.setColor(SK_ColorRED);
        paint.setAntiAlias(true);

        bool success = m.invert(&m);
        SkASSERT(success);
        (void) success; // silence compiler :(

        SkPath path;

        SkPoint pt = {10 * SK_Scalar1, 10 * SK_Scalar1};
        SkScalar small = 1 / (500 * SK_Scalar1);

        m.mapPoints(&pt, 1);
        path.addCircle(pt.fX, pt.fY, small);
        canvas->drawPath(path, paint);

        pt.set(30 * SK_Scalar1, 10 * SK_Scalar1);
        m.mapPoints(&pt, 1);
        SkRect rect = {pt.fX - small, pt.fY - small,
                       pt.fX + small, pt.fY + small};
        canvas->drawRect(rect, paint);

        SkBitmap bmp;
        bmp.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
        bmp.allocPixels();
        bmp.lockPixels();
        uint32_t* pixels = reinterpret_cast<uint32_t*>(bmp.getPixels());
        pixels[0] = SkPackARGB32(0xFF, 0xFF, 0x00, 0x00);
        pixels[1] = SkPackARGB32(0xFF, 0x00, 0xFF, 0x00);
        pixels[2] = SkPackARGB32(0x80, 0x00, 0x00, 0x00);
        pixels[3] = SkPackARGB32(0xFF, 0x00, 0x00, 0xFF);
        bmp.unlockPixels();
        pt.set(30 * SK_Scalar1, 30 * SK_Scalar1);
        m.mapPoints(&pt, 1);
        SkShader* shader = SkShader::CreateBitmapShader(
                                            bmp,
                                            SkShader::kRepeat_TileMode,
                                            SkShader::kRepeat_TileMode);
        SkMatrix s;
        s.reset();
        s.setScale(SK_Scalar1 / 1000, SK_Scalar1 / 1000);
        shader->setLocalMatrix(s);
        paint.setShader(shader)->unref();
        paint.setAntiAlias(false);
        paint.setFilterLevel(SkPaint::kLow_FilterLevel);
        rect.setLTRB(pt.fX - small, pt.fY - small,
                     pt.fX + small, pt.fY + small);
        canvas->drawRect(rect, paint);
    }
Exemplo n.º 5
0
/// Ignores scale
static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
                           SkShader::TileMode tm, SkUnitMapper* mapper,
                           float scale) {
    SkPoint center;
    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
               SkScalarAve(pts[0].fY, pts[1].fY));
    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
                                         data.fPos, data.fCount, mapper);
}
 void onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) override
 {
     if (!paint.getAnnotation())
         return;
     ASSERT_EQ(1u, count); // Only called from drawPoint().
     SkPoint point = getTotalMatrix().mapXY(pts[0].x(), pts[0].y());
     Operation operation = { DrawPoint, SkRect::MakeXYWH(point.x(), point.y(), 0, 0) };
     m_recordedOperations.append(operation);
 }
Exemplo n.º 7
0
static sk_sp<SkShader> MakeSweep4f(const SkPoint pts[2], const GradData& data,
                                   SkShader::TileMode, const SkMatrix& localMatrix) {
    SkPoint center;
    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
               SkScalarAve(pts[0].fY, pts[1].fY));
    auto srgb = SkColorSpace::MakeSRGBLinear();
    return SkGradientShader::MakeSweep(center.fX, center.fY, data.fColors4f, srgb, data.fPos,
                                       data.fCount, 0, &localMatrix);
}
Exemplo n.º 8
0
SkFlattenable* SkSweepGradient::CreateProc(SkReadBuffer& buffer) {
    DescriptorScope desc;
    if (!desc.unflatten(buffer)) {
        return NULL;
    }
    const SkPoint center = buffer.readPoint();
    return SkGradientShader::CreateSweep(center.x(), center.y(), desc.fColors, desc.fPos,
                                         desc.fCount, desc.fGradFlags, desc.fLocalMatrix);
}
Exemplo n.º 9
0
SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::noise2D(
        int channel, const StitchData& stitchData, const SkPoint& noiseVector) const {
    struct Noise {
        int noisePositionIntegerValue;
        int nextNoisePositionIntegerValue;
        SkScalar noisePositionFractionValue;
        Noise(SkScalar component)
        {
            SkScalar position = component + kPerlinNoise;
            noisePositionIntegerValue = SkScalarFloorToInt(position);
            noisePositionFractionValue = position - SkIntToScalar(noisePositionIntegerValue);
            nextNoisePositionIntegerValue = noisePositionIntegerValue + 1;
        }
    };
    Noise noiseX(noiseVector.x());
    Noise noiseY(noiseVector.y());
    SkScalar u, v;
    const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoiseShader&>(fShader);
    // If stitching, adjust lattice points accordingly.
    if (perlinNoiseShader.fStitchTiles) {
        noiseX.noisePositionIntegerValue =
            checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth);
        noiseY.noisePositionIntegerValue =
            checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight);
        noiseX.nextNoisePositionIntegerValue =
            checkNoise(noiseX.nextNoisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth);
        noiseY.nextNoisePositionIntegerValue =
            checkNoise(noiseY.nextNoisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight);
    }
    noiseX.noisePositionIntegerValue &= kBlockMask;
    noiseY.noisePositionIntegerValue &= kBlockMask;
    noiseX.nextNoisePositionIntegerValue &= kBlockMask;
    noiseY.nextNoisePositionIntegerValue &= kBlockMask;
    int i =
        fPaintingData->fLatticeSelector[noiseX.noisePositionIntegerValue];
    int j =
        fPaintingData->fLatticeSelector[noiseX.nextNoisePositionIntegerValue];
    int b00 = (i + noiseY.noisePositionIntegerValue) & kBlockMask;
    int b10 = (j + noiseY.noisePositionIntegerValue) & kBlockMask;
    int b01 = (i + noiseY.nextNoisePositionIntegerValue) & kBlockMask;
    int b11 = (j + noiseY.nextNoisePositionIntegerValue) & kBlockMask;
    SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue);
    SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue);
    // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement
    SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue,
                                          noiseY.noisePositionFractionValue); // Offset (0,0)
    u = fPaintingData->fGradient[channel][b00].dot(fractionValue);
    fractionValue.fX -= SK_Scalar1; // Offset (-1,0)
    v = fPaintingData->fGradient[channel][b10].dot(fractionValue);
    SkScalar a = SkScalarInterp(u, v, sx);
    fractionValue.fY -= SK_Scalar1; // Offset (-1,-1)
    v = fPaintingData->fGradient[channel][b11].dot(fractionValue);
    fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1)
    u = fPaintingData->fGradient[channel][b01].dot(fractionValue);
    SkScalar b = SkScalarInterp(u, v, sx);
    return SkScalarInterp(a, b, sy);
}
Exemplo n.º 10
0
static void draw_label(SkCanvas* canvas, const char* label,
                       const SkPoint& offset) {
    SkPaint paint;
    size_t len = strlen(label);

    SkScalar width = paint.measureText(label, len);
    canvas->drawText(label, len, offset.x() - width / 2, offset.y(),
                     paint);
}
Exemplo n.º 11
0
    void onPrepareDraws(Target* target) override {
        SkAutoTUnref<const GrGeometryProcessor> gp(create_gp(fOverrides.readsCoverage()));
        if (!gp) {
            SkDebugf("Couldn't create GrGeometryProcessor\n");
            return;
        }

        target->initDraw(gp, this->pipeline());

        size_t vertexStride = gp->getVertexStride();
        int instanceCount = fGeoData.count();

        SkAutoTUnref<const GrIndexBuffer> indexBuffer(
                target->resourceProvider()->refQuadIndexBuffer());
        InstancedHelper helper;
        void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride,
                                     indexBuffer, kVertsPerRect,
                                     kIndicesPerRect, instanceCount * kRectsPerInstance);
        if (!vertices || !indexBuffer) {
            SkDebugf("Could not allocate vertices\n");
            return;
        }

        for (int i = 0; i < instanceCount; i++) {
            intptr_t verts = reinterpret_cast<intptr_t>(vertices) +
                             i * kRectsPerInstance * kVertsPerRect * vertexStride;

            Geometry& geo = fGeoData[i];
            SkNinePatchIter iter(fImageWidth, fImageHeight, geo.fCenter, geo.fDst);

            SkRect srcR, dstR;
            while (iter.next(&srcR, &dstR)) {
                SkPoint* positions = reinterpret_cast<SkPoint*>(verts);

                positions->setRectFan(dstR.fLeft, dstR.fTop,
                                      dstR.fRight, dstR.fBottom, vertexStride);

                SkASSERT(!geo.fViewMatrix.hasPerspective());
                geo.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerRect);

                // Setup local coords
                static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
                SkPoint* coords = reinterpret_cast<SkPoint*>(verts + kLocalOffset);
                coords->setRectFan(srcR.fLeft, srcR.fTop, srcR.fRight, srcR.fBottom, vertexStride);

                static const int kColorOffset = sizeof(SkPoint);
                GrColor* vertColor = reinterpret_cast<GrColor*>(verts + kColorOffset);
                for (int j = 0; j < 4; ++j) {
                    *vertColor = geo.fColor;
                    vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
                }
                verts += kVertsPerRect * vertexStride;
            }
        }
        helper.recordDraw(target);
    }
Exemplo n.º 12
0
static SkShader* Make2ConicalConcentric(const SkPoint pts[2], const GradData& data,
                                       SkShader::TileMode tm) {
    SkPoint center;
    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
               SkScalarAve(pts[0].fY, pts[1].fY));
    return SkGradientShader::CreateTwoPointConical(
                            center, (pts[1].fX - pts[0].fX) / 7,
                            center, (pts[1].fX - pts[0].fX) / 2,
                            data.fColors, data.fPos, data.fCount, tm);
}
Exemplo n.º 13
0
        void updateDom() {
            const SkPoint corner = pos - SkPoint::Make(size.width() / 2, size.height() / 2);
            update_pos(objectNode, corner);

            // Simulate parallax shadow for a centered light source.
            SkPoint shadowOffset = pos - SkPoint::Make(kBounds.centerX(), kBounds.centerY());
            shadowOffset.scale(kShadowParallax);
            const SkPoint shadowCorner = corner + shadowOffset;

            update_pos(shadowNode, shadowCorner);
        }
Exemplo n.º 14
0
    void generateGeometry(GrBatchTarget* batchTarget) override {
        SkAutoTUnref<const GrGeometryProcessor> gp(this->createRectGP());
        if (!gp) {
            SkDebugf("Could not create GrGeometryProcessor\n");
            return;
        }

        batchTarget->initDraw(gp, this->pipeline());

        int instanceCount = fGeoData.count();
        size_t vertexStride = gp->getVertexStride();
        SkASSERT(this->hasLocalRect() ?
                 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
                 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
        QuadHelper helper;
        void* vertices = helper.init(batchTarget, vertexStride, instanceCount);

        if (!vertices) {
            return;
        }

        for (int i = 0; i < instanceCount; i++) {
            const Geometry& geom = fGeoData[i];

            intptr_t offset = reinterpret_cast<intptr_t>(vertices) +
                              kVerticesPerQuad * i * vertexStride;
            SkPoint* positions = reinterpret_cast<SkPoint*>(offset);

            positions->setRectFan(geom.fRect.fLeft, geom.fRect.fTop,
                                  geom.fRect.fRight, geom.fRect.fBottom, vertexStride);
            geom.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVerticesPerQuad);

            // TODO we should only do this if local coords are being read
            if (geom.fHasLocalRect) {
                static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
                SkPoint* coords = reinterpret_cast<SkPoint*>(offset + kLocalOffset);
                coords->setRectFan(geom.fLocalRect.fLeft, geom.fLocalRect.fTop,
                                   geom.fLocalRect.fRight, geom.fLocalRect.fBottom,
                                   vertexStride);
                if (geom.fHasLocalMatrix) {
                    geom.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVerticesPerQuad);
                }
            }

            static const int kColorOffset = sizeof(SkPoint);
            GrColor* vertColor = reinterpret_cast<GrColor*>(offset + kColorOffset);
            for (int j = 0; j < 4; ++j) {
                *vertColor = geom.fColor;
                vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
            }
        }

        helper.issueDraw(batchTarget);
    }
Exemplo n.º 15
0
SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatrix* localM) const {
    SkASSERT(fPicture && fPicture->width() > 0 && fPicture->height() > 0);

    SkMatrix m;
    m.setConcat(matrix, this->getLocalMatrix());
    if (localM) {
        m.preConcat(*localM);
    }

    // Use a rotation-invariant scale
    SkPoint scale;
    if (!SkDecomposeUpper2x2(m, NULL, &scale, NULL)) {
        // Decomposition failed, use an approximation.
        scale.set(SkScalarSqrt(m.getScaleX() * m.getScaleX() + m.getSkewX() * m.getSkewX()),
                  SkScalarSqrt(m.getScaleY() * m.getScaleY() + m.getSkewY() * m.getSkewY()));
    }
    SkSize scaledSize = SkSize::Make(scale.x() * fPicture->width(), scale.y() * fPicture->height());

    SkISize tileSize = scaledSize.toRound();
    if (tileSize.isEmpty()) {
        return NULL;
    }

    // The actual scale, compensating for rounding.
    SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fPicture->width(),
                                    SkIntToScalar(tileSize.height()) / fPicture->height());

    SkAutoMutexAcquire ama(fCachedBitmapShaderMutex);

    if (!fCachedBitmapShader || tileScale != fCachedTileScale) {
        SkBitmap bm;
        if (!bm.allocN32Pixels(tileSize.width(), tileSize.height())) {
            return NULL;
        }
        bm.eraseColor(SK_ColorTRANSPARENT);

        SkCanvas canvas(bm);
        canvas.scale(tileScale.width(), tileScale.height());
        canvas.drawPicture(fPicture);

        fCachedTileScale = tileScale;

        SkMatrix shaderMatrix = this->getLocalMatrix();
        shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height());
        fCachedBitmapShader.reset(CreateBitmapShader(bm, fTmx, fTmy, &shaderMatrix));
    }

    // Increment the ref counter inside the mutex to ensure the returned pointer is still valid.
    // Otherwise, the pointer may have been overwritten on a different thread before the object's
    // ref count was incremented.
    fCachedBitmapShader.get()->ref();
    return fCachedBitmapShader;
}
inline void GrStencilAndCoverTextContext::appendGlyph(const SkGlyph& glyph, const SkPoint& pos) {
    if (fQueuedGlyphCount >= fFallbackGlyphsIdx) {
        SkASSERT(fQueuedGlyphCount == fFallbackGlyphsIdx);
        this->flush();
    }

    // Stick the glyphs we can't draw at the end of the buffer, growing backwards.
    int index = (SkMask::kARGB32_Format == glyph.fMaskFormat) ?
                --fFallbackGlyphsIdx : fQueuedGlyphCount++;

    fGlyphIndices[index] = glyph.getGlyphID();
    fGlyphPositions[index].set(fTextInverseRatio * pos.x(), -fTextInverseRatio * pos.y());
}
Exemplo n.º 17
0
 void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) override
 {
     if (rect.width() == 0 && rect.height() == 0) {
         SkPoint point = getTotalMatrix().mapXY(rect.x(), rect.y());
         Operation operation = {
             DrawPoint, SkRect::MakeXYWH(point.x(), point.y(), 0, 0) };
         m_recordedOperations.append(operation);
     } else {
         Operation operation = { DrawRect, rect };
         getTotalMatrix().mapRect(&operation.rect);
         m_recordedOperations.append(operation);
     }
 }
    void onDrawContent(SkCanvas* canvas) override {
        SkScalar trans[2];
        fTrans.timeToValues(SkTime::GetMSecs(), trans);

        SkPoint offset;
        offset.set(trans[0], trans[1]);

        int saveCount = canvas->save();
        this->drawGeometry(canvas, offset, false);
        canvas->restoreToCount(saveCount);

        this->inval(nullptr);
    }
Exemplo n.º 19
0
/* Used by bloat_tri; outsets a single point. */
static bool outset(SkPoint* p1, SkPoint line1, SkPoint line2) {
    // rotate the two line vectors 90 degrees to form the normals, and compute
    // the dot product of the normals
    SkScalar dotProd = line1.fY * line2.fY + line1.fX * line2.fX;
    SkScalar lengthSq = 1.0f / ((1.0f - dotProd) / 2.0f);
    if (lengthSq > kBloatLimit) {
        return false;
    }
    SkPoint bisector = line1 + line2;
    bisector.setLength(SkScalarSqrt(lengthSq) * kBloatSize);
    *p1 += bisector;
    return true;
}
Exemplo n.º 20
0
    SkPath quadPath(SkPoint p1, SkPoint p2) {
        SkASSERT(p1.y() == p2.y());

        SkPath path;
        path.moveTo(p1);
        path.lineTo(p2);

        SkPoint p3 = SkPoint::Make((p1.x() + p2.x()) / 2.0f, p1.y() * 0.7f);

        path.quadTo(p3, p1);

        return path;
    }
Exemplo n.º 21
0
mbe_pattern_t *
mbe_pattern_create_radial(co_aix cx0, co_aix cy0, co_aix radius0,
			  co_aix cx1, co_aix cy1, co_aix radius1,
			  grad_stop_t *stops, int stop_cnt) {
    mbe_pattern_t *ptn;
    SkColor *colors;
    SkScalar *poses;
    grad_stop_t *stop;
    SkPoint center;
    int i;

    ptn = (mbe_pattern_t *)malloc(sizeof(mbe_pattern_t));
    colors = new SkColor[stop_cnt];
    poses = new SkScalar[stop_cnt];
    if(ptn == NULL || colors == NULL || poses == NULL)
	goto fail;

    center.set(CO_AIX_2_SKSCALAR(cx1), CO_AIX_2_SKSCALAR(cy1));

    stop = stops;
    for(i = 0; i < stop_cnt; i++) {
	colors[i] = MBSTOP_2_SKCOLOR(stop);
	poses[i] = CO_AIX_2_SKSCALAR(stop->offset);
    }

    /*
     * cx0, cy0 and radius0 is not used.  Since Skia is still not
     * support two circles radial.  And, SVG 1.2 is also not support
     * two circles.
     */
    ptn->shader =
	SkGradientShader::CreateRadial(center, CO_AIX_2_SKSCALAR(radius1),
				       colors, poses, stop_cnt,
				       SkShader::kClamp_TileMode);
    if(ptn->shader == NULL)
	goto fail;

    memcpy(ptn->matrix, id_matrix, sizeof(co_aix) * 6);
    
    ptn->bitmap = NULL;

    delete colors;
    delete poses;
    return ptn;

 fail:
    if(ptn) free(ptn);
    if(colors) delete colors;
    if(poses) delete poses;
    return NULL;
}
inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& glyph,
                                                               const SkPoint& pos,
                                                               FallbackBlobBuilder* fallback) {
    // Stick the glyphs we can't draw into the fallback text blob.
    if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
        if (!fallback->isInitialized()) {
            fallback->init(fFont, fTextRatio);
        }
        fallback->appendGlyph(glyph.getGlyphID(), pos);
    } else {
        fInstanceData->append(glyph.getGlyphID(), fTextInverseRatio * pos.x(),
                              fTextInverseRatio * pos.y());
    }
}
static jlong RadialGradient_create2(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat radius,
        jint color0, jint color1, jint tileMode) {
    SkPoint center;
    center.set(x, y);

    SkColor colors[2];
    colors[0] = color0;
    colors[1] = color1;

    SkShader* s = SkGradientShader::CreateRadial(center, radius, colors, NULL, 2,
            (SkShader::TileMode)tileMode);
    ThrowIAE_IfNull(env, s);
    return reinterpret_cast<jlong>(s);
}
Exemplo n.º 24
0
static void center_of_mass(const SegmentArray& segments, SkPoint* c) {
    SkScalar area = 0;
    SkPoint center = {0, 0};
    int count = segments.count();
    SkPoint p0 = {0, 0};
    if (count > 2) {
        // We translate the polygon so that the first point is at the origin.
        // This avoids some precision issues with small area polygons far away
        // from the origin.
        p0 = segments[0].endPt();
        SkPoint pi;
        SkPoint pj;
        // the first and last iteration of the below loop would compute
        // zeros since the starting / ending point is (0,0). So instead we start
        // at i=1 and make the last iteration i=count-2.
        pj = segments[1].endPt() - p0;
        for (int i = 1; i < count - 1; ++i) {
            pi = pj;
            const SkPoint pj = segments[i + 1].endPt() - p0;

            SkScalar t = SkScalarMul(pi.fX, pj.fY) - SkScalarMul(pj.fX, pi.fY);
            area += t;
            center.fX += (pi.fX + pj.fX) * t;
            center.fY += (pi.fY + pj.fY) * t;

        }
    }
    // If the poly has no area then we instead return the average of
    // its points.
    if (SkScalarNearlyZero(area)) {
        SkPoint avg;
        avg.set(0, 0);
        for (int i = 0; i < count; ++i) {
            const SkPoint& pt = segments[i].endPt();
            avg.fX += pt.fX;
            avg.fY += pt.fY;
        }
        SkScalar denom = SK_Scalar1 / count;
        avg.scale(denom);
        *c = avg;
    } else {
        area *= 3;
        area = SkScalarDiv(SK_Scalar1, area);
        center.fX = SkScalarMul(center.fX, area);
        center.fY = SkScalarMul(center.fY, area);
        // undo the translate of p0 to the origin.
        *c = center + p0;
    }
    SkASSERT(!SkScalarIsNaN(c->fX) && !SkScalarIsNaN(c->fY));
}
Exemplo n.º 25
0
void SkLinearGradient::
LinearGradient4fContext::shadeSpanInternal(int x, int y, dstType dst[], int count,
                                           float bias0, float bias1) const {
    SkPoint pt;
    fDstToPosProc(fDstToPos,
                  x + SK_ScalarHalf,
                  y + SK_ScalarHalf,
                  &pt);
    const SkScalar fx = pinFx<tileMode>(pt.x());
    const SkScalar dx = fDstToPos.getScaleX();
    LinearIntervalProcessor<dstType, premul, tileMode> proc(fIntervals->begin(),
                                                            fIntervals->end() - 1,
                                                            this->findInterval(fx),
                                                            fx,
                                                            dx,
                                                            SkScalarNearlyZero(dx * count));
    Sk4f bias4f0(bias0),
         bias4f1(bias1);

    while (count > 0) {
        // What we really want here is SkTPin(advance, 1, count)
        // but that's a significant perf hit for >> stops; investigate.
        const int n = SkScalarTruncToInt(
            SkTMin<SkScalar>(proc.currentAdvance() + 1, SkIntToScalar(count)));

        // The current interval advance can be +inf (e.g. when reaching
        // the clamp mode end intervals) - when that happens, we expect to
        //   a) consume all remaining count in one swoop
        //   b) return a zero color gradient
        SkASSERT(SkScalarIsFinite(proc.currentAdvance())
            || (n == count && proc.currentRampIsZero()));

        if (proc.currentRampIsZero()) {
            DstTraits<dstType, premul>::store(proc.currentColor(), dst, n);
        } else {
            ramp<dstType, premul>(proc.currentColor(), proc.currentColorGrad(), dst, n,
                                  bias4f0, bias4f1);
        }

        proc.advance(SkIntToScalar(n));
        count -= n;
        dst   += n;

        if (n & 1) {
            SkTSwap(bias4f0, bias4f1);
        }
    }
}
Exemplo n.º 26
0
    void onOnceBeforeDraw() override {
        SkRandom    rand;
        int         steps = 20;
        SkScalar    dist = SkIntToScalar(400);
        SkScalar    x = SkIntToScalar(20);
        SkScalar    y = SkIntToScalar(50);

        fPath.moveTo(x, y);
        for (int i = 0; i < steps; i++) {
            x += dist/steps;
            SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25);
            if (i == steps/2) {
                fPath.moveTo(x, tmpY);
            } else {
                fPath.lineTo(x, tmpY);
            }
        }

        {
            SkRect  oval;
            oval.set(SkIntToScalar(20), SkIntToScalar(30),
                     SkIntToScalar(100), SkIntToScalar(60));
            oval.offset(x, 0);
            fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8));
        }

        fClickPt.set(SkIntToScalar(200), SkIntToScalar(200));

        this->setBGColor(0xFFDDDDDD);
    }
Exemplo n.º 27
0
SkScalar SkPoint::distanceToLineSegmentBetweenSqd(const SkPoint& a,
                                                  const SkPoint& b) const {
    // See comments to distanceToLineBetweenSqd. If the projection of c onto
    // u is between a and b then this returns the same result as that
    // function. Otherwise, it returns the distance to the closer of a and
    // b. Let the projection of v onto u be v'.  There are three cases:
    //    1. v' points opposite to u. c is not between a and b and is closer
    //       to a than b.
    //    2. v' points along u and has magnitude less than y. c is between
    //       a and b and the distance to the segment is the same as distance
    //       to the line ab.
    //    3. v' points along u and has greater magnitude than u. c is not
    //       not between a and b and is closer to b than a.
    // v' = (u dot v) * u / |u|. So if (u dot v)/|u| is less than zero we're
    // in case 1. If (u dot v)/|u| is > |u| we are in case 3. Otherwise
    // we're in case 2. We actually compare (u dot v) to 0 and |u|^2 to
    // avoid a sqrt to compute |u|.

    SkVector u = b - a;
    SkVector v = *this - a;

    SkScalar uLengthSqd = u.lengthSqd();
    SkScalar uDotV = SkPoint::DotProduct(u, v);

    if (uDotV <= 0) {
        return v.lengthSqd();
    } else if (uDotV > uLengthSqd) {
        return b.distanceToSqd(*this);
    } else {
        SkScalar det = u.cross(v);
        return SkScalarMulDiv(det, det, uLengthSqd);
    }
}
Exemplo n.º 28
0
	PathEffectView()
    {
        SkRandom    rand;
        int         steps = 20;
        SkScalar    dist = SkIntToScalar(400);
        SkScalar    x = SkIntToScalar(20);
        SkScalar    y = SkIntToScalar(50);
        
        fPath.moveTo(x, y);
        for (int i = 0; i < steps; i++)
        {
            x += dist/steps;
            SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25);
            if (i == steps/2) {
                fPath.moveTo(x, tmpY);
            } else {
                fPath.lineTo(x, tmpY);
            }
        }

        {
            SkRect  oval;
            oval.set(SkIntToScalar(20), SkIntToScalar(30),
                     SkIntToScalar(100), SkIntToScalar(60));
            oval.offset(x, 0);
            fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8));
        }
        
        fClickPt.set(SkIntToScalar(200), SkIntToScalar(200));
    }
Exemplo n.º 29
0
static SkShader* RadialGradient_create2(JNIEnv* env, jobject,
                                        float x, float y, float radius,
                                        int color0, int color1, int tileMode)
{
    SkPoint center;
    center.set(SkFloatToScalar(x), SkFloatToScalar(y));

    SkColor colors[2];
    colors[0] = color0;
    colors[1] = color1;

    SkShader* s = SkGradientShader::CreateRadial(center, SkFloatToScalar(radius), colors, NULL,
                                          2, (SkShader::TileMode)tileMode);
    ThrowIAE_IfNull(env, s);
    return s;
}
Exemplo n.º 30
0
static void update_degenerate_test(DegenerateTestData* data, const SkPoint& pt) {
    switch (data->fStage) {
        case DegenerateTestData::kInitial:
            data->fFirstPoint = pt;
            data->fStage = DegenerateTestData::kPoint;
            break;
        case DegenerateTestData::kPoint:
            if (pt.distanceToSqd(data->fFirstPoint) > kCloseSqd) {
                data->fLineNormal = pt - data->fFirstPoint;
                data->fLineNormal.normalize();
                data->fLineNormal.setOrthog(data->fLineNormal);
                data->fLineC = -data->fLineNormal.dot(data->fFirstPoint);
                data->fStage = DegenerateTestData::kLine;
            }
            break;
        case DegenerateTestData::kLine:
            if (SkScalarAbs(data->fLineNormal.dot(pt) + data->fLineC) > kClose) {
                data->fStage = DegenerateTestData::kNonDegenerate;
            }
        case DegenerateTestData::kNonDegenerate:
            break;
        default:
            SkFAIL("Unexpected degenerate test stage.");
    }
}