/* TODO Need differentially more subdivisions when the follow-path is curvy. Not sure how to determine that, but we need it. I guess a cheap answer is let the caller tell us, but that seems like a cop-out. Another answer is to get Rob Johnson to figure it out. */ static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas, SkScalar dist) { SkPath::Iter iter(src, false); SkPoint srcP[4], dstP[3]; SkPath::Verb verb; while ((verb = iter.next(srcP)) != SkPath::kDone_Verb) { switch (verb) { case SkPath::kMove_Verb: morphpoints(dstP, srcP, 1, meas, dist); dst->moveTo(dstP[0]); break; case SkPath::kLine_Verb: srcP[2] = srcP[1]; srcP[1].set(SkScalarAve(srcP[0].fX, srcP[2].fX), SkScalarAve(srcP[0].fY, srcP[2].fY)); // fall through to quad case SkPath::kQuad_Verb: morphpoints(dstP, &srcP[1], 2, meas, dist); dst->quadTo(dstP[0], dstP[1]); break; case SkPath::kCubic_Verb: morphpoints(dstP, &srcP[1], 3, meas, dist); dst->cubicTo(dstP[0], dstP[1], dstP[2]); break; case SkPath::kClose_Verb: dst->close(); break; default: SkDEBUGFAIL("unknown verb"); break; } } }
/* TODO Need differentially more subdivisions when the follow-path is curvy. Not sure how to determine that, but we need it. I guess a cheap answer is let the caller tell us, but that seems like a cop-out. Another answer is to get Rob Johnson to figure it out. */ void TextArt::EnvelopeWarp::morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas, const SkMatrix& matrix) { SkPath::Iter iter(src, false); SkPoint srcP[4], dstP[3]; SkPath::Verb verb; while ((verb = iter.next(srcP)) != SkPath::kDone_Verb) { switch (verb) { case SkPath::kMove_Verb: morphpoints(dstP, srcP, 1, meas, matrix); dst->moveTo(dstP[0]); break; case SkPath::kLine_Verb: /* morphpoints(dstP, &srcP[1], 1, meas, matrix); dst->lineTo(dstP[0]); break; */ // turn lines into quads to look bendy srcP[0].fX = SkScalarAve(srcP[0].fX, srcP[1].fX); srcP[0].fY = SkScalarAve(srcP[0].fY, srcP[1].fY); morphpoints(dstP, srcP, 2, meas, matrix); dst->quadTo(dstP[0], dstP[1]); break; case SkPath::kQuad_Verb: morphpoints(dstP, &srcP[1], 2, meas, matrix); dst->quadTo(dstP[0], dstP[1]); break; case SkPath::kCubic_Verb: morphpoints(dstP, &srcP[1], 3, meas, matrix); dst->cubicTo(dstP[0], dstP[1], dstP[2]); break; case SkPath::kClose_Verb: dst->close(); break; default: SkDEBUGFAIL("unknown verb"); break; } } }
bool TextArt::EnvelopeWarp::getK(const SkRect& glypthBound, SkPathCrossing& bCrossing, SkPathCrossing& tCrossing, SkPathMeasure& basePathMeasure, const SkMatrix& compositeMatrix, SkScalar& k1, SkScalar& hBOffset, SkScalar& hTOffset) { SkScalar bCut = isTopBased_ ? SkIntToScalar(-3) : SkIntToScalar(+3); SkPoint centerX[4], tCenterX[4]; //left normal centerX[0].set(glypthBound.fLeft, glypthBound.fBottom + bCut); centerX[1].set(glypthBound.fLeft, glypthBound.fTop); //right normal centerX[2].set(glypthBound.fRight, glypthBound.fBottom + bCut); centerX[3].set(glypthBound.fRight, glypthBound.fTop); //morph normal point by Bottom skeleton isTop = isTopBased_; k1_ = 1.0; morphpoints(tCenterX, centerX, 4, basePathMeasure, compositeMatrix); normal.moveTo(tCenterX[0]); normal.lineTo(tCenterX[1]); normal.moveTo(tCenterX[2]); normal.lineTo(tCenterX[3]); SkPoint bCrossR, bCrossL, tCrossL, tCrossR; SkScalar bCrossDistR, bCrossDistL, tCrossDistL, tCrossDistR; //get intersection between Normals and Skeletons if (tCrossing.rayCrossing(tCenterX, &tCrossDistL, &tCrossL) && tCrossing.rayCrossing(&tCenterX[2], &tCrossDistR, &tCrossR) && bCrossing.rayCrossing(&tCenterX[0], &bCrossDistL, &bCrossL) && bCrossing.rayCrossing(&tCenterX[2], &bCrossDistR, &bCrossR) ) { intersections.push_back(tCrossL); intersections.push_back(tCrossR); intersections.push_back(bCrossL); intersections.push_back(bCrossR); //calulate linear coeffiction for stretching Top glypth k1 = (tCrossDistR - tCrossDistL) / (bCrossDistR - bCrossDistL); //use distance to Left on Top Skeleton for positioning Top glypthn hBOffset = bCrossDistL; hTOffset = tCrossDistL; return true; } return false; }