protected void onDraw(Canvas paramCanvas) {
   // today round
   if (mIsToday) {
     Paint painta = new Paint();
     painta.setStyle(Paint.Style.STROKE);
     painta.setColor(Color.BLACK);
     painta.setAntiAlias(true);
     Rect rect = paramCanvas.getClipBounds();
     RectF rt = new RectF(rect);
     rt.inset(getMeasuredWidth() / 12, getMeasuredHeight() / 12);
     paramCanvas.drawRoundRect(rt, getMeasuredWidth() / 5, getMeasuredHeight() / 5, painta);
     Paint paintb = new Paint();
     paintb.setColor(Color.GRAY);
     paintb.setAntiAlias(true);
     paintb.setAlpha(50);
     paramCanvas.drawRoundRect(rt, getMeasuredWidth() / 6, getMeasuredWidth() / 6, paintb);
   }
   // solar text
   Paint paint1 = new Paint();
   paint1.setAntiAlias(true);
   paint1.setFakeBoldText(true);
   paint1.setTextSize(getMeasuredWidth() / 2);
   if (mDay.mIsWeekEnd) {
     paint1.setColor(ECalendarActivity.mHolidayColor);
   } else {
     paint1.setColor(Color.BLACK);
   }
   Rect text = new Rect();
   paint1.getTextBounds(mDay.mSolarDay, 0, mDay.mSolarDay.length(), text);
   int w = getMeasuredWidth();
   int w1 = text.width();
   float fw = (w - w1) / 2;
   float fh = getMeasuredHeight() / 2 + 1;
   paramCanvas.drawText(mDay.mSolarDay, fw, fh, paint1);
   // lunar text
   Paint paint2 = new Paint();
   paint2.setAntiAlias(true);
   paint2.setTextSize(getMeasuredWidth() / 4);
   if (mDay.mIsFestival) {
     paint2.setColor(ECalendarActivity.mHolidayColor);
   } else {
     paint2.setColor(Color.BLACK);
   }
   paint2.getTextBounds(mDay.mLunarDay, 0, mDay.mLunarDay.length(), text);
   w1 = text.width();
   fw = (w - w1) / 2;
   fh = getMeasuredHeight() / 2 + 2 + text.height();
   paramCanvas.drawText(mDay.mLunarDay, fw, fh, paint2);
   if (mDay.mHasDiary) {
     Paint pd = new Paint();
     pd.setStyle(Paint.Style.STROKE);
     pd.setColor(ECalendarActivity.mHolidayColor);
     pd.setStrokeWidth(2);
     Rect rect = paramCanvas.getClipBounds();
     RectF rt = new RectF(rect);
     rt.inset(getMeasuredWidth() / 12, getMeasuredHeight() / 12);
     paramCanvas.drawLine(rt.left + rt.width() / 4, rt.top, rt.right - rt.width() / 4, rt.top, pd);
   }
 }
  // Grows the cropping rectange by (dx, dy) in image space.
  void growBy(float dx, float dy) {

    if (mMaintainAspectRatio) {
      if (dx != 0) {
        dy = dx / mInitialAspectRatio;
      } else if (dy != 0) {
        dx = dy * mInitialAspectRatio;
      }
    }

    // Don't let the cropping rectangle grow too fast.
    // Grow at most half of the difference between the image rectangle and
    // the cropping rectangle.
    RectF r = new RectF(mCropRect);
    if (dx > 0F && r.width() + 2 * dx > mImageRect.width()) {
      float adjustment = (mImageRect.width() - r.width()) / 2F;
      dx = adjustment;
      if (mMaintainAspectRatio) {
        dy = dx / mInitialAspectRatio;
      }
    }
    if (dy > 0F && r.height() + 2 * dy > mImageRect.height()) {
      float adjustment = (mImageRect.height() - r.height()) / 2F;
      dy = adjustment;
      if (mMaintainAspectRatio) {
        dx = dy * mInitialAspectRatio;
      }
    }

    r.inset(-dx, -dy);

    // Don't let the cropping rectangle shrink too fast.
    final float widthCap = 25F;
    if (r.width() < widthCap) {
      r.inset(-(widthCap - r.width()) / 2F, 0F);
    }
    float heightCap = mMaintainAspectRatio ? (widthCap / mInitialAspectRatio) : widthCap;
    if (r.height() < heightCap) {
      r.inset(0F, -(heightCap - r.height()) / 2F);
    }

    // Put the cropping rectangle inside the image rectangle.
    if (r.left < mImageRect.left) {
      r.offset(mImageRect.left - r.left, 0F);
    } else if (r.right > mImageRect.right) {
      r.offset(-(r.right - mImageRect.right), 0);
    }
    if (r.top < mImageRect.top) {
      r.offset(0F, mImageRect.top - r.top);
    } else if (r.bottom > mImageRect.bottom) {
      r.offset(0F, -(r.bottom - mImageRect.bottom));
    }

    mCropRect.set(r);
    mDrawRect = computeLayout();
    mContext.invalidate();
  }
  // Grows the cropping rectangle by (dx, dy) in image space.
  void growBy(float dx, float dy) {
    if (maintainAspectRatio) {
      if (dx != 0) {
        dy = dx / initialAspectRatio;
      } else if (dy != 0) {
        dx = dy * initialAspectRatio;
      }
    }

    // Don't let the cropping rectangle grow too fast.
    // Grow at most half of the difference between the image rectangle and
    // the cropping rectangle.
    RectF r = new RectF(cropRect);
    if (dx > 0F && r.width() + 2 * dx > imageRect.width()) {
      dx = (imageRect.width() - r.width()) / 2F;
      if (maintainAspectRatio) {
        dy = dx / initialAspectRatio;
      }
    }
    if (dy > 0F && r.height() + 2 * dy > imageRect.height()) {
      dy = (imageRect.height() - r.height()) / 2F;
      if (maintainAspectRatio) {
        dx = dy * initialAspectRatio;
      }
    }

    r.inset(-dx, -dy);

    // Don't let the cropping rectangle shrink too fast
    final float widthCap = 25F;
    if (r.width() < widthCap) {
      r.inset(-(widthCap - r.width()) / 2F, 0F);
    }
    float heightCap = maintainAspectRatio ? (widthCap / initialAspectRatio) : widthCap;
    if (r.height() < heightCap) {
      r.inset(0F, -(heightCap - r.height()) / 2F);
    }

    // Put the cropping rectangle inside the image rectangle
    if (r.left < imageRect.left) {
      r.offset(imageRect.left - r.left, 0F);
    } else if (r.right > imageRect.right) {
      r.offset(-(r.right - imageRect.right), 0F);
    }
    if (r.top < imageRect.top) {
      r.offset(0F, imageRect.top - r.top);
    } else if (r.bottom > imageRect.bottom) {
      r.offset(0F, -(r.bottom - imageRect.bottom));
    }

    cropRect.set(r);
    drawRect = computeLayout();
    viewContext.invalidate();
  }
Esempio n. 4
0
  @Override
  public void draw(Canvas canvas) {
    // Draw the bounding boxes
    drawBoundingBoxes(canvas);

    // Set the right values for the paint
    operatorPaint.setColor(getColor());
    operatorPaint.setTextSize(findTextSize());

    // Get our operator bounding boxes
    Rect[] operatorBounding = this.getOperatorBoundingBoxes();

    // Draws the operator
    canvas.save();
    Rect textBounding = new Rect();
    operatorPaint.getTextBounds(type.getName(), 0, type.getName().length(), textBounding);
    canvas.translate(
        (operatorBounding[0].width() - textBounding.width()) / 2,
        (operatorBounding[0].height() - textBounding.height()) / 2);
    canvas.drawText(
        type.getName(),
        operatorBounding[0].left - textBounding.left,
        operatorBounding[0].top - textBounding.top,
        operatorPaint);
    canvas.restore();

    // Use stroke style for the parentheses
    operatorPaint.setStyle(Paint.Style.STROKE);

    // Draw the left bracket
    canvas.save();
    canvas.clipRect(operatorBounding[1], Region.Op.INTERSECT);
    RectF bracket = new RectF(operatorBounding[1]);
    bracket.inset(0, -operatorPaint.getStrokeWidth());
    bracket.offset(bracket.width() / 4, 0);
    canvas.drawArc(bracket, 100.0f, 160.0f, false, operatorPaint);
    canvas.restore();

    // Draw the right bracket
    canvas.save();
    canvas.clipRect(operatorBounding[2], Region.Op.INTERSECT);
    bracket = new RectF(operatorBounding[2]);
    bracket.inset(0, -operatorPaint.getStrokeWidth());
    bracket.offset(-bracket.width() / 4, 0);
    canvas.drawArc(bracket, -80.0f, 160.0f, false, operatorPaint);
    canvas.restore();

    // Set the paint back to fill style
    operatorPaint.setStyle(Paint.Style.FILL);

    // Draw the children
    drawChildren(canvas);
  }
  @Override
  public void draw(Canvas canvas, MapView mapView, boolean shadow) {
    // Get the map projection to convert lat/long to screen coordinates
    Projection projection = mapView.getProjection();

    Point lPoint = new Point();
    projection.toPixels(locationPoint, lPoint);

    // Draw the overlay
    if (shadow == false) {
      if (friendLocations.size() > 0) {
        Iterator<String> e = friendLocations.keySet().iterator();
        do {
          // Get the name and location of each contact
          String name = e.next();
          Location location = friendLocations.get(name);

          // Convert the lat / long to a Geopoint
          Double latitude = location.getLatitude() * 1E6;
          Double longitude = location.getLongitude() * 1E6;
          GeoPoint geopoint = new GeoPoint(latitude.intValue(), longitude.intValue());

          // Ensure each contact is within 10km
          float dist = location.distanceTo(getLocation());
          if (dist < 10000) {
            Point point = new Point();
            projection.toPixels(geopoint, point);

            // Draw a line connecting the contact to your current location.
            canvas.drawLine(lPoint.x, lPoint.y, point.x, point.y, paint);

            // Draw a marker at the contact's location.
            RectF oval =
                new RectF(
                    point.x - markerRadius,
                    point.y - markerRadius,
                    point.x + markerRadius,
                    point.y + markerRadius);

            canvas.drawOval(oval, backPaint);
            oval.inset(2, 2);
            canvas.drawOval(oval, paint);

            // Draw the contact's name next to their position.
            float textWidth = paint.measureText(name);
            float textHeight = paint.getTextSize();
            RectF textRect =
                new RectF(
                    point.x + markerRadius,
                    point.y - textHeight,
                    point.x + markerRadius + 8 + textWidth,
                    point.y + 4);
            canvas.drawRoundRect(textRect, 3, 3, backPaint);
            canvas.drawText(name, point.x + markerRadius + 4, point.y, paint);
          }
        } while (e.hasNext());
      }
    }
    super.draw(canvas, mapView, shadow);
  }
Esempio n. 6
0
 private boolean findTextIntersection(
     Canvas cv,
     RenderingContext rc,
     QuadTree<TextDrawInfo> boundIntersections,
     TextDrawInfo text) {
   // for test purposes
   //		drawTestBox(cv, text.bounds, text.pathRotate, text.text);
   boundIntersections.queryInBox(text.bounds, tempSearch);
   for (int i = 0; i < tempSearch.size(); i++) {
     TextDrawInfo t = tempSearch.get(i);
     if (intersects(text.bounds, text.pathRotate, t.bounds, t.pathRotate)) {
       return true;
     }
   }
   if (text.minDistance > 0) {
     RectF boundsSearch = new RectF(text.bounds);
     boundsSearch.inset(
         -rc.getDensityValue(Math.max(5.0f, text.minDistance)), -rc.getDensityValue(15));
     boundIntersections.queryInBox(boundsSearch, tempSearch);
     // drawTestBox(cv, &boundsSearch, text.pathRotate, paintIcon, text.text, NULL/*paintText*/);
     for (int i = 0; i < tempSearch.size(); i++) {
       TextDrawInfo t = tempSearch.get(i);
       if (t.minDistance > 0
           && t.text.equals(text.text)
           && intersects(boundsSearch, text.pathRotate, t.bounds, t.pathRotate)) {
         return true;
       }
     }
   }
   boundIntersections.insert(text, text.bounds);
   return false;
 }
  protected void drawCenterText(Canvas c) {

    SpannableString centerText = mChart.getCenterText();

    if (mChart.isDrawCenterTextEnabled() && centerText != null) {

      PointF center = mChart.getCenterCircleBox();

      float innerRadius =
          mChart.isDrawHoleEnabled() && mChart.isHoleTransparent()
              ? mChart.getRadius() * (mChart.getHoleRadius() / 100f)
              : mChart.getRadius();

      RectF holeRect = mRectBuffer[0];
      holeRect.left = center.x - innerRadius;
      holeRect.top = center.y - innerRadius;
      holeRect.right = center.x + innerRadius;
      holeRect.bottom = center.y + innerRadius;
      RectF boundingRect = mRectBuffer[1];
      boundingRect.set(holeRect);

      float radiusPercent = mChart.getCenterTextRadiusPercent();
      if (radiusPercent > 0.0) {
        boundingRect.inset(
            (boundingRect.width() - boundingRect.width() * radiusPercent) / 2.f,
            (boundingRect.height() - boundingRect.height() * radiusPercent) / 2.f);
      }

      if (!centerText.equals(mCenterTextLastValue) || !boundingRect.equals(mCenterTextLastBounds)) {

        // Next time we won't recalculate StaticLayout...
        mCenterTextLastBounds.set(boundingRect);
        mCenterTextLastValue = centerText;

        float width = mCenterTextLastBounds.width();

        // If width is 0, it will crash. Always have a minimum of 1
        mCenterTextLayout =
            new StaticLayout(
                centerText,
                0,
                centerText.length(),
                mCenterTextPaint,
                (int) Math.max(Math.ceil(width), 1.f),
                Layout.Alignment.ALIGN_CENTER,
                1.f,
                0.f,
                false);
      }

      float layoutHeight = mCenterTextLayout.getHeight();

      c.save();
      c.translate(
          boundingRect.left, boundingRect.top + (boundingRect.height() - layoutHeight) / 2.f);
      mCenterTextLayout.draw(c);
      c.restore();
    }
  }
 /**
  * Adjust left and right edges by current crop window height and the given aspect ratio, both
  * right and left edges adjusts equally relative to center to keep aspect ratio to the height.
  */
 private void adjustLeftRightByAspectRatio(RectF rect, RectF bounds, float aspectRatio) {
   rect.inset((rect.width() - rect.height() * aspectRatio) / 2, 0);
   if (rect.left < bounds.left) {
     rect.offset(bounds.left - rect.left, 0);
   }
   if (rect.right > bounds.right) {
     rect.offset(bounds.right - rect.right, 0);
   }
 }
 /**
  * Adjust top and bottom edges by current crop window width and the given aspect ratio, both top
  * and bottom edges adjusts equally relative to center to keep aspect ratio to the width.
  */
 private void adjustTopBottomByAspectRatio(RectF rect, RectF bounds, float aspectRatio) {
   rect.inset(0, (rect.height() - rect.width() / aspectRatio) / 2);
   if (rect.top < bounds.top) {
     rect.offset(0, bounds.top - rect.top);
   }
   if (rect.bottom > bounds.bottom) {
     rect.offset(0, bounds.bottom - rect.bottom);
   }
 }
 /**
  * Adjusts the gradient used for the chart series to set the shader used in the paint. This is
  * only done if the line contains two colors and the bounds of the line has changed since it was
  * last set.
  *
  * @param bounds The bounds used to draw the chart
  */
 protected void processBoundsChange(final RectF bounds) {
   if (mBounds == null || !mBounds.equals(bounds)) {
     mBounds = new RectF(bounds);
     mBoundsInset = new RectF(bounds);
     if (mSeriesItem.getInset() != null) {
       mBoundsInset.inset(mSeriesItem.getInset().x, mSeriesItem.getInset().y);
     }
     applyGradientToPaint();
   }
 }
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    mInnerRectF.set(0, 0, canvas.getWidth(), canvas.getHeight());
    final int halfBorder = (int) (mStrokePaint.getStrokeWidth() / 2f + 0.5f);
    mInnerRectF.inset(halfBorder, halfBorder);

    canvas.drawArc(mInnerRectF, 0, 360, true, mBackgroundPaint);

    switch (mProgressFillType) {
      case FILL_TYPE_RADIAL:
        float sweepAngle = 360 * mProgress / mMax;
        canvas.drawArc(mInnerRectF, mStartAngle, sweepAngle, true, mProgressPaint);
        break;
      case FILL_TYPE_CENTER:
        float centerX = canvas.getWidth() / 2;
        float centerY = canvas.getHeight() / 2;
        float radius = (canvas.getWidth() / 2) * ((float) mProgress / mMax);
        canvas.drawCircle(
            centerX, centerY, radius + 0.5f - mStrokePaint.getStrokeWidth(), mProgressPaint);
        break;
      default:
        throw new IllegalArgumentException("Invalid Progress Fill = " + mProgressFillType);
    }

    if (!TextUtils.isEmpty(mText) && mShowText) {
      if (!TextUtils.isEmpty(mTypeface)) {
        Typeface typeface = sTypefaceCache.get(mTypeface);
        if (null == typeface && null != getResources()) {
          AssetManager assets = getResources().getAssets();
          if (null != assets) {
            typeface = Typeface.createFromAsset(assets, mTypeface);
            sTypefaceCache.put(mTypeface, typeface);
          }
        }
        mTextPaint.setTypeface(typeface);
      }
      int xPos = canvas.getWidth() / 2;
      int yPos =
          (int) ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2));
      canvas.drawText(mText, xPos, yPos, mTextPaint);
    }

    if (null != mImage && mShowImage) {
      int drawableSize = mImage.getIntrinsicWidth();
      mImageRect.set(0, 0, drawableSize, drawableSize);
      mImageRect.offset((getWidth() - drawableSize) / 2, (getHeight() - drawableSize) / 2);
      mImage.setBounds(mImageRect);
      mImage.draw(canvas);
    }

    if (mShowStroke) {
      canvas.drawOval(mInnerRectF, mStrokePaint);
    }
  }
Esempio n. 12
0
        // For each face, we create a HightlightView for it.
        private void handleFace(FaceDetector.Face f) {

          PointF midPoint = new PointF();

          int r = ((int) (f.eyesDistance() * mScale)) * 2;
          f.getMidPoint(midPoint);
          midPoint.x *= mScale;
          midPoint.y *= mScale;

          int midX = (int) midPoint.x;
          int midY = (int) midPoint.y;

          HighlightView hv = new HighlightView(mImageView);

          int width = mBitmap.getWidth();
          int height = mBitmap.getHeight();

          Rect imageRect = new Rect(0, 0, width, height);

          RectF faceRect = new RectF(midX, midY, midX, midY);
          faceRect.inset(-r, -r);
          if (faceRect.left < 0) {
            faceRect.inset(-faceRect.left, -faceRect.left);
          }

          if (faceRect.top < 0) {
            faceRect.inset(-faceRect.top, -faceRect.top);
          }

          if (faceRect.right > imageRect.right) {
            faceRect.inset(faceRect.right - imageRect.right, faceRect.right - imageRect.right);
          }

          if (faceRect.bottom > imageRect.bottom) {
            faceRect.inset(faceRect.bottom - imageRect.bottom, faceRect.bottom - imageRect.bottom);
          }

          hv.setup(mImageMatrix, imageRect, faceRect, mCircleCrop, mAspectX != 0 && mAspectY != 0);

          mImageView.add(hv);
        }
  private void drawBorder(Canvas canvas) {
    RectF rect = new RectF(getBounds());
    rect.inset(borderThickness / 2, borderThickness / 2);

    if (shape instanceof OvalShape) {
      canvas.drawOval(rect, borderPaint);
    } else if (shape instanceof RoundRectShape) {
      canvas.drawRoundRect(rect, radius, radius, borderPaint);
    } else {
      canvas.drawRect(rect, borderPaint);
    }
  }
 public final void draw(Canvas paramCanvas) {
   Rect localRect = getBounds();
   int i = paramCanvas.save();
   paramCanvas.rotate(this.mRotation, localRect.exactCenterX(), localRect.exactCenterY());
   Ring localRing = this.mRing;
   RectF localRectF = localRing.mTempBounds;
   localRectF.set(localRect);
   localRectF.inset(localRing.mStrokeInset, localRing.mStrokeInset);
   float f1 = 360.0F * (localRing.mStartTrim + localRing.mRotation);
   float f2 = 360.0F * (localRing.mEndTrim + localRing.mRotation) - f1;
   localRing.mPaint.setColor(localRing.mCurrentColor);
   paramCanvas.drawArc(localRectF, f1, f2, false, localRing.mPaint);
   if (localRing.mShowArrow) {
     if (localRing.mArrow != null) {
       break label427;
     }
     localRing.mArrow = new Path();
     localRing.mArrow.setFillType(Path.FillType.EVEN_ODD);
   }
   for (; ; ) {
     float f3 = (int) localRing.mStrokeInset / 2 * localRing.mArrowScale;
     float f4 = (float) (localRing.mRingCenterRadius * Math.cos(0.0D) + localRect.exactCenterX());
     float f5 = (float) (localRing.mRingCenterRadius * Math.sin(0.0D) + localRect.exactCenterY());
     localRing.mArrow.moveTo(0.0F, 0.0F);
     localRing.mArrow.lineTo(localRing.mArrowWidth * localRing.mArrowScale, 0.0F);
     localRing.mArrow.lineTo(
         localRing.mArrowWidth * localRing.mArrowScale / 2.0F,
         localRing.mArrowHeight * localRing.mArrowScale);
     localRing.mArrow.offset(f4 - f3, f5);
     localRing.mArrow.close();
     localRing.mArrowPaint.setColor(localRing.mCurrentColor);
     paramCanvas.rotate(f1 + f2 - 5.0F, localRect.exactCenterX(), localRect.exactCenterY());
     paramCanvas.drawPath(localRing.mArrow, localRing.mArrowPaint);
     if (localRing.mAlpha < 255) {
       localRing.mCirclePaint.setColor(localRing.mBackgroundColor);
       localRing.mCirclePaint.setAlpha(255 - localRing.mAlpha);
       paramCanvas.drawCircle(
           localRect.exactCenterX(),
           localRect.exactCenterY(),
           localRect.width() / 2,
           localRing.mCirclePaint);
     }
     paramCanvas.restoreToCount(i);
     return;
     label427:
     localRing.mArrow.reset();
   }
 }
Esempio n. 15
0
  private void setup() {
    if (!mReady) {
      mSetupPending = true;
      return;
    }

    if (getWidth() == 0 && getHeight() == 0) {
      return;
    }

    if (mBitmap == null) {
      invalidate();
      return;
    }

    // 给图片设置bitmapShader,到时花园时,画的便是这张图片
    mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    mBitmapPaint.setAntiAlias(true);
    mBitmapPaint.setShader(mBitmapShader);

    mBorderPaint.setStyle(Paint.Style.STROKE);
    mBorderPaint.setAntiAlias(true);
    mBorderPaint.setColor(mBorderColor);
    mBorderPaint.setStrokeWidth(mBorderWidth);

    mFillPaint.setStyle(Paint.Style.FILL);
    mFillPaint.setAntiAlias(true);
    mFillPaint.setColor(mFillColor);

    mBitmapHeight = mBitmap.getHeight();
    mBitmapWidth = mBitmap.getWidth();

    mBorderRect.set(calculateBounds());
    mBorderRadius =
        Math.min(
            (mBorderRect.height() - mBorderWidth) / 2.0f,
            (mBorderRect.width() - mBorderWidth) / 2.0f);

    mDrawableRect.set(mBorderRect);
    if (!mBorderOverlay && mBorderWidth > 0) {
      mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f);
    }
    mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);

    applyColorFilter();
    updateShaderMatrix();
    invalidate();
  }
Esempio n. 16
0
  private void setup() {

    if (!ready) {
      setupPending = true;
      return;
    }

    if (getWidth() == 0 && getHeight() == 0) {
      return;
    }

    if (bitmap == null) {
      invalidate();
      return;
    }

    bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

    bitmapPaint.setAntiAlias(true);
    bitmapPaint.setShader(bitmapShader);

    borderPaint.setStyle(Paint.Style.STROKE);
    borderPaint.setAntiAlias(true);
    borderPaint.setColor(borderColor);
    borderPaint.setStrokeWidth(borderWidth);

    fillPaint.setStyle(Paint.Style.FILL);
    fillPaint.setAntiAlias(true);
    fillPaint.setColor(fillColor);

    bitmapHeight = bitmap.getHeight();
    bitmapWidth = bitmap.getWidth();

    borderRect.set(0, 0, getWidth(), getHeight());
    borderRadius =
        Math.min(
            (borderRect.height() - borderWidth) / 2.0f, (borderRect.width() - borderWidth) / 2.0f);

    drawableRect.set(borderRect);
    if (!borderOverlay) {
      drawableRect.inset(borderWidth, borderWidth);
    }
    drawableRadius = Math.min(drawableRect.height() / 2.0f, drawableRect.width() / 2.0f);

    updateShaderMatrix();
    invalidate();
  }
  /**
   * The size of the indicator is same as the content region of the {@link #mBgDrawable} minus half
   * the stroke size to accommodate the indicator.
   */
  private void initIndicatorRect() {
    Drawable d = mBgDrawable;
    Rect bounds = d.getBounds();

    d.getPadding(sTempRect);
    // Amount by which padding has to be scaled
    float paddingScaleX = ((float) bounds.width()) / d.getIntrinsicWidth();
    float paddingScaleY = ((float) bounds.height()) / d.getIntrinsicHeight();
    mIndicatorRect.set(
        bounds.left + sTempRect.left * paddingScaleX,
        bounds.top + sTempRect.top * paddingScaleY,
        bounds.right - sTempRect.right * paddingScaleX,
        bounds.bottom - sTempRect.bottom * paddingScaleY);

    float inset = mPaint.getStrokeWidth() / 2;
    mIndicatorRect.inset(inset, inset);
    mIndicatorRectDirty = false;
  }
    /** Draw the progress spinner */
    public void draw(Canvas c, Rect bounds) {

      mCirclePaint.setColor(mBackgroundColor);
      mCirclePaint.setAlpha(mAlpha);

      c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2, mCirclePaint);

      final RectF arcBounds = mTempBounds;
      arcBounds.set(bounds);
      arcBounds.inset(mStrokeInset, mStrokeInset);
      final float startAngle = (mStartTrim + mRotation) * 360;
      final float endAngle = (mEndTrim + mRotation) * 360;
      float sweepAngle = endAngle - startAngle;
      mArcPaint.setColor(mColors[mColorIndex]);
      mArcPaint.setAlpha(mAlpha);
      c.drawArc(arcBounds, startAngle, sweepAngle, false, mArcPaint);
      drawTriangle(c, startAngle, sweepAngle, bounds);
    }
Esempio n. 19
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));
  }
  private Path createRiverPath(RectF arcBounds) {
    if (mRiverPath != null) {
      return mRiverPath;
    }

    mRiverPath = new Path();

    RectF rectF =
        new RectF(
            arcBounds.centerX() - mRiverWidth / 2.0f,
            arcBounds.centerY() - mRiverHeight / 2.0f,
            arcBounds.centerX() + mRiverWidth / 2.0f,
            arcBounds.centerY() + mRiverHeight / 2.0f);

    rectF.inset(mStrokeWidth / 2.0f, mStrokeWidth / 2.0f);

    mRiverPath.addRect(rectF, Path.Direction.CW);

    return mRiverPath;
  }
Esempio n. 21
0
 private void drawArcs(Canvas c, int width, int height) {
   mPaint.setStrokeWidth(STROKE_WIDTH);
   // firstCircleDrawPoint is circle diameter + circle width
   float firstCircleDrawPoint = THICK_STROKE_WIDTH - STROKE_WIDTH / 2;
   RectF rect =
       new RectF(
           firstCircleDrawPoint,
           firstCircleDrawPoint,
           width - firstCircleDrawPoint,
           height - firstCircleDrawPoint);
   float degree = mPercentage * 360f;
   if (mInDrag) {
     mPaint.setStrokeWidth(THICK_STROKE_WIDTH);
     float sizeChange = -(THICK_STROKE_WIDTH - STROKE_WIDTH) / 2;
     rect.inset(sizeChange, sizeChange);
   }
   mPaint.setStyle(Paint.Style.STROKE);
   mPaint.setColor(mPrimaryColor);
   c.drawArc(rect, -90f, degree, false, mPaint);
 }
  private void setup() {
    if (!mReady) {
      mSetupPending = true;
      return;
    }

    if (mBitmap == null) {
      return;
    }

    mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

    mBitmapPaint.setAntiAlias(true);
    mBitmapPaint.setShader(mBitmapShader);

    mBorderPaint.setStyle(Paint.Style.STROKE);
    mBorderPaint.setAntiAlias(true);
    mBorderPaint.setColor(mBorderColor);
    mBorderPaint.setStrokeWidth(mBorderWidth);

    mBitmapHeight = mBitmap.getHeight();
    mBitmapWidth = mBitmap.getWidth();

    mBorderRect.set(0, 0, getWidth(), getHeight());
    mBorderRadius =
        Math.min(
            (mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);

    mDrawableRect.set(mBorderRect);
    if (!mBorderOverlay) {
      mDrawableRect.inset(mBorderWidth, mBorderWidth);
    }
    mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);

    updateShaderMatrix();
    invalidate();
  }
  private void updatePath() {
    if (!mNeedUpdatePathForBorderRadius) {
      return;
    }
    mNeedUpdatePathForBorderRadius = false;
    if (mPathForBorderRadius == null) {
      mPathForBorderRadius = new Path();
      mTempRectForBorderRadius = new RectF();
      mPathForBorderRadiusOutline = new Path();
      mTempRectForBorderRadiusOutline = new RectF();
    }

    mPathForBorderRadius.reset();
    mPathForBorderRadiusOutline.reset();

    mTempRectForBorderRadius.set(getBounds());
    mTempRectForBorderRadiusOutline.set(getBounds());
    float fullBorderWidth = getFullBorderWidth();
    if (fullBorderWidth > 0) {
      mTempRectForBorderRadius.inset(fullBorderWidth * 0.5f, fullBorderWidth * 0.5f);
    }

    float defaultBorderRadius = !CSSConstants.isUndefined(mBorderRadius) ? mBorderRadius : 0;
    float topLeftRadius =
        mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[0])
            ? mBorderCornerRadii[0]
            : defaultBorderRadius;
    float topRightRadius =
        mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[1])
            ? mBorderCornerRadii[1]
            : defaultBorderRadius;
    float bottomRightRadius =
        mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[2])
            ? mBorderCornerRadii[2]
            : defaultBorderRadius;
    float bottomLeftRadius =
        mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[3])
            ? mBorderCornerRadii[3]
            : defaultBorderRadius;

    mPathForBorderRadius.addRoundRect(
        mTempRectForBorderRadius,
        new float[] {
          topLeftRadius,
          topLeftRadius,
          topRightRadius,
          topRightRadius,
          bottomRightRadius,
          bottomRightRadius,
          bottomLeftRadius,
          bottomLeftRadius
        },
        Path.Direction.CW);

    float extraRadiusForOutline = 0;

    if (mBorderWidth != null) {
      extraRadiusForOutline = mBorderWidth.get(Spacing.ALL) / 2f;
    }

    mPathForBorderRadiusOutline.addRoundRect(
        mTempRectForBorderRadiusOutline,
        new float[] {
          topLeftRadius + extraRadiusForOutline,
          topLeftRadius + extraRadiusForOutline,
          topRightRadius + extraRadiusForOutline,
          topRightRadius + extraRadiusForOutline,
          bottomRightRadius + extraRadiusForOutline,
          bottomRightRadius + extraRadiusForOutline,
          bottomLeftRadius + extraRadiusForOutline,
          bottomLeftRadius + extraRadiusForOutline
        },
        Path.Direction.CW);
  }
Esempio n. 24
0
 void c(float paramFloat1, float paramFloat2)
 {
   boolean bool = ImageViewTouchBase.a;
   if (this.h)
     if (paramFloat1 != 0.0F)
     {
       paramFloat2 = paramFloat1 / this.i;
       if (bool)
         App.wc = 1 + App.wc;
     }
     else if (paramFloat2 != 0.0F)
     {
       paramFloat1 = paramFloat2 * this.i;
     }
   RectF localRectF = new RectF(this.f);
   float f1;
   if ((paramFloat1 > 0.0F) && (localRectF.width() + 2.0F * paramFloat1 > this.e.width()))
   {
     paramFloat1 = (this.e.width() - localRectF.width()) / 2.0F;
     if (this.h)
       f1 = paramFloat1 / this.i;
   }
   for (float f2 = paramFloat1; ; f2 = paramFloat1)
   {
     if ((f1 > 0.0F) && (localRectF.height() + 2.0F * f1 > this.e.height()))
     {
       f1 = (this.e.height() - localRectF.height()) / 2.0F;
       if (this.h)
         f2 = f1 * this.i;
     }
     if (this.k > 0)
     {
       if (localRectF.width() + 2.0F * f2 < this.k)
         f2 = (this.k - localRectF.width()) / 2.0F;
       if (this.h)
         f1 = f2 / this.i;
       if (localRectF.height() + 2.0F * f1 < this.k)
         f1 = (this.k - localRectF.height()) / 2.0F;
       if (this.h)
         f2 = f1 * this.i;
     }
     localRectF.inset(-f2, -f1);
     if (localRectF.width() < 25.0F)
       localRectF.inset(-(25.0F - localRectF.width()) / 2.0F, 0.0F);
     if (this.h);
     for (float f3 = 25.0F / this.i; ; f3 = 25.0F)
     {
       if (localRectF.height() < f3)
         localRectF.inset(0.0F, -(f3 - localRectF.height()) / 2.0F);
       if (localRectF.left < this.e.left)
       {
         localRectF.offset(this.e.left - localRectF.left, 0.0F);
         if (!bool);
       }
       else if (localRectF.right > this.e.right)
       {
         localRectF.offset(-(localRectF.right - this.e.right), 0.0F);
       }
       if (localRectF.top < this.e.top)
       {
         localRectF.offset(0.0F, this.e.top - localRectF.top);
         if (!bool);
       }
       else if (localRectF.bottom > this.e.bottom)
       {
         localRectF.offset(0.0F, -(localRectF.bottom - this.e.bottom));
       }
       this.f.set(localRectF);
       this.d = d();
       this.a.invalidate();
       return;
     }
     f1 = paramFloat2;
   }
 }
  @Override
  protected void onDraw(Canvas canvas) {
    int selectedIndex = getSelectedIndicatorIndex();

    // Draw the highlight arc if an indicator is selected or being pressed.
    // And skip the zoom control which index is zero.
    if (selectedIndex >= 1) {
      int degree = (int) Math.toDegrees(mChildRadians[selectedIndex]);
      float innerR = (float) mShutterButtonRadius;
      float outerR = (float) (mShutterButtonRadius + mStrokeWidth + EDGE_STROKE_WIDTH * 0.5);

      // Construct the path of the fan-shaped semi-transparent area.
      Path fanPath = new Path();
      mBackgroundRect.set(
          mCenterX - innerR, mCenterY - innerR, mCenterX + innerR, mCenterY + innerR);
      fanPath.arcTo(mBackgroundRect, -degree + HIGHLIGHT_DEGREES / 2, -HIGHLIGHT_DEGREES);
      mBackgroundRect.set(
          mCenterX - outerR, mCenterY - outerR, mCenterX + outerR, mCenterY + outerR);
      fanPath.arcTo(mBackgroundRect, -degree - HIGHLIGHT_DEGREES / 2, HIGHLIGHT_DEGREES);
      fanPath.close();

      mBackgroundPaint.setStrokeWidth(HIGHLIGHT_WIDTH);
      mBackgroundPaint.setStrokeCap(Paint.Cap.SQUARE);
      mBackgroundPaint.setStyle(Paint.Style.FILL_AND_STROKE);
      mBackgroundPaint.setColor(HIGHLIGHT_FAN_COLOR);
      if (FeatureOption.MTK_THEMEMANAGER_APP) {
        int bgColor = res.getThemeMainColor();
        if (bgColor != 0) {
          bgColor &= 0x3FFFFFFF;
          mBackgroundPaint.setColor(bgColor);
        }
      }
      canvas.drawPath(fanPath, mBackgroundPaint);

      // Draw the highlight edge
      mBackgroundPaint.setStyle(Paint.Style.STROKE);
      mBackgroundPaint.setColor(HIGHLIGHT_COLOR);
      if (FeatureOption.MTK_THEMEMANAGER_APP) {
        int bgColor = res.getThemeMainColor();
        if (bgColor != 0) {
          mBackgroundPaint.setColor(bgColor);
        }
      }
      canvas.drawArc(
          mBackgroundRect,
          -degree - HIGHLIGHT_DEGREES / 2,
          HIGHLIGHT_DEGREES,
          false,
          mBackgroundPaint);
    }

    // Draw arc shaped indicator in time lapse recording.
    if (mTimeLapseInterval != 0) {
      // Setup rectangle and paint.
      mBackgroundRect.set(
          (float) (mCenterX - mShutterButtonRadius),
          (float) (mCenterY - mShutterButtonRadius),
          (float) (mCenterX + mShutterButtonRadius),
          (float) (mCenterY + mShutterButtonRadius));
      mBackgroundRect.inset(3f, 3f);
      mBackgroundPaint.setStrokeWidth(TIME_LAPSE_ARC_WIDTH);
      mBackgroundPaint.setStrokeCap(Paint.Cap.ROUND);
      mBackgroundPaint.setColor(TIME_LAPSE_ARC_COLOR);

      // Compute the start angle and sweep angle.
      long timeDelta = SystemClock.uptimeMillis() - mRecordingStartTime;
      long numberOfFrames = timeDelta / mTimeLapseInterval;
      float sweepAngle;
      if (numberOfFrames > mNumberOfFrames) {
        // The arc just acrosses 0 degree. Draw a full circle so it
        // looks better.
        sweepAngle = 360;
        mNumberOfFrames = numberOfFrames;
      } else {
        sweepAngle = timeDelta % mTimeLapseInterval * 360f / mTimeLapseInterval;
      }

      canvas.drawArc(mBackgroundRect, 0, sweepAngle, false, mBackgroundPaint);
      invalidate();
    }

    super.onDraw(canvas);
  }
 void c(float paramFloat1, float paramFloat2)
 {
   RectF localRectF;
   float f1;
   float f2;
   if (this.j)
   {
     if (paramFloat1 != 0.0F)
       paramFloat2 = paramFloat1 / this.k;
   }
   else
   {
     localRectF = new RectF(this.e);
     if ((paramFloat1 <= 0.0F) || (localRectF.width() + 2.0F * paramFloat1 <= this.i.width()))
       break label412;
     paramFloat1 = (this.i.width() - localRectF.width()) / 2.0F;
     if (!this.j)
       break label412;
     f1 = paramFloat1 / this.k;
     f2 = paramFloat1;
   }
   while (true)
   {
     if ((f1 > 0.0F) && (localRectF.height() + 2.0F * f1 > this.i.height()))
     {
       f1 = (this.i.height() - localRectF.height()) / 2.0F;
       if (this.j)
         f2 = f1 * this.k;
     }
     localRectF.inset(-f2, -f1);
     if (localRectF.width() < 25.0F)
       localRectF.inset(-(25.0F - localRectF.width()) / 2.0F, 0.0F);
     float f3;
     if (this.j)
     {
       f3 = 25.0F / this.k;
       label203: if (localRectF.height() < f3)
         localRectF.inset(0.0F, -(f3 - localRectF.height()) / 2.0F);
       if (localRectF.left >= this.i.left)
         break label340;
       localRectF.offset(this.i.left - localRectF.left, 0.0F);
       label260: if (localRectF.top >= this.i.top)
         break label376;
       localRectF.offset(0.0F, this.i.top - localRectF.top);
     }
     while (true)
     {
       this.e.set(localRectF);
       this.d = e();
       this.a.invalidate();
       return;
       if (paramFloat2 == 0.0F)
         break;
       paramFloat1 = paramFloat2 * this.k;
       break;
       f3 = 25.0F;
       break label203;
       label340: if (localRectF.right <= this.i.right)
         break label260;
       localRectF.offset(-(localRectF.right - this.i.right), 0.0F);
       break label260;
       label376: if (localRectF.bottom <= this.i.bottom)
         continue;
       localRectF.offset(0.0F, -(localRectF.bottom - this.i.bottom));
     }
     label412: f1 = paramFloat2;
     f2 = paramFloat1;
   }
 }
Esempio n. 27
0
  /**
   * draws the description text in the center of the pie chart makes most sense when center-hole is
   * enabled
   */
  protected void drawCenterText(Canvas c) {

    CharSequence centerText = mChart.getCenterText();

    if (mChart.isDrawCenterTextEnabled() && centerText != null) {

      PointF center = mChart.getCenterCircleBox();

      float innerRadius =
          mChart.isDrawHoleEnabled()
              ? mChart.getRadius() * (mChart.getHoleRadius() / 100f)
              : mChart.getRadius();

      RectF holeRect = mRectBuffer[0];
      holeRect.left = center.x - innerRadius;
      holeRect.top = center.y - innerRadius;
      holeRect.right = center.x + innerRadius;
      holeRect.bottom = center.y + innerRadius;
      RectF boundingRect = mRectBuffer[1];
      boundingRect.set(holeRect);

      float radiusPercent = mChart.getCenterTextRadiusPercent() / 100f;
      if (radiusPercent > 0.0) {
        boundingRect.inset(
            (boundingRect.width() - boundingRect.width() * radiusPercent) / 2.f,
            (boundingRect.height() - boundingRect.height() * radiusPercent) / 2.f);
      }

      if (!centerText.equals(mCenterTextLastValue) || !boundingRect.equals(mCenterTextLastBounds)) {

        // Next time we won't recalculate StaticLayout...
        mCenterTextLastBounds.set(boundingRect);
        mCenterTextLastValue = centerText;

        float width = mCenterTextLastBounds.width();

        // If width is 0, it will crash. Always have a minimum of 1
        mCenterTextLayout =
            new StaticLayout(
                centerText,
                0,
                centerText.length(),
                mCenterTextPaint,
                (int) Math.max(Math.ceil(width), 1.f),
                Layout.Alignment.ALIGN_CENTER,
                1.f,
                0.f,
                false);
      }

      // I wish we could make an ellipse clipping path on Android to clip to the hole...
      // If we ever find out how, this is the place to add it, based on holeRect

      // float layoutWidth = Utils.getStaticLayoutMaxWidth(mCenterTextLayout);
      float layoutHeight = mCenterTextLayout.getHeight();

      c.save();
      c.translate(
          boundingRect.left, boundingRect.top + (boundingRect.height() - layoutHeight) / 2.f);
      mCenterTextLayout.draw(c);
      c.restore();

      //            }
      //
      //        else {
      //
      //
      //                // get all lines from the text
      //                String[] lines = centerText.toString().split("\n");
      //
      //                float maxlineheight = 0f;
      //
      //                // calc the maximum line height
      //                for (String line : lines) {
      //                    float curHeight = Utils.calcTextHeight(mCenterTextPaint, line);
      //                    if (curHeight > maxlineheight)
      //                        maxlineheight = curHeight;
      //                }
      //
      //                float linespacing = maxlineheight * 0.25f;
      //
      //                float totalheight = maxlineheight * lines.length - linespacing *
      // (lines.length - 1);
      //
      //                int cnt = lines.length;
      //
      //                float y = center.y;
      //
      //                for (int i = 0; i < lines.length; i++) {
      //
      //                    String line = lines[lines.length - i - 1];
      //
      //
      //
      //                    c.drawText(line, center.x, y
      //                                    + maxlineheight * cnt - totalheight / 2f,
      //                            mCenterTextPaint);
      //                    cnt--;
      //                    y -= linespacing;
      //                }
      //            }
    }
  }
Esempio n. 28
0
  public void drawTextOverCanvas(RenderingContext rc, Canvas cv, boolean useEnglishNames) {
    int size = rc.textToDraw.size();

    // 1. Sort text using text order
    Collections.sort(
        rc.textToDraw,
        new Comparator<TextDrawInfo>() {
          @Override
          public int compare(TextDrawInfo object1, TextDrawInfo object2) {
            return object1.textOrder - object2.textOrder;
          }
        });
    RectF r = new RectF(0, 0, rc.width, rc.height);
    r.inset(-100, -100);
    QuadTree<TextDrawInfo> nonIntersectedBounds = new QuadTree<TextDrawInfo>(r, 4, 0.6f);

    for (int i = 0; i < size; i++) {
      TextDrawInfo text = rc.textToDraw.get(i);
      if (text.text != null && text.text.length() > 0) {
        if (useEnglishNames) {
          text.text = Junidecode.unidecode(text.text);
        }

        // sest text size before finding intersection (it is used there)
        float textSize = rc.getDensityValue(text.textSize);
        paintText.setTextSize(textSize);
        paintText.setFakeBoldText(text.bold);
        paintText.setColor(text.textColor);
        // align center y
        text.centerY += (-paintText.ascent());

        // calculate if there is intersection
        boolean intersects = findTextIntersection(cv, rc, nonIntersectedBounds, text);
        if (!intersects) {
          if (text.drawOnPath != null) {
            if (text.textShadow > 0) {
              paintText.setColor(Color.WHITE);
              paintText.setStyle(Style.STROKE);
              paintText.setStrokeWidth(2 + text.textShadow);
              cv.drawTextOnPath(text.text, text.drawOnPath, 0, text.vOffset, paintText);
              // reset
              paintText.setStyle(Style.FILL);
              paintText.setStrokeWidth(2);
              paintText.setColor(text.textColor);
            }
            cv.drawTextOnPath(text.text, text.drawOnPath, 0, text.vOffset, paintText);
          } else {
            if (text.shieldRes != null) {
              Bitmap ico = RenderingIcons.getIcon(context, text.shieldRes);
              if (ico != null) {

                if (rc.highResMode) {
                  float left = text.centerX - rc.getDensityValue(ico.getWidth() / 2) - 0.5f;
                  float top =
                      text.centerY
                          - rc.getDensityValue(ico.getHeight() / 2)
                          - rc.getDensityValue(4.5f);
                  Rect rec = new Rect(0, 0, ico.getWidth(), ico.getHeight());
                  cv.drawBitmap(
                      ico,
                      rec,
                      new RectF(
                          left,
                          top,
                          left + rc.getDensityValue(ico.getWidth()),
                          top + rc.getDensityValue(ico.getHeight())),
                      paintIcon);
                } else {
                  float left = text.centerX - ico.getWidth() / 2 - 0.5f;
                  float top = text.centerY - ico.getHeight() / 2 - rc.getDensityValue(4.5f);
                  cv.drawBitmap(ico, left, top, paintIcon);
                }
              }
            }

            drawWrappedText(cv, text, textSize);
          }
        }
      }
    }
  }
  private void updateShaderMatrix() {
    float scale;
    float dx;
    float dy;

    switch (mScaleType) {
      case CENTER:
        mBorderRect.set(mBounds);
        mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);

        mShaderMatrix.set(null);
        mShaderMatrix.setTranslate(
            (int) ((mBorderRect.width() - mBitmapWidth) * 0.5f + 0.5f),
            (int) ((mBorderRect.height() - mBitmapHeight) * 0.5f + 0.5f));
        break;

      case CENTER_CROP:
        mBorderRect.set(mBounds);
        mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);

        mShaderMatrix.set(null);

        dx = 0;
        dy = 0;

        if (mBitmapWidth * mBorderRect.height() > mBorderRect.width() * mBitmapHeight) {
          scale = mBorderRect.height() / (float) mBitmapHeight;
          dx = (mBorderRect.width() - mBitmapWidth * scale) * 0.5f;
        } else {
          scale = mBorderRect.width() / (float) mBitmapWidth;
          dy = (mBorderRect.height() - mBitmapHeight * scale) * 0.5f;
        }

        mShaderMatrix.setScale(scale, scale);
        mShaderMatrix.postTranslate(
            (int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth);
        break;

      case CENTER_INSIDE:
        mShaderMatrix.set(null);

        if (mBitmapWidth <= mBounds.width() && mBitmapHeight <= mBounds.height()) {
          scale = 1.0f;
        } else {
          scale =
              Math.min(
                  mBounds.width() / (float) mBitmapWidth, mBounds.height() / (float) mBitmapHeight);
        }

        dx = (int) ((mBounds.width() - mBitmapWidth * scale) * 0.5f + 0.5f);
        dy = (int) ((mBounds.height() - mBitmapHeight * scale) * 0.5f + 0.5f);

        mShaderMatrix.setScale(scale, scale);
        mShaderMatrix.postTranslate(dx, dy);

        mBorderRect.set(mBitmapRect);
        mShaderMatrix.mapRect(mBorderRect);
        mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
        mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
        break;

      default:
      case FIT_CENTER:
        mBorderRect.set(mBitmapRect);
        mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.CENTER);
        mShaderMatrix.mapRect(mBorderRect);
        mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
        mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
        break;

      case FIT_END:
        mBorderRect.set(mBitmapRect);
        mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.END);
        mShaderMatrix.mapRect(mBorderRect);
        mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
        mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
        break;

      case FIT_START:
        mBorderRect.set(mBitmapRect);
        mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.START);
        mShaderMatrix.mapRect(mBorderRect);
        mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
        mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
        break;

      case FIT_XY:
        mBorderRect.set(mBounds);
        mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
        mShaderMatrix.set(null);
        mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
        break;
    }

    mDrawableRect.set(mBorderRect);
    mBitmapShader.setLocalMatrix(mShaderMatrix);
  }
  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;
  }