Java Code Examples for android.graphics.PathMeasure#nextContour()

The following examples show how to use android.graphics.PathMeasure#nextContour() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: OC_ReadingReadToMeNTx.java    From GLEXP-Team-onebillion with Apache License 2.0 6 votes vote down vote up
List<Path> pathsFromComplexPath(Path p)
{
    List<Path>pathList = new ArrayList<>();
    PathMeasure pm = new PathMeasure(p,false);
    Boolean fin = false;
    while (!fin)
    {
        float len = pm.getLength();
        if (len > 0)
        {
            Path np = new Path();
            pm.getSegment(0,len,np,true);
            pathList.add(np);
        }
        fin = !pm.nextContour();
    }
    return pathList;
}
 
Example 2
Source File: FillableLoader.java    From AndroidFillableLoaders with Apache License 2.0 6 votes vote down vote up
private void buildPathData() {
  SvgPathParser parser = getPathParser();
  pathData = new PathData();
  try {
    pathData.path = parser.parsePath(svgPath);
  } catch (ParseException e) {
    pathData.path = new Path();
  }

  PathMeasure pm = new PathMeasure(pathData.path, true);
  while (true) {
    pathData.length = Math.max(pathData.length, pm.getLength());
    if (!pm.nextContour()) {
      break;
    }
  }
}
 
Example 3
Source File: GestureDescription.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
/**
 * @param path The path to follow. Must have exactly one contour. The bounds of the path
 * must not be negative. The path must not be empty. If the path has zero length
 * (for example, a single {@code moveTo()}), the stroke is a touch that doesn't move.
 * @param startTime The time, in milliseconds, from the time the gesture starts to the
 * time the stroke should start. Must not be negative.
 * @param duration The duration, in milliseconds, the stroke takes to traverse the path.
 * Must be positive.
 * @param willContinue {@code true} if this stroke will be continued by one in the
 * next gesture {@code false} otherwise. Continued strokes keep their pointers down when
 * the gesture completes.
 */
public StrokeDescription(@NonNull Path path,
        @IntRange(from = 0) long startTime,
        @IntRange(from = 0) long duration,
        boolean willContinue) {
    mContinued = willContinue;
    Preconditions.checkArgument(duration > 0, "Duration must be positive");
    Preconditions.checkArgument(startTime >= 0, "Start time must not be negative");
    Preconditions.checkArgument(!path.isEmpty(), "Path is empty");
    RectF bounds = new RectF();
    path.computeBounds(bounds, false /* unused */);
    Preconditions.checkArgument((bounds.bottom >= 0) && (bounds.top >= 0)
            && (bounds.right >= 0) && (bounds.left >= 0),
            "Path bounds must not be negative");
    mPath = new Path(path);
    mPathMeasure = new PathMeasure(path, false);
    if (mPathMeasure.getLength() == 0) {
        // Treat zero-length paths as taps
        Path tempPath = new Path(path);
        tempPath.lineTo(-1, -1);
        mTapLocation = new float[2];
        PathMeasure pathMeasure = new PathMeasure(tempPath, false);
        pathMeasure.getPosTan(0, mTapLocation, null);
    }
    if (mPathMeasure.nextContour()) {
        throw new IllegalArgumentException("Path has more than one contour");
    }
    /*
     * Calling nextContour has moved mPathMeasure off the first contour, which is the only
     * one we care about. Set the path again to go back to the first contour.
     */
    mPathMeasure.setPath(mPath, false);
    mStartTime = startTime;
    mEndTime = startTime + duration;
    mTimeToLengthConversion = getLength() / duration;
    mId = sIdCounter++;
}
 
Example 4
Source File: AnimatedSvgView.java    From DanDanPlayForAndroid with MIT License 5 votes vote down vote up
/**
 * If you set the SVG data paths more than once using {@link #setGlyphStrings(String...)} you should call this method
 * before playing the animation.
 */
@SuppressWarnings("SuspiciousNameCombination")
public void rebuildGlyphData() {

    float X = mWidth / mViewport.x;
    float Y = mHeight / mViewport.y;

    Matrix scaleMatrix = new Matrix();
    RectF outerRect = new RectF(X, X, Y, Y);
    scaleMatrix.setScale(X, Y, outerRect.centerX(), outerRect.centerY());

    mGlyphData = new GlyphData[mGlyphStrings.length];
    for (int i = 0; i < mGlyphStrings.length; i++) {
        mGlyphData[i] = new GlyphData();
        try {
            mGlyphData[i].path = PathParser.createPathFromPathData(mGlyphStrings[i]);
            mGlyphData[i].path.transform(scaleMatrix);
        } catch (Exception e) {
            mGlyphData[i].path = new Path();
            Log.e(TAG, "Couldn't parse path", e);
        }
        PathMeasure pm = new PathMeasure(mGlyphData[i].path, true);
        while (true) {
            mGlyphData[i].length = Math.max(mGlyphData[i].length, pm.getLength());
            if (!pm.nextContour()) {
                break;
            }
        }
        mGlyphData[i].paint = new Paint();
        mGlyphData[i].paint.setStyle(Paint.Style.STROKE);
        mGlyphData[i].paint.setAntiAlias(true);
        mGlyphData[i].paint.setColor(Color.WHITE);
        mGlyphData[i].paint.setStrokeWidth(
                TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()));
    }
}
 
Example 5
Source File: AnimatedSvgView.java    From AnimatedSvgView with Apache License 2.0 5 votes vote down vote up
/**
 * If you set the SVG data paths more than once using {@link #setGlyphStrings(String...)} you should call this method
 * before playing the animation.
 */
@SuppressWarnings("SuspiciousNameCombination")
public void rebuildGlyphData() {

  float X = mWidth / mViewport.x;
  float Y = mHeight / mViewport.y;

  Matrix scaleMatrix = new Matrix();
  RectF outerRect = new RectF(X, X, Y, Y);
  scaleMatrix.setScale(X, Y, outerRect.centerX(), outerRect.centerY());

  mGlyphData = new GlyphData[mGlyphStrings.length];
  for (int i = 0; i < mGlyphStrings.length; i++) {
    mGlyphData[i] = new GlyphData();
    try {
      mGlyphData[i].path = PathParser.createPathFromPathData(mGlyphStrings[i]);
      mGlyphData[i].path.transform(scaleMatrix);
    } catch (Exception e) {
      mGlyphData[i].path = new Path();
      Log.e(TAG, "Couldn't parse path", e);
    }
    PathMeasure pm = new PathMeasure(mGlyphData[i].path, true);
    while (true) {
      mGlyphData[i].length = Math.max(mGlyphData[i].length, pm.getLength());
      if (!pm.nextContour()) {
        break;
      }
    }
    mGlyphData[i].paint = new Paint();
    mGlyphData[i].paint.setStyle(Paint.Style.STROKE);
    mGlyphData[i].paint.setAntiAlias(true);
    mGlyphData[i].paint.setColor(Color.WHITE);
    mGlyphData[i].paint.setStrokeWidth(
        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()));
  }
}
 
Example 6
Source File: Keyframes.java    From PathLayoutManager with Apache License 2.0 4 votes vote down vote up
private void initPath(Path path) {
    if (path == null || path.isEmpty()) {
        throw new NullPointerException("path is empty!");
    }
    final PathMeasure pathMeasure = new PathMeasure(path, false);
    mX = new float[0];
    mY = new float[0];
    mAngle = new float[0];
    do {
        final float pathLength = pathMeasure.getLength();
        final int numPoints = (int) (pathLength / PRECISION) + 1;
        final float[] x = new float[numPoints];
        final float[] y = new float[numPoints];
        final float[] angle = new float[numPoints];
        final float[] position = new float[2];
        final float[] tangent = new float[2];
        for (int i = 0; i < numPoints; ++i) {
            final float distance = (i * pathLength) / (numPoints - 1);
            pathMeasure.getPosTan(distance, position, tangent);
            if (position[0] > mMaxX) {
                mMaxX = position[0];
            }
            if (position[1] > mMaxY) {
                mMaxY = position[1];
            }
            x[i] = position[0];
            y[i] = position[1];
            angle[i] = fixAngle((float) (Math.atan2(tangent[1], tangent[0]) * 180F / Math.PI));
        }
        mNumPoints += numPoints;

        float[] tmpX = new float[mX.length + x.length];
        System.arraycopy(mX, 0, tmpX, 0, mX.length);
        System.arraycopy(x, 0, tmpX, mX.length, x.length);
        mX = tmpX;

        float[] tmpY = new float[mY.length + y.length];
        System.arraycopy(mY, 0, tmpY, 0, mY.length);
        System.arraycopy(y, 0, tmpY, mY.length, y.length);
        mY = tmpY;

        float[] tmpAngle = new float[mAngle.length + angle.length];
        System.arraycopy(mAngle, 0, tmpAngle, 0, mAngle.length);
        System.arraycopy(angle, 0, tmpAngle, mAngle.length, angle.length);
        mAngle = tmpAngle;
    } while (pathMeasure.nextContour());
}
 
Example 7
Source File: PathMeasureView.java    From zone-sdk with MIT License 4 votes vote down vote up
private void testNextContour(Canvas canvas) {

        Path path = new Path();

        path.addRect(-100, -100, 100, 100, Path.Direction.CW);  // 添加小矩形
        path.addRect(-200, -200, 200, 200, Path.Direction.CW);  // 添加大矩形

        canvas.drawPath(path, mDeafultPaint);                    // 绘制 Path

        PathMeasure measure = new PathMeasure(path, false);     // 将Path与PathMeasure关联

        float len1 = measure.getLength();                       // 获得第一条路径的长度

        measure.nextContour();                                  // 跳转到下一条路径

        float len2 = measure.getLength();                       // 获得第二条路径的长度

        Log.i("LEN", "len1=" + len1);                              // 输出两条路径的长度
        Log.i("LEN", "len2=" + len2);
    }