Пример #1
0
  private void buildShadow() {
    if (mShadowSize <= 0) return;

    if (mShadowPaint == null) {
      mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
      mShadowPaint.setStyle(Paint.Style.FILL);
      mShadowPaint.setDither(true);
    }
    float startRatio = (float) mRadius / (mRadius + mShadowSize + mShadowOffset);
    mShadowPaint.setShader(
        new RadialGradient(
            0,
            0,
            mRadius + mShadowSize,
            new int[] {COLOR_SHADOW_START, COLOR_SHADOW_START, COLOR_SHADOW_END},
            new float[] {0f, startRatio, 1f},
            Shader.TileMode.CLAMP));

    if (mShadowPath == null) {
      mShadowPath = new Path();
      mShadowPath.setFillType(Path.FillType.EVEN_ODD);
    } else mShadowPath.reset();
    float radius = mRadius + mShadowSize;
    mTempRect.set(-radius, -radius, radius, radius);
    mShadowPath.addOval(mTempRect, Path.Direction.CW);
    radius = mRadius - 1;
    mTempRect.set(-radius, -radius - mShadowOffset, radius, radius - mShadowOffset);
    mShadowPath.addOval(mTempRect, Path.Direction.CW);

    if (mGlowPaint == null) {
      mGlowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
      mGlowPaint.setStyle(Paint.Style.FILL);
      mGlowPaint.setDither(true);
    }
    startRatio = (mRadius - mShadowSize / 2f) / (mRadius + mShadowSize / 2f);
    mGlowPaint.setShader(
        new RadialGradient(
            0,
            0,
            mRadius + mShadowSize / 2f,
            new int[] {COLOR_SHADOW_START, COLOR_SHADOW_START, COLOR_SHADOW_END},
            new float[] {0f, startRatio, 1f},
            Shader.TileMode.CLAMP));

    if (mGlowPath == null) {
      mGlowPath = new Path();
      mGlowPath.setFillType(Path.FillType.EVEN_ODD);
    } else mGlowPath.reset();

    radius = mRadius + mShadowSize / 2f;
    mTempRect.set(-radius, -radius, radius, radius);
    mGlowPath.addOval(mTempRect, Path.Direction.CW);
    radius = mRadius - 1;
    mTempRect.set(-radius, -radius, radius, radius);
    mGlowPath.addOval(mTempRect, Path.Direction.CW);
  }
 /**
  * Creates arrow icon that depends on ExpandDirection
  *
  * @param context context
  * @param width width of icon in pixels
  * @param height height of icon in pixels
  * @param color arrow color
  * @param expandDirection arrow direction
  * @return icon drawable
  */
 private static Drawable createArrowIcon(
     Context context, int width, int height, int color, ExpandDirection expandDirection) {
   Bitmap canvasBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
   Canvas canvas = new Canvas(canvasBitmap);
   Paint paint = new Paint();
   paint.setStyle(Paint.Style.FILL_AND_STROKE);
   paint.setStrokeWidth(1);
   paint.setColor(color);
   paint.setAntiAlias(true);
   Path path = new Path();
   path.setFillType(Path.FillType.EVEN_ODD);
   switch (expandDirection) {
     case UP:
       path.moveTo(0, (height / 3) * 2);
       path.lineTo(width, (height / 3) * 2);
       path.lineTo(width / 2, height / 3);
       path.lineTo(0, (height / 3) * 2);
       break;
     case DOWN:
       path.moveTo(0, height / 3);
       path.lineTo(width, height / 3);
       path.lineTo(width / 2, (height / 3) * 2);
       path.lineTo(0, height / 3);
       break;
   }
   path.close();
   canvas.drawPath(path, paint);
   return new BitmapDrawable(context.getResources(), canvasBitmap);
 }
Пример #3
0
    private void drawTriangle(Canvas c, float startAngle, float sweepAngle, Rect bounds) {
      if (mShowArrow) {
        if (mArrow == null) {
          mArrow = new Path();
          mArrow.setFillType(Path.FillType.EVEN_ODD);
        } else {
          mArrow.reset();
        }

        // Adjust the position of the triangle so that it is inset as
        // much as the arc, but also centered on the arc.
        float inset = (int) mStrokeInset / 2 * mArrowScale;
        float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX());
        float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY());

        // Update the path each time. This works around an issue in SKIA
        // where concatenating a rotation matrix to a scale matrix
        // ignored a starting negative rotation. This appears to have
        // been fixed as of API 21.
        mArrow.moveTo(0, 0);
        mArrow.lineTo(mArrowWidth * mArrowScale, 0);
        mArrow.lineTo((mArrowWidth * mArrowScale / 2), (mArrowHeight * mArrowScale));
        mArrow.offset(x - inset, y);
        mArrow.close();
        // draw a triangle
        mArrowPaint.setColor(mColors[mColorIndex]);
        c.rotate(
            startAngle + sweepAngle - ARROW_OFFSET_ANGLE,
            bounds.exactCenterX(),
            bounds.exactCenterY());
        c.drawPath(mArrow, mArrowPaint);
      }
    }
 private void buildShadowCorners() {
   Object obj = new RectF(-mCornerRadius, -mCornerRadius, mCornerRadius, mCornerRadius);
   Object obj1 = new RectF(((RectF) (obj)));
   ((RectF) (obj1)).inset(-mShadowSize, -mShadowSize);
   float f;
   float f1;
   float f2;
   float f3;
   int i;
   int j;
   int k;
   if (mCornerShadowPath == null) {
     mCornerShadowPath = new Path();
   } else {
     mCornerShadowPath.reset();
   }
   mCornerShadowPath.setFillType(android.graphics.Path.FillType.EVEN_ODD);
   mCornerShadowPath.moveTo(-mCornerRadius, 0.0F);
   mCornerShadowPath.rLineTo(-mShadowSize, 0.0F);
   mCornerShadowPath.arcTo(((RectF) (obj1)), 180F, 90F, false);
   mCornerShadowPath.arcTo(((RectF) (obj)), 270F, -90F, false);
   mCornerShadowPath.close();
   f = mCornerRadius / (mCornerRadius + mShadowSize);
   obj = mCornerShadowPaint;
   f1 = mCornerRadius;
   f2 = mShadowSize;
   i = mShadowStartColor;
   j = mShadowStartColor;
   k = mShadowEndColor;
   obj1 = android.graphics.Shader.TileMode.CLAMP;
   ((Paint) (obj))
       .setShader(
           new RadialGradient(
               0.0F,
               0.0F,
               f1 + f2,
               new int[] {i, j, k},
               new float[] {0.0F, f, 1.0F},
               ((android.graphics.Shader.TileMode) (obj1))));
   obj = mEdgeShadowPaint;
   f = -mCornerRadius;
   f1 = mShadowSize;
   f2 = -mCornerRadius;
   f3 = mShadowSize;
   i = mShadowStartColor;
   j = mShadowStartColor;
   k = mShadowEndColor;
   obj1 = android.graphics.Shader.TileMode.CLAMP;
   ((Paint) (obj))
       .setShader(
           new LinearGradient(
               0.0F,
               f + f1,
               0.0F,
               f2 - f3,
               new int[] {i, j, k},
               new float[] {0.0F, 0.5F, 1.0F},
               ((android.graphics.Shader.TileMode) (obj1))));
   mEdgeShadowPaint.setAntiAlias(false);
 }
Пример #5
0
  private void drawPolygon(
      BinaryMapDataObject obj,
      RenderingRuleSearchRequest render,
      Canvas canvas,
      RenderingContext rc,
      TagValuePair pair) {
    if (render == null || pair == null) {
      return;
    }
    float xText = 0;
    float yText = 0;
    int zoom = rc.zoom;
    Path path = null;

    // rc.main.color = Color.rgb(245, 245, 245);
    render.setInitialTagValueZoom(pair.tag, pair.value, zoom, obj);
    boolean rendered = render.search(RenderingRulesStorage.POLYGON_RULES);
    if (!rendered || !updatePaint(render, paint, 0, true, rc)) {
      return;
    }
    rc.visible++;
    int len = obj.getPointsLength();
    for (int i = 0; i < obj.getPointsLength(); i++) {

      PointF p = calcPoint(obj, i, rc);
      xText += p.x;
      yText += p.y;
      if (path == null) {
        path = new Path();
        path.moveTo(p.x, p.y);
      } else {
        path.lineTo(p.x, p.y);
      }
    }
    int[][] polygonInnerCoordinates = obj.getPolygonInnerCoordinates();
    if (polygonInnerCoordinates != null && path != null) {
      path.setFillType(FillType.EVEN_ODD);
      for (int j = 0; j < polygonInnerCoordinates.length; j++) {
        for (int i = 0; i < polygonInnerCoordinates[j].length; i += 2) {
          PointF p =
              calcPoint(polygonInnerCoordinates[j][i], polygonInnerCoordinates[j][i + 1], rc);
          if (i == 0) {
            path.moveTo(p.x, p.y);
          } else {
            path.lineTo(p.x, p.y);
          }
        }
      }
    }

    if (path != null && len > 0) {
      canvas.drawPath(path, paint);
      if (updatePaint(render, paint, 1, false, rc)) {
        canvas.drawPath(path, paint);
      }
      textRenderer.renderText(obj, render, rc, pair, xText / len, yText / len, null, null);
    }
  }
 private void updatePath() {
   if (bounds.isEmpty()) return;
   path = null;
   RectF outerRect = TiUIHelper.insetRect(boundsF, mPadding);
   if (radius != null) {
     path = new Path();
     path.setFillType(FillType.EVEN_ODD);
     if (pathWidth > 0) {
       path.addRoundRect(outerRect, radius, Direction.CW);
       float padding = 0;
       float maxPadding = 0;
       RectF innerRect = new RectF();
       maxPadding = Math.min(bounds.width() / 2, bounds.height() / 2);
       padding = Math.min(pathWidth, maxPadding);
       innerRect.set(
           outerRect.left + padding,
           outerRect.top + padding,
           outerRect.right - padding,
           outerRect.bottom - padding);
       path.addRoundRect(innerRect, innerRadiusFromPadding(outerRect, padding), Direction.CCW);
     } else {
       // adjustment not see background under border because of antialias
       path.addRoundRect(TiUIHelper.insetRect(outerRect, 0.3f), radius, Direction.CW);
     }
   } else {
     if (pathWidth > 0) {
       path = new Path();
       path.setFillType(FillType.EVEN_ODD);
       path.addRect(outerRect, Direction.CW);
       int padding = 0;
       int maxPadding = 0;
       RectF innerRect = new RectF();
       maxPadding = (int) Math.min(bounds.width() / 2, bounds.height() / 2);
       padding = (int) Math.min(pathWidth, maxPadding);
       innerRect.set(
           outerRect.left + padding,
           outerRect.top + padding,
           outerRect.right - padding,
           outerRect.bottom - padding);
       path.addRect(innerRect, Direction.CCW);
     }
   }
 }
Пример #7
0
  private void drawArrow(Canvas c) {
    int height = getHeight();
    int width = getWidth();

    // Create a buffer around the arrow so when it rotates it doesn't get clipped by view edge
    final float BUFFER = width / 5;

    // Height of the cutout in the bottom of the triangle that makes it an arrow (0=triangle)
    final float CUTOUT_HEIGHT = getHeight() / 5;

    float x1, y1; // Tip of arrow
    x1 = width / 2;
    y1 = BUFFER;

    float x2, y2; // lower left
    x2 = BUFFER;
    y2 = height - BUFFER;

    float x3, y3; // cutout in arrow bottom
    x3 = width / 2;
    y3 = height - CUTOUT_HEIGHT - BUFFER;

    float x4, y4; // lower right
    x4 = width - BUFFER;
    y4 = height - BUFFER;

    Path path = new Path();
    path.setFillType(Path.FillType.EVEN_ODD);
    path.moveTo(x1, y1);
    path.lineTo(x2, y2);
    path.lineTo(x3, y3);
    path.lineTo(x4, y4);
    path.lineTo(x1, y1);
    path.close();

    float direction = mHeading - mBearingToStop;
    // Make sure value is between 0-360
    direction = MathUtils.mod(direction, 360.0f);

    // Rotate arrow around center point
    Matrix matrix = new Matrix();
    matrix.postRotate((float) -direction, width / 2, height / 2);
    path.transform(matrix);

    c.drawPath(path, mArrowPaint);
    c.drawPath(path, mArrowFillPaint);

    // Update content description, so screen readers can announce direction to stop
    String[] spokenDirections = getResources().getStringArray(R.array.spoken_compass_directions);
    String directionName = spokenDirections[MathUtils.getHalfWindIndex(direction)];
    setContentDescription(directionName);
  }
Пример #8
0
 private void drawOvalBackground(Canvas canvas, Rect bitmapRect) {
   final float left = Edge.LEFT.getCoordinate();
   final float top = Edge.TOP.getCoordinate();
   final float right = Edge.RIGHT.getCoordinate();
   final float bottom = Edge.BOTTOM.getCoordinate();
   RectF r = new RectF(left, top, right, bottom);
   Path path = new Path();
   path.addRect(
       bitmapRect.left, bitmapRect.top, bitmapRect.right, bitmapRect.bottom, Path.Direction.CW);
   path.addOval(r, Path.Direction.CCW);
   path.setFillType(Path.FillType.EVEN_ODD);
   canvas.drawPath(path, mBackgroundPaint);
 }
Пример #9
0
  private Path convertAwtPathToAndroid(PathIterator pi) {
    Path path = new Path();
    float[] coords = new float[6];
    while (!pi.isDone()) {
      int windingRule = pi.getWindingRule();

      if (windingRule == PathIterator.WIND_EVEN_ODD) {
        path.setFillType(Path.FillType.EVEN_ODD);
      } else {
        path.setFillType(Path.FillType.WINDING);
      }

      int pathType = pi.currentSegment(coords);

      switch (pathType) {
        case PathIterator.SEG_CLOSE:
          path.close();
          break;
        case PathIterator.SEG_CUBICTO:
          path.cubicTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
          break;
        case PathIterator.SEG_LINETO:
          path.lineTo(coords[0], coords[1]);
          break;
        case PathIterator.SEG_MOVETO:
          path.moveTo(coords[0], coords[1]);
          break;
        case PathIterator.SEG_QUADTO:
          path.quadTo(coords[0], coords[1], coords[2], coords[3]);
          break;
      }

      pi.next();
    }
    return path;
  }
Пример #10
0
  public void render(Collection<Triangle> triangles, Canvas canvas) {
    colorGenerator.setCount(triangles.size());
    for (Triangle triangle : triangles) {
      Path path = new Path();
      path.setFillType(Path.FillType.EVEN_ODD);

      path.moveTo(triangle.a.x, triangle.a.y);
      path.lineTo(triangle.b.x, triangle.b.y);
      path.lineTo(triangle.c.x, triangle.c.y);
      path.lineTo(triangle.a.x, triangle.a.y);

      path.close();

      trianglePaint.setColor(colorGenerator.nextColor());
      canvas.drawPath(path, trianglePaint);
    }
  }
Пример #11
0
  @Override
  public void calculate(
      int bitmapWidth,
      int bitmapHeight,
      float width,
      float height,
      float scale,
      float translateX,
      float translateY) {
    path.reset();
    float x = -translateX;
    float y = -translateY;
    float scaledTriangleHeight = triangleHeightPx / scale;
    float resultWidth = bitmapWidth + 2 * translateX;
    float resultHeight = bitmapHeight + 2 * translateY;
    float centerY = resultHeight / 2f + y;

    path.setFillType(Path.FillType.EVEN_ODD);
    float rectLeft;
    float rectRight;
    switch (arrowPosition) {
      case LEFT:
        rectLeft = scaledTriangleHeight + x;
        rectRight = resultWidth + rectLeft;
        path.addRect(rectLeft, y, rectRight, resultHeight + y, Path.Direction.CW);

        path.moveTo(x, centerY);
        path.lineTo(rectLeft, centerY - scaledTriangleHeight);
        path.lineTo(rectLeft, centerY + scaledTriangleHeight);
        path.lineTo(x, centerY);
        break;
      case RIGHT:
        rectLeft = x;
        float imgRight = resultWidth + rectLeft;
        rectRight = imgRight - scaledTriangleHeight;
        path.addRect(rectLeft, y, rectRight, resultHeight + y, Path.Direction.CW);
        path.moveTo(imgRight, centerY);
        path.lineTo(rectRight, centerY - scaledTriangleHeight);
        path.lineTo(rectRight, centerY + scaledTriangleHeight);
        path.lineTo(imgRight, centerY);
        break;
    }
  }
Пример #12
0
  private void buildShadowCorners() {
    RectF innerBounds = new RectF(-mCornerRadius, -mCornerRadius, mCornerRadius, mCornerRadius);
    RectF outerBounds = new RectF(innerBounds);
    outerBounds.inset(-mShadowSize, -mShadowSize);

    if (mCornerShadowPath == null) {
      mCornerShadowPath = new Path();
    } else {
      mCornerShadowPath.reset();
    }
    mCornerShadowPath.setFillType(Path.FillType.EVEN_ODD);
    mCornerShadowPath.moveTo(-mCornerRadius, 0);
    mCornerShadowPath.rLineTo(-mShadowSize, 0);
    // outer arc
    mCornerShadowPath.arcTo(outerBounds, 180f, 90f, false);
    // inner arc
    mCornerShadowPath.arcTo(innerBounds, 270f, -90f, false);
    mCornerShadowPath.close();

    float startRatio = mCornerRadius / (mCornerRadius + mShadowSize);
    mCornerShadowPaint.setShader(
        new RadialGradient(
            0,
            0,
            mCornerRadius + mShadowSize,
            new int[] {mShadowStartColor, mShadowStartColor, mShadowEndColor},
            new float[] {0f, startRatio, 1f},
            Shader.TileMode.CLAMP));

    // we offset the content shadowSize/2 pixels up to make it more realistic.
    // this is why edge shadow shader has some extra space
    // When drawing bottom edge shadow, we use that extra space.
    mEdgeShadowPaint.setShader(
        new LinearGradient(
            0,
            -mCornerRadius + mShadowSize,
            0,
            -mCornerRadius - mShadowSize,
            new int[] {mShadowStartColor, mShadowStartColor, mShadowEndColor},
            new float[] {0f, .5f, 1f},
            Shader.TileMode.CLAMP));
  }
  public NMapCalloutBasicOverlay(NMapOverlay itemOverlay, NMapOverlayItem item, Rect itemBounds) {
    super(itemOverlay, item, itemBounds);

    mInnerPaint = new Paint();
    mInnerPaint.setARGB(225, 75, 75, 75); // gray
    mInnerPaint.setAntiAlias(true);

    mBorderPaint = new Paint();
    mBorderPaint.setARGB(255, 255, 255, 255);
    mBorderPaint.setAntiAlias(true);
    mBorderPaint.setStyle(Style.STROKE);
    mBorderPaint.setStrokeWidth(2);

    mTextPaint = new Paint();
    mTextPaint.setARGB(255, 255, 255, 255);
    mTextPaint.setAntiAlias(true);

    mPath = new Path();
    mPath.setFillType(Path.FillType.WINDING);
  }
Пример #14
0
  protected void onDraw(Canvas canvas) {

    canvas.drawLine(8, height - 5, width - 8, height - 5, mPaintUnderline); // draw
    // underline

    // canvas.drawLine(8, height - 5, 8, height - 10, mPaintUnderline); // draw
    // left
    // corner

    Path path = new Path();
    path.setFillType(Path.FillType.EVEN_ODD);
    path.moveTo(width - 7, height - 4);
    path.lineTo(width - 25, height - 4);
    path.lineTo(width - 7, height - 25);
    // path.lineTo(width - 8, height -5);
    path.close();

    canvas.drawPath(path, mPaintTriangle);

    super.onDraw(canvas);
  }
Пример #15
0
  public void draw(Canvas c) {
    changeState();
    setBounds(xCoord - 50, yCoord - 20, xCoord + 50, yCoord + 20);
    Paint p = new Paint();
    Path path = new Path();
    path.setFillType(Path.FillType.EVEN_ODD);
    path.moveTo(xCoord - 50, yCoord);
    path.arcTo(new RectF(xCoord - 50, yCoord - 20, xCoord + 50, yCoord + 20), 180, 180);
    path.lineTo(xCoord, yCoord + 20);
    path.lineTo(xCoord - 50, yCoord);
    path.close();

    p.setColor(Color.CYAN);
    p.setStyle(Paint.Style.FILL_AND_STROKE);
    c.drawPath(path, p);
    p.setColor(Color.BLACK);
    p.setStyle(Paint.Style.STROKE);
    c.drawPath(path, p);

    if (yCoord < 0) {
      setComplete(true);
    }
  }
Пример #16
0
  /**
   * Creates a bus stop icon with the given direction arrow, or without a direction arrow if the
   * direction is NO_DIRECTION
   *
   * @param direction Bus stop direction, obtained from ObaStop.getDirection() and defined in
   *     constants in this class, or NO_DIRECTION if the stop icon shouldn't have a direction arrow
   * @return a bus stop icon bitmap with the arrow pointing the given direction, or with no arrow if
   *     direction is NO_DIRECTION
   */
  private static Bitmap createBusStopIcon(String direction) throws NullPointerException {
    if (direction == null) {
      throw new IllegalArgumentException(direction);
    }

    Resources r = Application.get().getResources();
    Context context = Application.get();

    Float directionAngle = null; // 0-360 degrees
    Bitmap bm;
    Canvas c;
    Drawable shape;
    Float rotationX = null, rotationY = null; // Point around which to rotate the arrow

    Paint arrowPaintFill = new Paint();
    arrowPaintFill.setStyle(Paint.Style.FILL);
    arrowPaintFill.setAntiAlias(true);

    if (direction.equals(NO_DIRECTION)) {
      // Don't draw the arrow
      bm = Bitmap.createBitmap(mPx, mPx, Bitmap.Config.ARGB_8888);
      c = new Canvas(bm);
      shape = ContextCompat.getDrawable(context, R.drawable.map_stop_icon);
      shape.setBounds(0, 0, bm.getWidth(), bm.getHeight());
    } else if (direction.equals(NORTH)) {
      directionAngle = 0f;
      bm = Bitmap.createBitmap(mPx, (int) (mPx + mBuffer), Bitmap.Config.ARGB_8888);
      c = new Canvas(bm);
      shape = ContextCompat.getDrawable(context, R.drawable.map_stop_icon);
      shape.setBounds(0, (int) mBuffer, mPx, bm.getHeight());
      // Shade with darkest color at tip of arrow
      arrowPaintFill.setShader(
          new LinearGradient(
              bm.getWidth() / 2,
              0,
              bm.getWidth() / 2,
              mArrowHeightPx,
              r.getColor(R.color.theme_primary),
              r.getColor(R.color.theme_accent),
              Shader.TileMode.MIRROR));
      // For NORTH, no rotation occurs - use center of image anyway so we have some value
      rotationX = bm.getWidth() / 2f;
      rotationY = bm.getHeight() / 2f;
    } else if (direction.equals(NORTH_WEST)) {
      directionAngle = 315f; // Arrow is drawn N, rotate 315 degrees
      bm =
          Bitmap.createBitmap(
              (int) (mPx + mBuffer), (int) (mPx + mBuffer), Bitmap.Config.ARGB_8888);
      c = new Canvas(bm);
      shape = ContextCompat.getDrawable(context, R.drawable.map_stop_icon);
      shape.setBounds((int) mBuffer, (int) mBuffer, bm.getWidth(), bm.getHeight());
      // Shade with darkest color at tip of arrow
      arrowPaintFill.setShader(
          new LinearGradient(
              0,
              0,
              mBuffer,
              mBuffer,
              r.getColor(R.color.theme_primary),
              r.getColor(R.color.theme_accent),
              Shader.TileMode.MIRROR));
      // Rotate around below coordinates (trial and error)
      rotationX = mPx / 2f + mBuffer / 2f;
      rotationY = bm.getHeight() / 2f - mBuffer / 2f;
    } else if (direction.equals(WEST)) {
      directionAngle = 0f; // Arrow is drawn pointing West, so no rotation
      bm = Bitmap.createBitmap((int) (mPx + mBuffer), mPx, Bitmap.Config.ARGB_8888);
      c = new Canvas(bm);
      shape = ContextCompat.getDrawable(context, R.drawable.map_stop_icon);
      shape.setBounds((int) mBuffer, 0, bm.getWidth(), bm.getHeight());
      arrowPaintFill.setShader(
          new LinearGradient(
              0,
              bm.getHeight() / 2,
              mArrowHeightPx,
              bm.getHeight() / 2,
              r.getColor(R.color.theme_primary),
              r.getColor(R.color.theme_accent),
              Shader.TileMode.MIRROR));
      // For WEST
      rotationX = bm.getHeight() / 2f;
      rotationY = bm.getHeight() / 2f;
    } else if (direction.equals(SOUTH_WEST)) {
      directionAngle = 225f; // Arrow is drawn N, rotate 225 degrees
      bm =
          Bitmap.createBitmap(
              (int) (mPx + mBuffer), (int) (mPx + mBuffer), Bitmap.Config.ARGB_8888);
      c = new Canvas(bm);
      shape = ContextCompat.getDrawable(context, R.drawable.map_stop_icon);
      shape.setBounds((int) mBuffer, 0, bm.getWidth(), mPx);
      arrowPaintFill.setShader(
          new LinearGradient(
              0,
              bm.getHeight(),
              mBuffer,
              bm.getHeight() - mBuffer,
              r.getColor(R.color.theme_primary),
              r.getColor(R.color.theme_accent),
              Shader.TileMode.MIRROR));
      // Rotate around below coordinates (trial and error)
      rotationX = bm.getWidth() / 2f - mBuffer / 4f;
      rotationY = mPx / 2f + mBuffer / 4f;
    } else if (direction.equals(SOUTH)) {
      directionAngle = 180f; // Arrow is drawn N, rotate 180 degrees
      bm = Bitmap.createBitmap(mPx, (int) (mPx + mBuffer), Bitmap.Config.ARGB_8888);
      c = new Canvas(bm);
      shape = ContextCompat.getDrawable(context, R.drawable.map_stop_icon);
      shape.setBounds(0, 0, bm.getWidth(), (int) (bm.getHeight() - mBuffer));
      arrowPaintFill.setShader(
          new LinearGradient(
              bm.getWidth() / 2,
              bm.getHeight(),
              bm.getWidth() / 2,
              bm.getHeight() - mArrowHeightPx,
              r.getColor(R.color.theme_primary),
              r.getColor(R.color.theme_accent),
              Shader.TileMode.MIRROR));
      rotationX = bm.getWidth() / 2f;
      rotationY = bm.getHeight() / 2f;
    } else if (direction.equals(SOUTH_EAST)) {
      directionAngle = 135f; // Arrow is drawn N, rotate 135 degrees
      bm =
          Bitmap.createBitmap(
              (int) (mPx + mBuffer), (int) (mPx + mBuffer), Bitmap.Config.ARGB_8888);
      c = new Canvas(bm);
      shape = ContextCompat.getDrawable(context, R.drawable.map_stop_icon);
      shape.setBounds(0, 0, mPx, mPx);
      arrowPaintFill.setShader(
          new LinearGradient(
              bm.getWidth(),
              bm.getHeight(),
              bm.getWidth() - mBuffer,
              bm.getHeight() - mBuffer,
              r.getColor(R.color.theme_primary),
              r.getColor(R.color.theme_accent),
              Shader.TileMode.MIRROR));
      // Rotate around below coordinates (trial and error)
      rotationX = (mPx + mBuffer / 2) / 2f;
      rotationY = bm.getHeight() / 2f;
    } else if (direction.equals(EAST)) {
      directionAngle = 180f; // Arrow is drawn pointing West, so rotate 180
      bm = Bitmap.createBitmap((int) (mPx + mBuffer), mPx, Bitmap.Config.ARGB_8888);
      c = new Canvas(bm);
      shape = ContextCompat.getDrawable(context, R.drawable.map_stop_icon);
      shape.setBounds(0, 0, mPx, bm.getHeight());
      arrowPaintFill.setShader(
          new LinearGradient(
              bm.getWidth(),
              bm.getHeight() / 2,
              bm.getWidth() - mArrowHeightPx,
              bm.getHeight() / 2,
              r.getColor(R.color.theme_primary),
              r.getColor(R.color.theme_accent),
              Shader.TileMode.MIRROR));
      rotationX = bm.getWidth() / 2f;
      rotationY = bm.getHeight() / 2f;
    } else if (direction.equals(NORTH_EAST)) {
      directionAngle = 45f; // Arrow is drawn pointing N, so rotate 45 degrees
      bm =
          Bitmap.createBitmap(
              (int) (mPx + mBuffer), (int) (mPx + mBuffer), Bitmap.Config.ARGB_8888);
      c = new Canvas(bm);
      shape = ContextCompat.getDrawable(context, R.drawable.map_stop_icon);
      shape.setBounds(0, (int) mBuffer, mPx, bm.getHeight());
      // Shade with darkest color at tip of arrow
      arrowPaintFill.setShader(
          new LinearGradient(
              bm.getWidth(),
              0,
              bm.getWidth() - mBuffer,
              mBuffer,
              r.getColor(R.color.theme_primary),
              r.getColor(R.color.theme_accent),
              Shader.TileMode.MIRROR));
      // Rotate around middle of circle
      rotationX = (float) mPx / 2;
      rotationY = bm.getHeight() - (float) mPx / 2;
    } else {
      throw new IllegalArgumentException(direction);
    }

    shape.draw(c);

    if (direction.equals(NO_DIRECTION)) {
      // Everything after this point is for drawing the arrow image, so return the bitmap as-is for
      // no arrow
      return bm;
    }

    /**
     * Draw the arrow - all dimensions should be relative to px so the arrow is drawn the same size
     * for all orientations
     */
    // Height of the cutout in the bottom of the triangle that makes it an arrow (0=triangle)
    final float CUTOUT_HEIGHT = mPx / 12;
    Path path = new Path();
    float x1 = 0, y1 = 0; // Tip of arrow
    float x2 = 0, y2 = 0; // lower left
    float x3 = 0, y3 = 0; // cutout in arrow bottom
    float x4 = 0, y4 = 0; // lower right

    if (direction.equals(NORTH)
        || direction.equals(SOUTH)
        || direction.equals(NORTH_EAST)
        || direction.equals(SOUTH_EAST)
        || direction.equals(NORTH_WEST)
        || direction.equals(SOUTH_WEST)) {
      // Arrow is drawn pointing NORTH
      // Tip of arrow
      x1 = mPx / 2;
      y1 = 0;

      // lower left
      x2 = (mPx / 2) - (mArrowWidthPx / 2);
      y2 = mArrowHeightPx;

      // cutout in arrow bottom
      x3 = mPx / 2;
      y3 = mArrowHeightPx - CUTOUT_HEIGHT;

      // lower right
      x4 = (mPx / 2) + (mArrowWidthPx / 2);
      y4 = mArrowHeightPx;
    } else if (direction.equals(EAST) || direction.equals(WEST)) {
      // Arrow is drawn pointing WEST
      // Tip of arrow
      x1 = 0;
      y1 = mPx / 2;

      // lower left
      x2 = mArrowHeightPx;
      y2 = (mPx / 2) - (mArrowWidthPx / 2);

      // cutout in arrow bottom
      x3 = mArrowHeightPx - CUTOUT_HEIGHT;
      y3 = mPx / 2;

      // lower right
      x4 = mArrowHeightPx;
      y4 = (mPx / 2) + (mArrowWidthPx / 2);
    }

    path.setFillType(Path.FillType.EVEN_ODD);
    path.moveTo(x1, y1);
    path.lineTo(x2, y2);
    path.lineTo(x3, y3);
    path.lineTo(x4, y4);
    path.lineTo(x1, y1);
    path.close();

    // Rotate arrow around (rotationX, rotationY) point
    Matrix matrix = new Matrix();
    matrix.postRotate(directionAngle, rotationX, rotationY);
    path.transform(matrix);

    c.drawPath(path, arrowPaintFill);
    c.drawPath(path, mArrowPaintStroke);

    return bm;
  }
Пример #17
0
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // 移动时候的状态
    if (VIEW_STATUS == VIEW_ACTIOMOVE_STATUS) {
      Log.i("CJT", "=========拖动状态=========");
      float length_temp =
          (float)
              Math.sqrt(
                  ((Math.abs(moveX - centerX) * Math.abs(moveX - centerX))
                      + (Math.abs(moveY - centerY) * Math.abs(moveY - centerY))));
      float radius_temp;
      //                if (radius <= length_temp) {
      //                    radius_temp = (radius / length_temp) * radius;
      //                } else {
      //                    radius_temp = radius/2;
      //                }
      radius_temp =
          radius / 2 < (radius / length_temp) * radius
              ? radius / 2
              : (radius / length_temp) * radius;
      canvas.drawCircle(centerX, centerY, radius_temp, mPaint);
      canvas.drawCircle(moveX, moveY, radius, mPaint);
      canvas.drawLine(centerX, centerY, moveX, moveY, mPaint);
      if (radius_temp / radius < 0.15) {
        Log.i("CJT", "半径比=" + radius_temp / radius);
        VIEW_STATUS = VIEW_BREAK_STATUS;
      }
      float x, y;

      y = ((Math.abs(centerX - moveX) / length_temp) * radius) + moveY;
      x = moveX - ((Math.abs(centerY - moveY) / length_temp) * radius);

      float lengthX = Math.abs(moveX - x);
      float lengthY = Math.abs(y - moveY);
      //            if (moveX < centerX && moveY < centerY) {
      //                canvas.drawLine(moveX - lengthX, moveY + lengthY, moveX + lengthX, moveY -
      // lengthY, mPaint);
      //            } else if (moveX > centerX && moveY < centerY) {
      //                canvas.drawLine(moveX - lengthX, moveY - lengthY, moveX + lengthX, moveY +
      // lengthY, mPaint);
      //            } else if (moveX > centerX && moveY > centerY) {
      //                canvas.drawLine(moveX - lengthX, moveY + lengthY, moveX + lengthX, moveY -
      // lengthY, mPaint);
      //            } else if (moveX < centerX && moveY > centerY) {
      //                canvas.drawLine(moveX - lengthX, moveY - lengthY, moveX + lengthX, moveY +
      // lengthY, mPaint);
      //            }

      float sx, sy;
      sy = ((Math.abs(centerX - moveX) / length_temp) * radius_temp) + centerY;
      sx = centerX - ((Math.abs(centerY - moveY) / length_temp) * radius_temp);
      float lengthsX = Math.abs(centerX - sx);
      float lengthsY = Math.abs(sy - centerY);

      if (moveX < centerX && moveY < centerY) {
        canvas.drawLine(moveX - lengthX, moveY + lengthY, moveX + lengthX, moveY - lengthY, mPaint);
        canvas.drawLine(
            centerX - lengthsX, centerY + lengthsY, centerX + lengthsX, centerY - lengthsY, mPaint);
      } else if (moveX > centerX && moveY < centerY) {
        canvas.drawLine(moveX - lengthX, moveY - lengthY, moveX + lengthX, moveY + lengthY, mPaint);
        canvas.drawLine(
            centerX - lengthsX, centerY - lengthsY, centerX + lengthsX, centerY + lengthsY, mPaint);
      } else if (moveX > centerX && moveY > centerY) {
        canvas.drawLine(moveX - lengthX, moveY + lengthY, moveX + lengthX, moveY - lengthY, mPaint);
        canvas.drawLine(
            centerX - lengthsX, centerY + lengthsY, centerX + lengthsX, centerY - lengthsY, mPaint);
      } else if (moveX < centerX && moveY > centerY) {
        canvas.drawLine(moveX - lengthX, moveY - lengthY, moveX + lengthX, moveY + lengthY, mPaint);
        canvas.drawLine(
            centerX - lengthsX, centerY - lengthsY, centerX + lengthsX, centerY + lengthsY, mPaint);
      }

      if (moveX < centerX && moveY < centerY) {
        //                canvas.drawLine(moveX - lengthX, moveY + lengthY, centerX - lengthsX,
        // centerY + lengthsY, mPaint);
        //                canvas.drawLine(moveX + lengthX, moveY - lengthY, centerX + lengthsX,
        // centerY - lengthsY, mPaint);

        mPath.reset();
        mPath.moveTo(moveX - lengthX, moveY + lengthY);
        mPath.quadTo(
            (moveX + centerX) / 2, (moveY + centerY) / 2, centerX - lengthsX, centerY + lengthsY);
        mPath.lineTo(centerX + lengthsX, centerY - lengthsY);
        mPath.quadTo(
            (moveX + centerX) / 2, (moveY + centerY) / 2, moveX + lengthX, moveY - lengthY);
        mPath.lineTo(moveX - lengthX, moveY + lengthY);
        mPath.close();
        mPath.setFillType(Path.FillType.WINDING);
        //                mPaint.setStyle(Paint.Style.FILL);
        canvas.drawPath(mPath, mPaint);
        //                mPaint.setStyle(Paint.Style.STROKE);

      } else if (moveX > centerX && moveY < centerY) {
        //                canvas.drawLine(moveX - lengthX, moveY - lengthY, centerX - lengthsX,
        // centerY - lengthsY, mPaint);
        //                canvas.drawLine(moveX + lengthX, moveY + lengthY, centerX + lengthsX,
        // centerY + lengthsY, mPaint);

        mPath.reset();
        mPath.moveTo(moveX - lengthX, moveY - lengthY);
        mPath.quadTo(
            (moveX + centerX) / 2, (moveY + centerY) / 2, centerX - lengthsX, centerY - lengthsY);
        mPath.lineTo(centerX + lengthsX, centerY + lengthsY);
        mPath.quadTo(
            (moveX + centerX) / 2, (moveY + centerY) / 2, moveX + lengthX, moveY + lengthY);
        mPath.lineTo(moveX - lengthX, moveY - lengthY);
        canvas.drawPath(mPath, mPaint);

      } else if (moveX > centerX && moveY > centerY) {
        //                canvas.drawLine(moveX - lengthX, moveY + lengthY, centerX - lengthsX,
        // centerY + lengthsY, mPaint);
        //                canvas.drawLine(moveX + lengthX, moveY - lengthY, centerX + lengthsX,
        // centerY - lengthsY, mPaint);

        mPath.reset();
        mPath.moveTo(moveX - lengthX, moveY + lengthY);
        mPath.quadTo(
            (moveX + centerX) / 2, (moveY + centerY) / 2, centerX - lengthsX, centerY + lengthsY);
        mPath.lineTo(centerX + lengthsX, centerY - lengthsY);
        mPath.quadTo(
            (moveX + centerX) / 2, (moveY + centerY) / 2, moveX + lengthX, moveY - lengthY);
        mPath.lineTo(moveX - lengthX, moveY + lengthY);
        canvas.drawPath(mPath, mPaint);
      } else if (moveX < centerX && moveY > centerY) {
        //                canvas.drawLine(moveX - lengthX, moveY - lengthY, centerX - lengthsX,
        // centerY - lengthsY, mPaint);
        //                canvas.drawLine(moveX + lengthX, moveY + lengthY, centerX + lengthsX,
        // centerY + lengthsY, mPaint);
        mPath.reset();
        mPath.moveTo(moveX - lengthX, moveY - lengthY);
        mPath.quadTo(
            (moveX + centerX) / 2, (moveY + centerY) / 2, centerX - lengthsX, centerY - lengthsY);
        mPath.lineTo(centerX + lengthsX, centerY + lengthsY);
        mPath.quadTo(
            (moveX + centerX) / 2, (moveY + centerY) / 2, moveX + lengthX, moveY + lengthY);
        mPath.lineTo(moveX - lengthX, moveY - lengthY);
        canvas.drawPath(mPath, mPaint);
      }

      //            canvas.drawText("99+", moveX, moveY, textPaint);
    } else if (VIEW_STATUS == VIEW_BREAK_STATUS) { // 断开时候的状态
      Log.i("CJT", "=========断开状态=========");
      canvas.drawCircle(moveX, moveY, radius, mPaint);
    } else if (VIEW_STATUS == VIEW_ACTION_STATUS) { // 初始状态
      Log.i("CJT", "=========初始状态=========");
      canvas.drawCircle(centerX, centerY, radius, mPaint);
      //            canvas.drawText("99+", centerX, centerY, textPaint);
    }
  }
  private Intent createShortcutIntent(int position) {
    String url = getUrl(position);
    String title = getBookmarkTitle(position);
    Bitmap touchIcon = getTouchIcon(position);

    final Intent i = new Intent();
    final Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
    long urlHash = url.hashCode();
    long uniqueId = (urlHash << 32) | shortcutIntent.hashCode();
    shortcutIntent.putExtra(Browser.EXTRA_APPLICATION_ID, Long.toString(uniqueId));
    i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
    i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
    // Use the apple-touch-icon if available
    if (touchIcon != null) {
      // Make a copy so we can modify the pixels.  We can't use
      // createScaledBitmap or copy since they will preserve the config
      // and lose the ability to add alpha.
      Bitmap bm = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ARGB_8888);
      Canvas canvas = new Canvas(bm);
      Rect src = new Rect(0, 0, touchIcon.getWidth(), touchIcon.getHeight());
      Rect dest = new Rect(0, 0, bm.getWidth(), bm.getHeight());

      // Paint used for scaling the bitmap and drawing the rounded rect.
      Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
      paint.setFilterBitmap(true);
      canvas.drawBitmap(touchIcon, src, dest, paint);

      // Construct a path from a round rect. This will allow drawing with
      // an inverse fill so we can punch a hole using the round rect.
      Path path = new Path();
      path.setFillType(Path.FillType.INVERSE_WINDING);
      RectF rect = new RectF(0, 0, bm.getWidth(), bm.getHeight());
      rect.inset(1, 1);
      path.addRoundRect(rect, 8f, 8f, Path.Direction.CW);

      // Reuse the paint and clear the outside of the rectangle.
      paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
      canvas.drawPath(path, paint);

      i.putExtra(Intent.EXTRA_SHORTCUT_ICON, bm);
    } else {
      Bitmap favicon = getFavicon(position);
      if (favicon == null) {
        i.putExtra(
            Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
            Intent.ShortcutIconResource.fromContext(
                BrowserBookmarksPage.this, R.drawable.ic_launcher_shortcut_browser_bookmark));
      } else {
        Bitmap icon =
            BitmapFactory.decodeResource(
                getResources(), R.drawable.ic_launcher_shortcut_browser_bookmark_icon);

        // Make a copy of the regular icon so we can modify the pixels.
        Bitmap copy = icon.copy(Bitmap.Config.ARGB_8888, true);
        Canvas canvas = new Canvas(copy);

        // Make a Paint for the white background rectangle and for
        // filtering the favicon.
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
        p.setStyle(Paint.Style.FILL_AND_STROKE);
        p.setColor(Color.WHITE);

        final float density = getResources().getDisplayMetrics().density;
        // Create a rectangle that is slightly wider than the favicon
        final float iconSize = 16 * density; // 16x16 favicon
        final float padding = 2 * density; // white padding around icon
        final float rectSize = iconSize + 2 * padding;

        final Rect iconBounds = new Rect(0, 0, icon.getWidth(), icon.getHeight());
        final float x = iconBounds.exactCenterX() - (rectSize / 2);
        // Note: Subtract 2 dip from the y position since the box is
        // slightly higher than center. Use padding since it is already
        // 2 * density.
        final float y = iconBounds.exactCenterY() - (rectSize / 2) - padding;
        RectF r = new RectF(x, y, x + rectSize, y + rectSize);

        // Draw a white rounded rectangle behind the favicon
        canvas.drawRoundRect(r, 2, 2, p);

        // Draw the favicon in the same rectangle as the rounded
        // rectangle but inset by the padding
        // (results in a 16x16 favicon).
        r.inset(padding, padding);
        canvas.drawBitmap(favicon, null, r, p);
        i.putExtra(Intent.EXTRA_SHORTCUT_ICON, copy);
      }
    }
    // Do not allow duplicate items
    i.putExtra("duplicate", false);
    return i;
  }