示例#1
0
    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();
    }
void anchor_handle_renderer::draw_anchor (SkCanvas &canvas, const SkRect &rect, SkPaint &paint) const
{
  switch (m_node_type)
  {
    case handle_type::DIAMOND:
    {
      canvas.save ();
      canvas.translate (rect.centerX (), rect.centerY ());
      canvas.rotate (45);
      SkRect moved_rect = rect;
      moved_rect.offset (-rect.centerX (), -rect.centerY ());
      paint.setAntiAlias (true);
      canvas.drawRect (moved_rect, paint);
      canvas.restore ();
      break;
    }
    case handle_type::SQUARE:
      canvas.drawRect (rect, paint);
      break;
    case handle_type::CIRCLE:
      canvas.drawOval (rect, paint);
      break;
    case handle_type::DOUBLE_HEADED_ARROW:
    case handle_type::ROTATE_ARROW:
      SkPath path = qt2skia::path (*m_paths.at (m_node_type));
      SkMatrix trans;
      trans.setIdentity ();
      trans.postRotate (m_rotation_angle, 32, 32); // TODO: change all these to use info from path_storage (bounding box and center (possibly should be made 0))
      trans.postConcat (qt2skia::matrix (geom::rect2rect (QRectF (0, 0, 64, 64), qt2skia::rect (rect))));
      path.transform (trans);
      paint.setAntiAlias (true);
      canvas.drawPath (path, paint);
      break;
  }
}
示例#3
0
    virtual void onDraw(SkCanvas* canvas) {

        SkPoint pts[2] = {
            { 0, 0 },
            { SkIntToScalar(100), SkIntToScalar(100) }
        };
        SkShader::TileMode tm = SkShader::kClamp_TileMode;
        SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) };
        SkPaint paint;
        paint.setAntiAlias(true);

        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
        for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); i++) {
            canvas->save();
            for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); j++) {
                SkShader* shader = gGradMakers[j](pts, gGradData[i], tm, NULL);

                // apply an increasing y perspective as we move to the right
                SkMatrix perspective;
                perspective.setIdentity();
                perspective.setPerspY(SkScalarDiv(SkIntToScalar((unsigned) i+1),
                                      SkIntToScalar(500)));
                perspective.setSkewX(SkScalarDiv(SkIntToScalar((unsigned) i+1),
                                     SkIntToScalar(10)));
                shader->setLocalMatrix(perspective);

                paint.setShader(shader);
                canvas->drawRect(r, paint);
                shader->unref();
                canvas->translate(0, SkIntToScalar(120));
            }
            canvas->restore();
            canvas->translate(SkIntToScalar(120), 0);
        }
    }
示例#4
0
sk_shader_t* sk_shader_new_two_point_conical_gradient(const sk_point_t* start,
                                                      float startRadius,
                                                      const sk_point_t* end,
                                                      float endRadius,
                                                      const sk_color_t colors[],
                                                      const float colorPos[],
                                                      int colorCount,
                                                      sk_shader_tilemode_t cmode,
                                                      const sk_matrix_t* cmatrix) {
    SkTileMode mode;
    if (!from_c_tilemode(cmode, &mode)) {
        return nullptr;
    }
    SkMatrix matrix;
    if (cmatrix) {
        from_c_matrix(cmatrix, &matrix);
    } else {
        matrix.setIdentity();
    }
    SkPoint skstart = to_skpoint(*start);
    SkPoint skend = to_skpoint(*end);
    return (sk_shader_t*)SkGradientShader::MakeTwoPointConical(skstart, (SkScalar)startRadius,
                                                        skend, (SkScalar)endRadius,
                                                        reinterpret_cast<const SkColor*>(colors),
                                                        reinterpret_cast<const SkScalar*>(colorPos),
                                                        colorCount, mode, 0, &matrix).release();
}
示例#5
0
    GiantDashBench(LineType lt, SkScalar width)  {
        fName.printf("giantdashline_%s_%g", LineTypeName(lt), width);
        fStrokeWidth = width;

        // deliberately pick intervals that won't be caught by asPoints(), so
        // we can test the filterPath code-path.
        const SkScalar intervals[] = { 20, 10, 10, 10 };
        fPathEffect.reset(SkDashPathEffect::Create(intervals,
                                                   SK_ARRAY_COUNT(intervals), 0));

        SkScalar cx = 640 / 2;  // center X
        SkScalar cy = 480 / 2;  // center Y
        SkMatrix matrix;

        switch (lt) {
            case kHori_LineType:
                matrix.setIdentity();
                break;
            case kVert_LineType:
                matrix.setRotate(90, cx, cy);
                break;
            case kDiag_LineType:
                matrix.setRotate(45, cx, cy);
                break;
            case kLineTypeCount:
                // Not a real enum value.
                break;
        }

        const SkScalar overshoot = 100*1000;
        const SkPoint pts[2] = {
            { -overshoot, cy }, { 640 + overshoot, cy }
        };
        matrix.mapPoints(fPts, pts, 2);
    }
示例#6
0
    void onDraw(int loops, SkCanvas* canvas) override {
        SkPaint paint;
        paint.setAntiAlias(fAA);
        paint.setBlendMode(fMode);
        SkColor color = start_color(fColorType);

        int w = this->getSize().x();
        int h = this->getSize().y();

        static const SkScalar kRectW = 25.1f;
        static const SkScalar kRectH = 25.9f;

        if (fColorType == kShaderOpaque_ColorType) {
            // The only requirement for the shader is that it requires local coordinates
            SkPoint pts[2] = { {0.0f, 0.0f}, {kRectW, kRectH} };
            SkColor colors[] = { color, SK_ColorBLUE };
            paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
                                                         SkTileMode::kClamp));
        }

        SkMatrix rotate;
        // This value was chosen so that we frequently hit the axis-aligned case.
        rotate.setRotate(30.f, kRectW / 2, kRectH / 2);
        SkMatrix m = rotate;

        SkScalar tx = 0, ty = 0;

        if (fPerspective) {
            // Apply some fixed perspective to change how ops may draw the rects
            SkMatrix perspective;
            perspective.setIdentity();
            perspective.setPerspX(1e-4f);
            perspective.setPerspY(1e-3f);
            perspective.setSkewX(0.1f);
            canvas->concat(perspective);
        }

        for (int i = 0; i < loops; ++i) {
            canvas->save();
            canvas->translate(tx, ty);
            canvas->concat(m);
            paint.setColor(color);
            color = advance_color(color, fColorType, i);

            canvas->drawRect(SkRect::MakeWH(kRectW, kRectH), paint);
            canvas->restore();

            tx += kRectW + 2;
            if (tx > w) {
                tx = 0;
                ty += kRectH + 2;
                if (ty > h) {
                    ty = 0;
                }
            }

            m.postConcat(rotate);
        }
    }
示例#7
0
 virtual void onDraw(SkCanvas* canvas) {
     SkMatrix perspective;
     perspective.setIdentity();
     perspective.setPerspY(SkScalarDiv(SK_Scalar1, SkIntToScalar(1000)));
     perspective.setSkewX(SkScalarDiv(SkIntToScalar(8), SkIntToScalar(25)));
     canvas->concat(perspective);
     INHERITED::onDraw(canvas);
 }
示例#8
0
void draw(SkCanvas* canvas) {
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setTextSize(24);
    canvas->drawString("normal", 12, 24, paint);
    SkMatrix matrix;
    matrix.setIdentity();
    matrix.setSkewX(-.7f);
    canvas->concat(matrix);
    canvas->drawString("x skew", 36, 48, paint);
}
static void android_view_RenderNode_getInverseTransformMatrix(JNIEnv* env,
        jobject clazz, jlong renderNodePtr, jlong outMatrixPtr) {
    // load transform matrix
    android_view_RenderNode_getTransformMatrix(env, clazz, renderNodePtr, outMatrixPtr);
    SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);

    // return it inverted
    if (!outMatrix->invert(outMatrix)) {
        // failed to load inverse, pass back identity
        outMatrix->setIdentity();
    }
}
示例#10
0
void OsmAnd::MapRasterizer_P::rasterizePolylineIcons(
    const Context& context,
    SkCanvas& canvas,
    const SkPath& path,
    const MapStyleEvaluationResult& evalResult)
{
    bool ok;

    QString pathIconName;
    ok = evalResult.getStringValue(context.env->styleBuiltinValueDefs->id_OUTPUT_PATH_ICON, pathIconName);
    if (!ok || pathIconName.isEmpty())
        return;

    float pathIconStep = 0.0f;
    ok = evalResult.getFloatValue(context.env->styleBuiltinValueDefs->id_OUTPUT_PATH_ICON_STEP, pathIconStep);
    if (!ok || pathIconStep <= 0.0f)
        return;

    std::shared_ptr<const SkBitmap> pathIcon;
    ok = context.env->obtainMapIcon(pathIconName, pathIcon);
    if (!ok || !pathIcon)
        return;

    SkMatrix mIconTransform;
    mIconTransform.setIdentity();
    mIconTransform.setTranslate(-0.5f * pathIcon->width(), -0.5f * pathIcon->height());
    mIconTransform.postRotate(90.0f);

    SkPathMeasure pathMeasure(path, false);

    const auto length = pathMeasure.getLength();
    auto iconOffset = 0.5f * pathIconStep;
    const auto iconInstancesCount = static_cast<int>((length - iconOffset) / pathIconStep) + 1;
    if (iconInstancesCount < 1)
        return;

    SkMatrix mIconInstanceTransform;
    for (auto iconInstanceIdx = 0; iconInstanceIdx < iconInstancesCount; iconInstanceIdx++, iconOffset += pathIconStep)
    {
        SkMatrix mPinPoint;
        ok = pathMeasure.getMatrix(iconOffset, &mPinPoint);
        if (!ok)
            break;

        mIconInstanceTransform.setConcat(mPinPoint, mIconTransform);
        canvas.save();
        canvas.concat(mIconInstanceTransform);
        canvas.drawBitmap(*pathIcon, 0, 0, &_defaultPaint);
        canvas.restore();
    }
}
static void android_view_RenderNode_getTransformMatrix(JNIEnv* env,
        jobject clazz, jlong renderNodePtr, jlong outMatrixPtr) {
    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);

    renderNode->mutateStagingProperties().updateMatrix();
    const SkMatrix* transformMatrix = renderNode->stagingProperties().getTransformMatrix();

    if (transformMatrix) {
        *outMatrix = *transformMatrix;
    } else {
        outMatrix->setIdentity();
    }
}
示例#12
0
    void makeMatrices() {
        {
        SkMatrix m;
        m.setIdentity();
        fMatrices.push_back(m);
        }

        {
        SkMatrix m;
        m.setScale(SkIntToScalar(3), SkIntToScalar(2));
        fMatrices.push_back(m);
        }

        {
        SkMatrix m;
        m.setScale(SkIntToScalar(2), SkIntToScalar(2));
        fMatrices.push_back(m);
        }

        {
        SkMatrix m;
        m.setScale(SkIntToScalar(1), SkIntToScalar(2));
        fMatrices.push_back(m);
        }

        {
        SkMatrix m;
        m.setScale(SkIntToScalar(4), SkIntToScalar(1));
        fMatrices.push_back(m);
        }

        {
        SkMatrix m;
        m.setRotate(SkIntToScalar(90));
        fMatrices.push_back(m);
        }

        {
        SkMatrix m;
        m.setSkew(SkIntToScalar(2), SkIntToScalar(3));
        fMatrices.push_back(m);
        }

        {
        SkMatrix m;
        m.setRotate(SkIntToScalar(60));
        fMatrices.push_back(m);
        }
    }
示例#13
0
void draw(SkCanvas* canvas) {
    SkMatrix m;
    m.setIdentity();
    m.set(SkMatrix::kMPersp0, -0.004f);
    SkAutoCanvasRestore autoRestore(canvas, true);
    canvas->translate(22, 144);
    SkPaint black;
    black.setAntiAlias(true);
    black.setTextSize(24);
    SkPaint gray = black;
    gray.setColor(0xFF9f9f9f);
    SkString string;
    string.appendScalar(m.getPerspX());
    canvas->drawString(string, 0, -72, gray);
    canvas->concat(m);
    canvas->drawString(string, 0, 0, black);
}
示例#14
0
sk_shader_t* sk_shader_new_sweep_gradient(const sk_point_t* ccenter,
                                          const sk_color_t colors[],
                                          const float colorPos[],
                                          int colorCount,
                                          const sk_matrix_t* cmatrix) {
    SkMatrix matrix;
    if (cmatrix) {
        from_c_matrix(cmatrix, &matrix);
    } else {
        matrix.setIdentity();
    }
    return (sk_shader_t*)SkGradientShader::MakeSweep((SkScalar)(ccenter->x),
                                                     (SkScalar)(ccenter->y),
                                                     reinterpret_cast<const SkColor*>(colors),
                                                     reinterpret_cast<const SkScalar*>(colorPos),
                                                     colorCount, 0, &matrix).release();
}
示例#15
0
void draw(SkCanvas* canvas) {
    SkPaint black;
    black.setAntiAlias(true);
    black.setTextSize(48);
    SkPaint gray = black;
    gray.setColor(0xFF9f9f9f);
    SkScalar offset[] = { 1.5f, 1.5f, 20,   1.5f, 1.5f, 20,   .03f, .01f, 2 };
    for (int i : { SkMatrix::kMScaleX, SkMatrix::kMSkewX,  SkMatrix::kMTransX,
                   SkMatrix::kMSkewY,  SkMatrix::kMScaleY, SkMatrix::kMTransY,
                   SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 } ) {
        SkMatrix m;
        m.setIdentity();
        m.set(i, offset[i]);
        SkAutoCanvasRestore autoRestore(canvas, true);
        canvas->translate(22 + (i % 3) * 88, 44 + (i / 3) * 88);
        canvas->drawString("&", 0, 0, gray);
        canvas->concat(m);
        canvas->drawString("&", 0, 0, black);
    }
}
示例#16
0
sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t pts[2],
                                           const sk_color_t colors[],
                                           const float colorPos[],
                                           int colorCount,
                                           sk_shader_tilemode_t cmode,
                                           const sk_matrix_t* cmatrix) {
    SkShader::TileMode mode;
    if (!from_c_tilemode(cmode, &mode)) {
        return NULL;
    }
    SkMatrix matrix;
    if (cmatrix) {
        from_c_matrix(cmatrix, &matrix);
    } else {
        matrix.setIdentity();
    }
    SkShader* s = SkGradientShader::CreateLinear(reinterpret_cast<const SkPoint*>(pts),
                                                 reinterpret_cast<const SkColor*>(colors),
                                                 colorPos, colorCount, mode, 0, &matrix);
    return (sk_shader_t*)s;
}
示例#17
0
sk_shader_t* sk_shader_new_radial_gradient(const sk_point_t* ccenter,
                                           float radius,
                                           const sk_color_t colors[],
                                           const float colorPos[],
                                           int colorCount,
                                           sk_shader_tilemode_t cmode,
                                           const sk_matrix_t* cmatrix) {
    SkTileMode mode;
    if (!from_c_tilemode(cmode, &mode)) {
        return nullptr;
    }
    SkMatrix matrix;
    if (cmatrix) {
        from_c_matrix(cmatrix, &matrix);
    } else {
        matrix.setIdentity();
    }
    SkPoint center = to_skpoint(*ccenter);
    return (sk_shader_t*)SkGradientShader::MakeRadial(center, (SkScalar)radius,
                                                      reinterpret_cast<const SkColor*>(colors),
                                                      reinterpret_cast<const SkScalar*>(colorPos),
                                                      colorCount, mode, 0, &matrix).release();
}
示例#18
0
static void test_matrix_is_similarity(skiatest::Reporter* reporter) {
    SkMatrix mat;

    // identity
    mat.setIdentity();
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // translation only
    mat.reset();
    mat.setTranslate(SkIntToScalar(100), SkIntToScalar(100));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with same size
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(15));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with one negative
    mat.reset();
    mat.setScale(SkIntToScalar(-15), SkIntToScalar(15));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with different size
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(20));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // scale with same size at a pivot point
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(15),
                 SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with different size at a pivot point
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(20),
                 SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with same size
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(15));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with different size
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(20));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with same size at a pivot point
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(15),
                SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with different size at a pivot point
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(20),
                SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // perspective x
    mat.reset();
    mat.setPerspX(SkScalarToPersp(SK_Scalar1 / 2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // perspective y
    mat.reset();
    mat.setPerspY(SkScalarToPersp(SK_Scalar1 / 2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // rotate
    for (int angle = 0; angle < 360; ++angle) {
        mat.reset();
        mat.setRotate(SkIntToScalar(angle));
        REPORTER_ASSERT(reporter, mat.isSimilarity());
    }

    // see if there are any accumulated precision issues
    mat.reset();
    for (int i = 1; i < 360; i++) {
        mat.postRotate(SkIntToScalar(1));
    }
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // rotate + translate
    mat.reset();
    mat.setRotate(SkIntToScalar(30));
    mat.postTranslate(SkIntToScalar(10), SkIntToScalar(20));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // rotate + uniform scale
    mat.reset();
    mat.setRotate(SkIntToScalar(30));
    mat.postScale(SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // rotate + non-uniform scale
    mat.reset();
    mat.setRotate(SkIntToScalar(30));
    mat.postScale(SkIntToScalar(3), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // all zero
    mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, 0);
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // all zero except perspective
    mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1);
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // scales zero, only skews
    mat.setAll(0, SK_Scalar1, 0,
               SK_Scalar1, 0, 0,
               0, 0, SkMatrix::I()[8]);
    REPORTER_ASSERT(reporter, mat.isSimilarity());
}
示例#19
0
void TextArtView::onDrawContent(SkCanvas* canvas)
{
	const std::string TEXT = "Helpo TextArt Effects";
	SkTypeface* typeface = SkTypeface::CreateFromName("Georgia", SkTypeface::kBold);

	if (!initialized)
	{
		initialized = true;

		WarpFrameT	warpFrame;
		SkMatrix	warpMatrix;
		warpMatrix.setIdentity();

		getWarpParams(warpFrame, warpMatrix);

		bSkeleton_ = warpFrame[0];
		if (warpFrame.size()>1)
			tSkeleton_ = warpFrame[1];

		TextArt::EnvelopeWarp textArt(bSkeleton_, warpMatrix);	
		textArt.setTopSkeleton(tSkeleton_);
		textArt.setIsNormalRotated(getIsNormalRotated());
		textArt.setIsSymmetric(getIsSymmetric());
		textArt.setIsTopBased(getIsTopBased());
		
		path_ = textArt.warp(TEXT, typeface);
	}

    SkPaint paint;
    paint.setAntiAlias(true);
	paint.setTextSize(SkIntToScalar(64));
    paint.setStyle(SkPaint::kStroke_Style);
	paint.setTypeface(typeface);

	canvas->save();

	//center path on the cnavas
	const SkRect& pathBounds = path_.getBounds();
	SkISize screenSize = canvas->getDeviceSize();

	SkScalar xOffset = SkScalarHalf( SkIntToScalar(screenSize.width()) ) - pathBounds.centerX();
	SkScalar yOffset = SkScalarHalf( SkIntToScalar(screenSize.height()) ) - pathBounds.centerY();

	canvas->translate(xOffset, yOffset);

	paint.setColor(0x33FF3333);
//	canvas->drawRect(pathBounds, paint);


/*
	paint.setColor(SK_ColorGREEN);
	canvas->drawPath(textArt.bSkeleton_, paint);
	canvas->drawPath(textArt.bWarped_, paint);

	paint.setColor(SK_ColorCYAN);
	canvas->drawPath(textArt.tSkeleton_, paint);
	canvas->drawPath(textArt.tWarped_, paint);
*/
	//draw the skeleton path
	paint.setColor(SK_ColorBLUE);
	canvas->drawPath(bSkeleton_, paint);
	canvas->drawPath(tSkeleton_, paint);

	//draw the path
	paint.setColor(SK_ColorBLACK);
	paint.setStyle(SkPaint::kFill_Style);
	canvas->drawPath(path_, paint);
/*
	paint.setColor(SK_ColorRED);
	canvas->drawPath(textArt.normal, paint);
	canvas->drawPath(textArt.tFlattern, paint);
	for(int i=0; i<textArt.intersections.size(); ++i)
	{
		canvas->drawCircle(textArt.intersections[i].fX, textArt.intersections[i].fY, 1.5, paint);
	}
*/
	canvas->restore();
}
static void test_matrix_is_similarity(skiatest::Reporter* reporter) {
    SkMatrix mat;

    // identity
    mat.setIdentity();
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // translation only
    mat.reset();
    mat.setTranslate(SkIntToScalar(100), SkIntToScalar(100));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with same size
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(15));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with one negative
    mat.reset();
    mat.setScale(SkIntToScalar(-15), SkIntToScalar(15));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with different size
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(20));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // scale with same size at a pivot point
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(15),
                 SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with different size at a pivot point
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(20),
                 SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with same size
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(15));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with different size
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(20));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with same size at a pivot point
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(15),
                SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with different size at a pivot point
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(20),
                SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // perspective x
    mat.reset();
    mat.setPerspX(SkScalarToPersp(SK_Scalar1 / 2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // perspective y
    mat.reset();
    mat.setPerspY(SkScalarToPersp(SK_Scalar1 / 2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

#ifdef SK_SCALAR_IS_FLOAT
    /* We bypass the following tests for SK_SCALAR_IS_FIXED build.
     * The long discussion can be found in this issue:
     *     http://codereview.appspot.com/5999050/
     * In short, we haven't found a perfect way to fix the precision
     * issue, i.e. the way we use tolerance in isSimilarityTransformation
     * is incorrect. The situation becomes worse in fixed build, so
     * we disabled rotation related tests for fixed build.
     */

    // rotate
    for (int angle = 0; angle < 360; ++angle) {
        mat.reset();
        mat.setRotate(SkIntToScalar(angle));
        REPORTER_ASSERT(reporter, mat.isSimilarity());
    }

    // see if there are any accumulated precision issues
    mat.reset();
    for (int i = 1; i < 360; i++) {
        mat.postRotate(SkIntToScalar(1));
    }
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // rotate + translate
    mat.reset();
    mat.setRotate(SkIntToScalar(30));
    mat.postTranslate(SkIntToScalar(10), SkIntToScalar(20));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // rotate + uniform scale
    mat.reset();
    mat.setRotate(SkIntToScalar(30));
    mat.postScale(SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // rotate + non-uniform scale
    mat.reset();
    mat.setRotate(SkIntToScalar(30));
    mat.postScale(SkIntToScalar(3), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());
#endif

    // all zero
    mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, 0);
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // all zero except perspective
    mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1);
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // scales zero, only skews
    mat.setAll(0, SK_Scalar1, 0,
               SK_Scalar1, 0, 0,
               0, 0, SkMatrix::I()[8]);
    REPORTER_ASSERT(reporter, mat.isSimilarity());
}
示例#21
0
SkPath TextArt::EnvelopeWarp::warp(const std::string& text, SkTypeface* typeface)
{
	SkPath				warpedPath;

	if (text.empty())
		return warpedPath;

	//prepare paint
	SkPaint paint;
	paint.setTextSize(SkIntToScalar(64));
	paint.setTypeface(typeface);
	paint.setTextAlign(SkPaint::kCenter_Align);

	//measure Bottom path to center text on it
	SkPathMeasure   bMeasure(bSkeleton_, false);
	SkScalar        hBOffset = 0;

    if (paint.getTextAlign() != SkPaint::kLeft_Align)
	{
        SkScalar pathLen = bMeasure.getLength();
        if (paint.getTextAlign() == SkPaint::kCenter_Align)
		{
            pathLen = SkScalarHalf(pathLen);
        }
        hBOffset += pathLen;
    }

	//get text boundaries on normal(non-warped) state
	{
		SkMatrix scaleMartix;
		scaleMartix.setIdentity();

		SkTextToPathIter	iter(text.c_str(), text.size(), paint, true);
		const SkPath*   glypthPath;
		SkScalar        xpos;

		SkScalar        scale = iter.getPathScale();
		scaleMartix.setScale(scale, scale);

		while (iter.next(&glypthPath, &xpos))
		{
			if (glypthPath)
			{
				//prepare resulting transformatiom Matrix
				SkMatrix	compositeMatrix(scaleMartix);
				compositeMatrix.postTranslate(xpos + hBOffset, 0);
				
				SkPath p;
				(*glypthPath).transform(compositeMatrix, &p);
				//get normal(without any warps) text boundaries
				boundsRect_.join( p.getBounds() );
			}
		}
	}

	//center text on Top skeleton
	SkPathMeasure   tMeasure(tSkeleton_, false);
	SkScalar        hTOffset = 0;	
	{
		if (paint.getTextAlign() != SkPaint::kLeft_Align)
		{
			SkScalar pathLen = tMeasure.getLength();
			if (paint.getTextAlign() == SkPaint::kCenter_Align)
			{
				pathLen = SkScalarHalf(pathLen);
			}
			hTOffset += pathLen;
		}
	}		
	
	//warp text on Bottom and Top skeletons
	{
		SkTextToPathIter	iter(text.c_str(), text.size(), paint, true);
		SkScalar        xpos;

		SkMatrix        scaleMartix;
		SkScalar        scale = iter.getPathScale();
		scaleMartix.setScale(scale, scale);

		SkPath line;
		line.lineTo(SkIntToScalar(100), SkIntToScalar(0));
		SkPathMeasure   lineMeasure(line, false);

		SkPathCrossing bCrossing(bSkeleton_);
		SkPathCrossing tCrossing(tSkeleton_);

		const SkPath*   glypthPathOrig;
		while (iter.next(&glypthPathOrig, &xpos))
		{
			if (glypthPathOrig)
			{
				SkPath glypthPath;
				SkRect glypthBound;
				glypthBound = (*glypthPathOrig).getBounds();
				glypthPathOrig->offset(-glypthBound.fLeft, 0, &glypthPath);

				morph(bSkeleton_, bMeasure, bCrossing,
						tSkeleton_, tMeasure, tCrossing,
						glypthPath, lineMeasure, scaleMartix,
						xpos, hBOffset, hTOffset, warpedPath);

			}
		}
	}
	
	return warpedPath;
}
示例#22
0
static void test_matrix_is_similarity(skiatest::Reporter* reporter) {
    SkMatrix mat;

    // identity
    mat.setIdentity();
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // translation only
    mat.reset();
    mat.setTranslate(SkIntToScalar(100), SkIntToScalar(100));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with same size
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(15));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with one negative
    mat.reset();
    mat.setScale(SkIntToScalar(-15), SkIntToScalar(15));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with different size
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(20));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // scale with same size at a pivot point
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(15),
                 SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // scale with different size at a pivot point
    mat.reset();
    mat.setScale(SkIntToScalar(15), SkIntToScalar(20),
                 SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with same size
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(15));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with different size
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(20));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with same size at a pivot point
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(15),
                SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // skew with different size at a pivot point
    mat.reset();
    mat.setSkew(SkIntToScalar(15), SkIntToScalar(20),
                SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // perspective x
    mat.reset();
    mat.setPerspX(SkScalarToPersp(SK_Scalar1 / 2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // perspective y
    mat.reset();
    mat.setPerspY(SkScalarToPersp(SK_Scalar1 / 2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // rotate
    for (int angle = 0; angle < 360; ++angle) {
        mat.reset();
        mat.setRotate(SkIntToScalar(angle));
#ifndef SK_CPU_ARM64
        REPORTER_ASSERT(reporter, mat.isSimilarity());
#else
        // 64-bit ARM devices built with -O2 and -ffp-contract=fast have a loss
        // of precision and require that we have a higher tolerance
        REPORTER_ASSERT(reporter, mat.isSimilarity(SK_ScalarNearlyZero + 0.00010113f));
#endif
    }

    // see if there are any accumulated precision issues
    mat.reset();
    for (int i = 1; i < 360; i++) {
        mat.postRotate(SkIntToScalar(1));
    }
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // rotate + translate
    mat.reset();
    mat.setRotate(SkIntToScalar(30));
    mat.postTranslate(SkIntToScalar(10), SkIntToScalar(20));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // rotate + uniform scale
    mat.reset();
    mat.setRotate(SkIntToScalar(30));
    mat.postScale(SkIntToScalar(2), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, mat.isSimilarity());

    // rotate + non-uniform scale
    mat.reset();
    mat.setRotate(SkIntToScalar(30));
    mat.postScale(SkIntToScalar(3), SkIntToScalar(2));
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // all zero
    mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, 0);
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // all zero except perspective
    mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1);
    REPORTER_ASSERT(reporter, !mat.isSimilarity());

    // scales zero, only skews
    mat.setAll(0, SK_Scalar1, 0,
               SK_Scalar1, 0, 0,
               0, 0, SkMatrix::I()[8]);
    REPORTER_ASSERT(reporter, mat.isSimilarity());
}