Beispiel #1
0
static bool calculatePointAndNormalOnPath(SkPathMeasure& measure,
                                          SkScalar length,
                                          FloatPoint& point,
                                          float& normalAngle,
                                          SkScalar* accumulatedLength = 0) {
  do {
    SkScalar contourLength = measure.getLength();
    if (length <= contourLength) {
      SkVector tangent;
      SkPoint position;

      if (measure.getPosTan(length, &position, &tangent)) {
        normalAngle =
            rad2deg(SkScalarToFloat(SkScalarATan2(tangent.fY, tangent.fX)));
        point = FloatPoint(SkScalarToFloat(position.fX),
                           SkScalarToFloat(position.fY));
        return true;
      }
    }
    length -= contourLength;
    if (accumulatedLength)
      *accumulatedLength += contourLength;
  } while (measure.nextContour());
  return false;
}
Beispiel #2
0
SkScalar SkPath1DPathEffect::next(SkPath* dst, SkScalar distance,
                                  SkPathMeasure& meas) const {
    switch (fStyle) {
    case kTranslate_Style: {
        SkPoint pos;
        if (meas.getPosTan(distance, &pos, nullptr)) {
            dst->addPath(fPath, pos.fX, pos.fY);
        }
    }
    break;
    case kRotate_Style: {
        SkMatrix matrix;
        if (meas.getMatrix(distance, &matrix)) {
            dst->addPath(fPath, matrix);
        }
    }
    break;
    case kMorph_Style:
        morphpath(dst, fPath, meas, distance);
        break;
    default:
        SkDEBUGFAIL("unknown Style enum");
        break;
    }
    return fAdvance;
}
Beispiel #3
0
static void morphpoints(SkPoint dst[], const SkPoint src[], int count,
                        SkPathMeasure& meas, const SkMatrix& matrix) {
    SkMatrix::MapXYProc proc = matrix.getMapXYProc();

    for (int i = 0; i < count; i++) {
        SkPoint pos;
        SkVector tangent;

        proc(matrix, src[i].fX, src[i].fY, &pos);
        SkScalar sx = pos.fX;
        SkScalar sy = pos.fY;

        if (!meas.getPosTan(sx, &pos, &tangent)) {
            // set to 0 if the measure failed, so that we just set dst == pos
            tangent.set(0, 0);
        }

        /*  This is the old way (that explains our approach but is way too slow
         SkMatrix    matrix;
         SkPoint     pt;

         pt.set(sx, sy);
         matrix.setSinCos(tangent.fY, tangent.fX);
         matrix.preTranslate(-sx, 0);
         matrix.postTranslate(pos.fX, pos.fY);
         matrix.mapPoints(&dst[i], &pt, 1);
         */
        dst[i].set(pos.fX - SkScalarMul(tangent.fY, sy),
                   pos.fY + SkScalarMul(tangent.fX, sy));
    }
}
Beispiel #4
0
void TextArt::EnvelopeWarp::morphpoints(SkPoint dst[], const SkPoint src[], int count,
                        SkPathMeasure& meas, const SkMatrix& matrix)
{
    SkMatrix::MapXYProc proc = matrix.getMapXYProc();

    for (int i = 0; i < count; i++)
	{
        SkPoint pos;
        SkVector tangent;

		SkPoint iSrc = src[i];
		iSrc.fX = k1_ * iSrc.fX;

        proc(matrix, iSrc.fX, iSrc.fY, &pos);

		SkScalar sx = pos.fX;
        SkScalar sy = pos.fY;

		if (xWeightingMode_ & XWeightingMode_Linearly)
		{	//in Linearly mode adjust Top text by TopLength/BottomLength relation 
			if (isTop)
			{
				//move text below the Top skeleton
				sy -= boundsRect_.fTop;
			}
		}

        if (!meas.getPosTan(sx, &pos, &tangent))
		{
            // set to 0 if the measure failed, so that we just set dst == pos
            tangent.set(0, 0);
        }

        /*  This is the old way (that explains our approach but is way too slow
            SkMatrix    matrix;
            SkPoint     pt;

            pt.set(sx, sy);
            matrix.setSinCos(tangent.fY, tangent.fX);
            matrix.preTranslate(-sx, 0);
            matrix.postTranslate(pos.fX, pos.fY);
            matrix.mapPoints(&dst[i], &pt, 1);
        */

		if (isNormalRotated_)
		{
			dst[i].set(pos.fX - SkScalarMul(tangent.fY, sy),
                   pos.fY + SkScalarMul(tangent.fX, sy));
		}
		else
		{
			dst[i].set(pos.fX,
				pos.fY + sy);
		}
    }
}
Beispiel #5
0
static void morphpoints(SkPoint dst[], const SkPoint src[], int count,
                        SkPathMeasure& meas, SkScalar dist) {
    for (int i = 0; i < count; i++) {
        SkPoint pos;
        SkVector tangent;
        
        SkScalar sx = src[i].fX;
        SkScalar sy = src[i].fY;
        
        meas.getPosTan(dist + sx, &pos, &tangent);
        
        SkMatrix    matrix;
        SkPoint     pt;
        
        pt.set(sx, sy);
        matrix.setSinCos(tangent.fY, tangent.fX, 0, 0);
        matrix.preTranslate(-sx, 0);
        matrix.postTranslate(pos.fX, pos.fY);
        matrix.mapPoints(&dst[i], &pt, 1);
    }
}
void Font::drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
        SkPathMeasure& measure, SkPoint* position, SkVector* tangent) {
    const float halfWidth = glyph->mBitmapWidth * 0.5f;
    const float height = glyph->mBitmapHeight;

    vOffset += glyph->mBitmapTop + height;

    SkPoint destination[4];
    bool ok = measure.getPosTan(x + hOffset + glyph->mBitmapLeft + halfWidth, position, tangent);
    if (!ok) {
        ALOGW("The path for drawTextOnPath is empty or null");
    }

    // Move along the tangent and offset by the normal
    destination[0].set(-tangent->fX * halfWidth - tangent->fY * vOffset,
            -tangent->fY * halfWidth + tangent->fX * vOffset);
    destination[1].set(tangent->fX * halfWidth - tangent->fY * vOffset,
            tangent->fY * halfWidth + tangent->fX * vOffset);
    destination[2].set(destination[1].fX + tangent->fY * height,
            destination[1].fY - tangent->fX * height);
    destination[3].set(destination[0].fX + tangent->fY * height,
            destination[0].fY - tangent->fX * height);

    const float u1 = glyph->mBitmapMinU;
    const float u2 = glyph->mBitmapMaxU;
    const float v1 = glyph->mBitmapMinV;
    const float v2 = glyph->mBitmapMaxV;

    mState->appendRotatedMeshQuad(
            position->x() + destination[0].x(),
            position->y() + destination[0].y(), u1, v2,
            position->x() + destination[1].x(),
            position->y() + destination[1].y(), u2, v2,
            position->x() + destination[2].x(),
            position->y() + destination[2].y(), u2, v1,
            position->x() + destination[3].x(),
            position->y() + destination[3].y(), u1, v1,
            glyph->mCacheTexture);
}