Ejemplo n.º 1
0
    virtual void onDraw(SkCanvas* canvas) {
        const char* lcd_text = "LCD";
        const char* gray_text = "GRAY";

        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setLCDRenderText(true);

        const struct {
            SkPoint     fLoc;
            SkScalar    fTextSize;
            SkScalar    fScale;
            const char* fText;
        } rec[] = {
            { {  10,  50 }, kLCDTextSizeLimit - 1,     1,  lcd_text },
            { { 160,  50 }, kLCDTextSizeLimit + 1,     1,  gray_text },
            { {  10, 100 }, kLCDTextSizeLimit / 2, 1.99f,  lcd_text },
            { { 160, 100 }, kLCDTextSizeLimit / 2, 2.01f,  gray_text },
        };

        for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
            const SkPoint loc = rec[i].fLoc;
            SkAutoCanvasRestore acr(canvas, true);

            paint.setTextSize(rec[i].fTextSize);
            ScaleAbout(canvas, rec[i].fScale, rec[i].fScale, loc.x(), loc.y());
            canvas->drawString(rec[i].fText, loc.x(), loc.y(), paint);
        }
    }
Ejemplo n.º 2
0
    void drawSceneColumn(SkCanvas* canvas, const SkPoint& pos, SkScalar scale, SkScalar localScale,
                         unsigned tileMode) {
        SkMatrix ctm, localMatrix;

        ctm.setTranslate(pos.x(), pos.y());
        ctm.preScale(scale, scale);
        localMatrix.setScale(localScale, localScale);
        this->drawScene(canvas, ctm, localMatrix, tileMode);

        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 1.2f * scale);
        ctm.preScale(scale, scale);
        localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
        localMatrix.preScale(localScale, localScale);
        this->drawScene(canvas, ctm, localMatrix, tileMode);

        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 2.4f * scale);
        ctm.preScale(scale, scale);
        localMatrix.setRotate(45);
        localMatrix.preScale(localScale, localScale);
        this->drawScene(canvas, ctm, localMatrix, tileMode);

        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 3.6f * scale);
        ctm.preScale(scale, scale);
        localMatrix.setSkew(1, 0);
        localMatrix.preScale(localScale, localScale);
        this->drawScene(canvas, ctm, localMatrix, tileMode);

        ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 4.8f * scale);
        ctm.preScale(scale, scale);
        localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
        localMatrix.preRotate(45);
        localMatrix.preScale(localScale, localScale);
        this->drawScene(canvas, ctm, localMatrix, tileMode);
    }
Ejemplo n.º 3
0
    /**
     * Called on a background thread. Here we can only modify fBackPaths.
     */
    void runAnimationTask(double t, double dt, int w, int h) override {
        const float tsec = static_cast<float>(t);
        this->INHERITED::runAnimationTask(t, 0.5 * dt, w, h);

        for (int i = 0; i < kNumPaths; ++i) {
            const Glyph& glyph = fGlyphs[i];
            const SkMatrix& backMatrix = fBackMatrices[i];

            const Sk2f matrix[3] = {
                Sk2f(backMatrix.getScaleX(), backMatrix.getSkewY()),
                Sk2f(backMatrix.getSkewX(), backMatrix.getScaleY()),
                Sk2f(backMatrix.getTranslateX(), backMatrix.getTranslateY())
            };

            SkPath* backpath = &fBackPaths[i];
            backpath->reset();
            backpath->setFillType(SkPath::kEvenOdd_FillType);

            SkPath::RawIter iter(glyph.fPath);
            SkPath::Verb verb;
            SkPoint pts[4];

            while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
                switch (verb) {
                    case SkPath::kMove_Verb: {
                        SkPoint pt = fWaves.apply(tsec, matrix, pts[0]);
                        backpath->moveTo(pt.x(), pt.y());
                        break;
                    }
                    case SkPath::kLine_Verb: {
                        SkPoint endpt = fWaves.apply(tsec, matrix, pts[1]);
                        backpath->lineTo(endpt.x(), endpt.y());
                        break;
                    }
                    case SkPath::kQuad_Verb: {
                        SkPoint controlPt = fWaves.apply(tsec, matrix, pts[1]);
                        SkPoint endpt = fWaves.apply(tsec, matrix, pts[2]);
                        backpath->quadTo(controlPt.x(), controlPt.y(), endpt.x(), endpt.y());
                        break;
                    }
                    case SkPath::kClose_Verb: {
                        backpath->close();
                        break;
                    }
                    case SkPath::kCubic_Verb:
                    case SkPath::kConic_Verb:
                    case SkPath::kDone_Verb:
                        SK_ABORT("Unexpected path verb");
                        break;
                }
            }
        }
    }
Ejemplo n.º 4
0
        void updateDom() {
            const SkPoint corner = pos - SkPoint::Make(size.width() / 2, size.height() / 2);
            objectNode->setX(SkSVGLength(corner.x()));
            objectNode->setY(SkSVGLength(corner.y()));

            // 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;

            shadowNode->setX(SkSVGLength(shadowCorner.x()));
            shadowNode->setY(SkSVGLength(shadowCorner.y()));
        }
Ejemplo n.º 5
0
    SkPath cubicPath(SkPoint p1, SkPoint p2) {
        SkASSERT(p1.y() == p2.y());

        SkPath path;
        path.moveTo(p1);

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

        path.cubicTo(p3, p4, p2);

        return path;
    }
Ejemplo n.º 6
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;
    }
Ejemplo n.º 7
0
bool RRect::onContains(const SkPoint& p) const {
    if (!fRRect.rect().contains(p.x(), p.y())) {
        return false;
    }

    if (fRRect.isRect()) {
        return true;
    }

    // TODO: no SkRRect::contains(x, y)
    return fRRect.contains(SkRect::MakeLTRB(p.x() - SK_ScalarNearlyZero,
                                            p.y() - SK_ScalarNearlyZero,
                                            p.x() + SK_ScalarNearlyZero,
                                            p.y() + SK_ScalarNearlyZero));
}
Ejemplo n.º 8
0
 static void AddRun(const SkFont& font, int count, SkTextBlobRunIterator::GlyphPositioning pos,
                    const SkPoint& offset, SkTextBlobBuilder& builder,
                    const SkRect* bounds = nullptr) {
     switch (pos) {
     case SkTextBlobRunIterator::kDefault_Positioning: {
         const SkTextBlobBuilder::RunBuffer& rb = builder.allocRun(font, count, offset.x(),
                                                                   offset.y(), bounds);
         for (int i = 0; i < count; ++i) {
             rb.glyphs[i] = i;
         }
     } break;
     case SkTextBlobRunIterator::kHorizontal_Positioning: {
         const SkTextBlobBuilder::RunBuffer& rb = builder.allocRunPosH(font, count, offset.y(),
                                                                       bounds);
         for (int i = 0; i < count; ++i) {
             rb.glyphs[i] = i;
             rb.pos[i] = SkIntToScalar(i);
         }
     } break;
     case SkTextBlobRunIterator::kFull_Positioning: {
         const SkTextBlobBuilder::RunBuffer& rb = builder.allocRunPos(font, count, bounds);
         for (int i = 0; i < count; ++i) {
             rb.glyphs[i] = i;
             rb.pos[i * 2] = SkIntToScalar(i);
             rb.pos[i * 2 + 1] = -SkIntToScalar(i);
         }
     } break;
     default:
         SK_ABORT("unhandled positioning value");
     }
 }
Ejemplo n.º 9
0
static void convolve_gaussian_2d(GrDrawContext* drawContext,
                                 const GrClip& clip,
                                 const SkRect& dstRect,
                                 const SkPoint& srcOffset,
                                 GrTexture* texture,
                                 int radiusX,
                                 int radiusY,
                                 SkScalar sigmaX,
                                 SkScalar sigmaY,
                                 const SkRect* srcBounds) {
    SkMatrix localMatrix = SkMatrix::MakeTrans(-srcOffset.x(), -srcOffset.y());
    SkISize size = SkISize::Make(2 * radiusX + 1,  2 * radiusY + 1);
    SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
    GrPaint paint;
    SkIRect bounds;
    if (srcBounds) {
        srcBounds->roundOut(&bounds);
    } else {
        bounds.setEmpty();
    }

    SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaussian(
            texture, bounds, size, 1.0, 0.0, kernelOffset,
            srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_Mode,
            true, sigmaX, sigmaY));
    paint.addColorFragmentProcessor(conv);
    paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
    drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, localMatrix);
}
Ejemplo n.º 10
0
    void drawSets(SkCanvas* canvas) const {
        SkAutoCanvasRestore acr(canvas, true);

        const SkFilterQuality filters[] = {
            kNone_SkFilterQuality,
            kLow_SkFilterQuality,
            kMedium_SkFilterQuality,
            kHigh_SkFilterQuality
        };
        const bool AAs[] = { false, true };

        SkPaint paint;
        for (int i = 0; i < fSets.count(); ++i) {
            auto& set = fSets[i];
            SkPoint lastPt;
            for (size_t j = 0; j < SK_ARRAY_COUNT(AAs); ++j) {
                paint.setAntiAlias(AAs[j]);
                for (size_t k = 0; k < SK_ARRAY_COUNT(filters); ++k) {
                    paint.setFilterQuality(filters[k]);
                    lastPt = drawSet(canvas, set, paint);
                    canvas->translate((kSegLen + 4) * set.fVector.y(),
                                      (kSegLen + 4) * set.fVector.x());
                }
            }
            canvas->translate(lastPt.x() + kSegLen,
                - SkIntToScalar(kSegLen + 4) * SK_ARRAY_COUNT(filters) * SK_ARRAY_COUNT(AAs));
        }
    }
Ejemplo n.º 11
0
PassRefPtr<JSONObject> LoggingCanvas::objectForSkPoint(const SkPoint& point)
{
    RefPtr<JSONObject> pointItem = JSONObject::create();
    pointItem->setNumber("x", point.x());
    pointItem->setNumber("y", point.y());
    return pointItem.release();
}
Ejemplo n.º 12
0
void SkAnnotateNamedDestination(SkCanvas* canvas, const SkPoint& point, SkData* name) {
    if (nullptr == name) {
        return;
    }
    const SkRect rect = SkRect::MakeXYWH(point.x(), point.y(), 0, 0);
    canvas->drawAnnotation(rect, SkAnnotationKeys::Define_Named_Dest_Key(), name);
}
inline void GrStencilAndCoverTextContext::appendGlyph(const SkGlyph& glyph, const SkPoint& pos) {
    // Stick the glyphs we can't draw into the fallback arrays.
    if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
        fFallbackIndices.push_back(glyph.getGlyphID());
        fFallbackPositions.push_back().set(fTextInverseRatio * pos.x(),
                                           -fTextInverseRatio * pos.y());
    } else {
        // TODO: infer the reserve count from the text length.
        if (!fDraw) {
            fDraw = GrPathRangeDraw::Create(fGlyphs,
                                            GrPathRendering::kTranslate_PathTransformType,
                                            64);
        }
        float translate[] = { fTextInverseRatio * pos.x(), -fTextInverseRatio * pos.y() };
        fDraw->append(glyph.getGlyphID(), translate);
    }
}
Ejemplo n.º 14
0
void SkAnnotateNamedDestination(SkCanvas* canvas, const SkPoint& point, SkData* name) {
    if (NULL == name) {
        return;
    }
    SkPaint paint;
    annotate_paint(paint, SkAnnotationKeys::Define_Named_Dest_Key(), name);
    canvas->drawPoint(point.x(), point.y(), paint);
}
Ejemplo n.º 15
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);
}
Ejemplo n.º 16
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);
}
Ejemplo n.º 17
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);
}
 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);
 }
Ejemplo n.º 19
0
void SkLinearGradient::
LinearGradient4fContext::mapTs(int x, int y, SkScalar ts[], int count) const {
    SkASSERT(count > 0);
    SkASSERT(fDstToPosClass != kLinear_MatrixClass);

    SkScalar sx = x + SK_ScalarHalf;
    const SkScalar sy = y + SK_ScalarHalf;
    SkPoint pt;

    if (fDstToPosClass != kPerspective_MatrixClass) {
        // kLinear_MatrixClass, kFixedStepInX_MatrixClass => fixed dt per scanline
        const SkScalar dtdx = fDstToPos.fixedStepInX(sy).x();
        fDstToPosProc(fDstToPos, sx, sy, &pt);

        const Sk4f dtdx4 = Sk4f(4 * dtdx);
        Sk4f t4 = Sk4f(pt.x() + 0 * dtdx,
                       pt.x() + 1 * dtdx,
                       pt.x() + 2 * dtdx,
                       pt.x() + 3 * dtdx);

        while (count >= 4) {
            t4.store(ts);
            t4 = t4 + dtdx4;
            ts += 4;
            count -= 4;
        }

        if (count & 2) {
            *ts++ = t4[0];
            *ts++ = t4[1];
            t4 = SkNx_shuffle<2, 0, 1, 3>(t4);
        }

        if (count & 1) {
            *ts++ = t4[0];
        }
    } else {
        for (int i = 0; i < count; ++i) {
            fDstToPosProc(fDstToPos, sx, sy, &pt);
            ts[i] = pt.x();
            sx += SK_Scalar1;
        }
    }
}
Ejemplo n.º 20
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;
}
Ejemplo n.º 21
0
    void onOnceBeforeDraw() override {
        SkPictureRecorder recorder;
        SkCanvas* pictureCanvas = recorder.beginRecording(kPictureSize, kPictureSize);
        draw_scene(pictureCanvas, kPictureSize);
        SkAutoTUnref<SkPicture> picture(recorder.endRecording());

        SkPoint offset = SkPoint::Make(100, 100);
        pictureCanvas = recorder.beginRecording(SkRect::MakeXYWH(offset.x(), offset.y(),
                                                                 kPictureSize, kPictureSize));
        pictureCanvas->translate(offset.x(), offset.y());
        draw_scene(pictureCanvas, kPictureSize);
        SkAutoTUnref<SkPicture> offsetPicture(recorder.endRecording());

        for (unsigned i = 0; i < SK_ARRAY_COUNT(tiles); ++i) {
            SkRect tile = SkRect::MakeXYWH(tiles[i].x * kPictureSize,
                                           tiles[i].y * kPictureSize,
                                           tiles[i].w * kPictureSize,
                                           tiles[i].h * kPictureSize);
            SkMatrix localMatrix;
            localMatrix.setTranslate(tiles[i].offsetX * kPictureSize,
                                     tiles[i].offsetY * kPictureSize);
            localMatrix.postScale(kFillSize / (2 * kPictureSize),
                                  kFillSize / (2 * kPictureSize));

            SkPicture* picturePtr = picture.get();
            SkRect* tilePtr = &tile;

            if (tile == SkRect::MakeWH(kPictureSize, kPictureSize)) {
                // When the tile == picture bounds, exercise the picture + offset path.
                picturePtr = offsetPicture.get();
                tilePtr = NULL;
            }

            fShaders[i].reset(SkShader::CreatePictureShader(picturePtr,
                                                            SkShader::kRepeat_TileMode,
                                                            SkShader::kRepeat_TileMode,
                                                            &localMatrix,
                                                            tilePtr));
        }
    }
Ejemplo n.º 22
0
static IntersectionType intersection(const SkPoint& p1, const SkPoint& p2,
                                     const SkPoint& p3, const SkPoint& p4,
                                     SkPoint& res) {
    // Store the values for fast access and easy
    // equations-to-code conversion
    SkScalar x1 = p1.x(), x2 = p2.x(), x3 = p3.x(), x4 = p4.x();
    SkScalar y1 = p1.y(), y2 = p2.y(), y3 = p3.y(), y4 = p4.y();

    SkScalar d = SkScalarMul(x1 - x2, y3 - y4) - SkScalarMul(y1 - y2, x3 - x4);
    // If d is zero, there is no intersection
    if (SkScalarNearlyZero(d)) {
        return kNone_IntersectionType;
    }

    // Get the x and y
    SkScalar pre  = SkScalarMul(x1, y2) - SkScalarMul(y1, x2),
             post = SkScalarMul(x3, y4) - SkScalarMul(y3, x4);
    // Compute the point of intersection
    res.set(SkScalarDiv(SkScalarMul(pre, x3 - x4) - SkScalarMul(x1 - x2, post), d),
            SkScalarDiv(SkScalarMul(pre, y3 - y4) - SkScalarMul(y1 - y2, post), d));

    // Check if the x and y coordinates are within both lines
    return (res.x() < GrMin(x1, x2) || res.x() > GrMax(x1, x2) ||
            res.x() < GrMin(x3, x4) || res.x() > GrMax(x3, x4) ||
            res.y() < GrMin(y1, y2) || res.y() > GrMax(y1, y2) ||
            res.y() < GrMin(y3, y4) || res.y() > GrMax(y3, y4)) ?
            kOut_IntersectionType : kIn_IntersectionType;
}
Ejemplo n.º 23
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);
     }
 }
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());
}
Ejemplo n.º 25
0
    static sk_sp<SkImage> MakeImage(const SkVector& vec, SkColor color) {
        const SkPoint start = SkPoint::Make(vec.y() * kSegLen / 2, vec.x() * kSegLen / 2);
        const SkPoint end   = SkPoint::Make(start.x() + vec.x() * (kSegLen - 1),
                                            start.y() + vec.y() * (kSegLen - 1));

        SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(kSegLen, kSegLen));
        surface->getCanvas()->clear(SK_ColorTRANSPARENT);

        SkPaint paint;
        paint.setAntiAlias(true);
        const SkRect border = SkRect::MakeIWH(kSegLen, kSegLen).makeInset(.5f, .5f);
        paint.setColor(SK_ColorBLUE);
        paint.setStyle(SkPaint::kStroke_Style);
        surface->getCanvas()->drawRect(border, paint);

        paint.setColor(SK_ColorBLACK);
        surface->getCanvas()->drawLine(start.x(), start.y(), end.x(), end.y(), paint);
        surface->getCanvas()->drawPoint(start.x(), start.y(), color);
        surface->getCanvas()->drawPoint(end.x(), end.y(), color);

        return surface->makeImageSnapshot();
    }
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());
    }
}
Ejemplo n.º 27
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);
        }
    }
}
Ejemplo n.º 28
0
SkPoint WavyPathText::Waves::apply(float tsec, const Sk2f matrix[3], const SkPoint& pt) const {
    constexpr static int kTablePeriod = 1 << 12;
    static float sin2table[kTablePeriod + 1];
    static SkOnce initTable;
    initTable([]() {
        for (int i = 0; i <= kTablePeriod; ++i) {
            const double sintheta = sin(i * (SK_ScalarPI / kTablePeriod));
            sin2table[i] = static_cast<float>(sintheta * sintheta - 0.5);
        }
    });

     const Sk4f amplitudes = Sk4f::Load(fAmplitudes);
     const Sk4f frequencies = Sk4f::Load(fFrequencies);
     const Sk4f dirsX = Sk4f::Load(fDirsX);
     const Sk4f dirsY = Sk4f::Load(fDirsY);
     const Sk4f speeds = Sk4f::Load(fSpeeds);
     const Sk4f offsets = Sk4f::Load(fOffsets);

    float devicePt[2];
    (matrix[0] * pt.x() + matrix[1] * pt.y() + matrix[2]).store(devicePt);

    const Sk4f t = (frequencies * (dirsX * devicePt[0] + dirsY * devicePt[1]) +
                    speeds * tsec +
                    offsets).abs() * (float(kTablePeriod) / float(SK_ScalarPI));

    const Sk4i ipart = SkNx_cast<int>(t);
    const Sk4f fpart = t - SkNx_cast<float>(ipart);

    int32_t indices[4];
    (ipart & (kTablePeriod-1)).store(indices);

    const Sk4f left(sin2table[indices[0]], sin2table[indices[1]],
                    sin2table[indices[2]], sin2table[indices[3]]);
    const Sk4f right(sin2table[indices[0] + 1], sin2table[indices[1] + 1],
                     sin2table[indices[2] + 1], sin2table[indices[3] + 1]);
    const Sk4f height = amplitudes * (left * (1.f - fpart) + right * fpart);

    Sk4f dy = height * dirsY;
    Sk4f dx = height * dirsX;

    float offsetY[4], offsetX[4];
    (dy + SkNx_shuffle<2,3,0,1>(dy)).store(offsetY); // accumulate.
    (dx + SkNx_shuffle<2,3,0,1>(dx)).store(offsetX);;

    return {devicePt[0] + offsetY[0] + offsetY[1], devicePt[1] - offsetX[0] - offsetX[1]};
}
Ejemplo n.º 29
0
    virtual void onDraw(SkCanvas* canvas) {
        SkAutoTUnref<SkData> name(SkData::NewWithCString("target-a"));

        canvas->save();
        canvas->translate(SkIntToScalar(100), SkIntToScalar(100));
        drawLabeledRect(canvas, "Link to A", 0, 0);
        SkRect rect = SkRect::MakeXYWH(0, 0, SkIntToScalar(50), SkIntToScalar(20));
        SkAnnotateLinkToDestination(canvas, rect, name.get());
        canvas->restore();

        canvas->save();
        canvas->translate(SkIntToScalar(200), SkIntToScalar(200));
        SkPoint point = SkPoint::Make(SkIntToScalar(100), SkIntToScalar(50));
        drawLabeledRect(canvas, "Target A", point.x(), point.y());
        SkAnnotateNamedDestination(canvas, point, name.get());
        canvas->restore();
    }
Ejemplo n.º 30
0
    SkPoint drawSet(SkCanvas* canvas, const ImageSet& set, const SkPaint& paint) const {
        SkASSERT(set.fImages.count() == set.fScales.count());

        SkPoint pt = SkPoint::Make(0, 0);
        for (int i = 0; i < set.fImages.count(); ++i) {
            auto& img = set.fImages[i];
            const SkRect dst =
                SkRect::MakeXYWH(pt.x(), pt.y(),
                    img->width() * (1 + (set.fScales[i] - 1) * set.fVector.x()),
                    img->height() * (1 + (set.fScales[i] - 1) * set.fVector.y()));

            canvas->drawImageRect(img.get(), dst, &paint);
            pt.offset(dst.width() * set.fVector.x(), dst.height() * set.fVector.y());
        }

        return pt;
    }