Example #1
0
  private Item createItem(String label, float percent, int sliceColor, int itemColor) {
    Item it = new Item();
    it.mLabel = label;
    it.mItemColor = itemColor;
    it.cSliceColor = sliceColor;
    it.cPercent = percent;
    //        Log.d(TAG, "Percent for "+it.mLabel+": "+it.cPercent);

    // Calculate the highlight color. Saturate at 0xff to make sure that high values
    // don't result in aliasing.
    it.mItemHighlight =
        Color.argb(
            0xff,
            Math.min((int) (mHighlightStrength * (float) Color.red(itemColor)), 0xff),
            Math.min((int) (mHighlightStrength * (float) Color.green(itemColor)), 0xff),
            Math.min((int) (mHighlightStrength * (float) Color.blue(itemColor)), 0xff));

    it.cSliceHighlight =
        Color.argb(
            0xff,
            Math.min((int) (mHighlightStrength * (float) Color.red(sliceColor)), 0xff),
            Math.min((int) (mHighlightStrength * (float) Color.green(sliceColor)), 0xff),
            Math.min((int) (mHighlightStrength * (float) Color.blue(sliceColor)), 0xff));

    float centerX = mPieBounds.width() / 2;
    float centerY = mPieBounds.height() / 2;
    float itemW = (mPieBounds.width() / 2) * it.cPercent;
    float itemH = (mPieBounds.height() / 2) * it.cPercent;
    it.cSliceBounds = new RectF(centerX - itemW, centerY - itemH, centerX + itemW, centerY + itemH);

    return it;
  }
Example #2
0
 public PointF getElementCoordinates(
     float height, float width, RectF viewRect, PositionMetrics metrics) {
   float x = metrics.getXPositionMetric().getPixelValue(viewRect.width()) + viewRect.left;
   float y = metrics.getYPositionMetric().getPixelValue(viewRect.height()) + viewRect.top;
   PointF point = new PointF(x, y);
   return PixelUtils.sub(point, getAnchorOffset(width, height, metrics.getAnchor()));
 }
Example #3
0
  public SVGTileProvider(File file, float dpi) throws IOException {
    mScale = Math.round(dpi + .3f); // Make it look nice on N7 (1.3 dpi)
    mDimension = BASE_TILE_SIZE * mScale;

    mPool = new TileGeneratorPool(POOL_MAX_SIZE);

    SVG svg = new SVGBuilder().readFromInputStream(new FileInputStream(file)).build();
    mSvgPicture = svg.getPicture();
    RectF limits = svg.getLimits();

    // These values map the SVG file to world coordinates.
    // See: http://stackoverflow.com/questions/21167584/google-io-2013-app-mystery-values
    mBaseMatrix = new Matrix();
    mBaseMatrix.setPolyToPoly(
        new float[] {
          0,
          0, // North-West
          limits.width(),
          0, // North-East
          limits.width(),
          limits.height() // South-East
        },
        0,
        BuildConfig.MAP_FLOORPLAN_MAPPING,
        0,
        3);
  }
Example #4
0
 public boolean onTouch(View view, MotionEvent event) {
   float x = event.getX();
   float y = event.getY();
   switch (event.getAction()) {
     case MotionEvent.ACTION_DOWN:
       path.moveTo(x, y);
       return true;
     case MotionEvent.ACTION_UP:
     case MotionEvent.ACTION_MOVE:
       l = x;
       r = x;
       t = y;
       b = y;
       for (int i = 0; i < event.getHistorySize(); i++) {
         float newX = event.getHistoricalX(i);
         float newY = event.getHistoricalY(i);
         path.lineTo(newX, newY);
         l = newX < l ? newX : l;
         t = newY < t ? newY : t;
         r = newX > r ? newX : r;
         b = newY > b ? newY : b;
       }
       rect.set(l, t, r, b);
       Log.d("TAG", rect.toShortString());
       invalidate(
           (int) rect.left - 5, (int) rect.top - 5, (int) rect.right + 5, (int) rect.bottom + 5);
       break;
     default:
   }
   return super.onTouchEvent(event);
 }
  // ==============================================================================
  public final int[] renderGlyph(
      char glyph, Paint paint, android.graphics.Matrix matrix, Rect bounds) {
    Path p = new Path();
    paint.getTextPath(String.valueOf(glyph), 0, 1, 0.0f, 0.0f, p);

    RectF boundsF = new RectF();
    p.computeBounds(boundsF, true);
    matrix.mapRect(boundsF);

    boundsF.roundOut(bounds);
    bounds.left--;
    bounds.right++;

    final int w = bounds.width();
    final int h = bounds.height();

    Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

    Canvas c = new Canvas(bm);
    matrix.postTranslate(-bounds.left, -bounds.top);
    c.setMatrix(matrix);
    c.drawPath(p, paint);

    final int sizeNeeded = w * h;
    if (cachedRenderArray.length < sizeNeeded) cachedRenderArray = new int[sizeNeeded];

    bm.getPixels(cachedRenderArray, 0, w, 0, 0, w, h);
    bm.recycle();
    return cachedRenderArray;
  }
  /**
   * Drawing src bitmap to dest bitmap with rounded corners
   *
   * @param src source bitmap
   * @param dest destination bitmap
   * @param radius radius in destination bitmap scale
   * @param clearColor clear color
   */
  public static void drawRoundedCorners(Bitmap src, Bitmap dest, int radius, int clearColor) {
    clearBitmap(dest, clearColor);
    Canvas canvas = new Canvas(dest);

    Rect sourceRect = WorkCache.RECT1.get();
    Rect destRect = WorkCache.RECT2.get();
    sourceRect.set(0, 0, src.getWidth(), src.getHeight());
    destRect.set(0, 0, dest.getWidth(), dest.getHeight());

    RectF roundRect = WorkCache.RECTF1.get();
    roundRect.set(0, 0, dest.getWidth(), dest.getHeight());

    Paint paint = WorkCache.PAINT.get();
    paint.reset();
    paint.setStyle(Paint.Style.FILL);
    paint.setColor(Color.RED);
    paint.setAntiAlias(true);
    canvas.drawRoundRect(roundRect, radius, radius, paint);

    paint.reset();
    paint.setFilterBitmap(true);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(src, sourceRect, destRect, paint);

    canvas.setBitmap(null);
  }
  private void computePath(Rect bounds) {
    final float currentScale = mCurrentScale;
    final Path path = mPath;
    final RectF rect = mRect;
    final Matrix matrix = mMatrix;

    path.reset();
    int totalSize = Math.min(bounds.width(), bounds.height());

    float initial = mClosedStateSize;
    float destination = totalSize;
    float currentSize = initial + (destination - initial) * currentScale;

    float halfSize = currentSize / 2f;
    float inverseScale = 1f - currentScale;
    float cornerSize = halfSize * inverseScale;
    float[] corners =
        new float[] {
          halfSize, halfSize, halfSize, halfSize, halfSize, halfSize, cornerSize, cornerSize
        };
    rect.set(bounds.left, bounds.top, bounds.left + currentSize, bounds.top + currentSize);
    path.addRoundRect(rect, corners, Path.Direction.CCW);
    matrix.reset();
    matrix.postRotate(-45, bounds.left + halfSize, bounds.top + halfSize);
    matrix.postTranslate((bounds.width() - currentSize) / 2, 0);
    float hDiff = (bounds.bottom - currentSize - mExternalOffset) * inverseScale;
    matrix.postTranslate(0, hDiff);
    path.transform(matrix);
  }
 @Override
 protected void onBoundsChange(Rect bounds) {
   super.onBoundsChange(bounds);
   fBounds.left = bounds.left + mBorderWidth / 2f + .5f;
   fBounds.right = bounds.right - mBorderWidth / 2f - .5f;
   fBounds.top = bounds.top + mBorderWidth / 2f + .5f;
   fBounds.bottom = bounds.bottom - mBorderWidth / 2f - .5f;
 }
Example #9
0
  /** Do all of the recalculations needed when the data array changes. */
  private void onDataChanged() {
    int angle = 360 / mData.size();
    // This is the extra degrees that cannot be equally divided by the number of sides
    int extra = 360 % mData.size();

    // When the data changes, we have to recalculate
    // all of the angles.
    int currentAngle = 0;
    for (Item it : mData) {

      // Adds the extra degrees to the last slice to ensue no gaps
      if (mData.get(mData.size() - 1).mLabel.equals(it.mLabel)) {
        it.mEndAngle = currentAngle + angle + extra;
      } else {

        it.mEndAngle = currentAngle + angle;
      }
      it.mStartAngle = currentAngle;
      currentAngle = it.mEndAngle;

      // Recalculate the gradient shaders. There are
      // three values in this gradient, even though only
      // two are necessary, in order to work around
      // a bug in certain versions of the graphics engine
      // that expects at least three values if the
      // positions array is non-null.
      //
      it.mItemShader =
          new SweepGradient(
              mPieBounds.width() / 2.0f,
              mPieBounds.height() / 2.0f,
              new int[] {
                it.mItemHighlight, it.mItemHighlight, it.mItemColor, it.mItemColor,
              },
              new float[] {
                0,
                (float) (360 - it.mEndAngle) / 360.0f,
                (float) (360 - it.mStartAngle) / 360.0f,
                1.0f
              });

      it.cSliceShader =
          new SweepGradient(
              mPieBounds.width() / 2.0f,
              mPieBounds.height() / 2.0f,
              new int[] {
                it.cSliceHighlight, it.cSliceHighlight, it.cSliceColor, it.cSliceColor,
              },
              new float[] {
                0,
                (float) (360 - it.mEndAngle) / 360.0f,
                (float) (360 - it.mStartAngle) / 360.0f,
                1.0f
              });
    }
    calcCurrentItem();
    onScrollFinished();
  }
  /** Resets the dirty region when the motion event occurs. */
  private void resetDirtyRect(float eventX, float eventY) {

    // The lastTouchX and lastTouchY were set when the ACTION_DOWN
    // motion event occurred.
    dirtyRect.left = Math.min(lastTouchX, eventX);
    dirtyRect.right = Math.max(lastTouchX, eventX);
    dirtyRect.top = Math.min(lastTouchY, eventY);
    dirtyRect.bottom = Math.max(lastTouchY, eventY);
  }
 private RectF getRectF() {
   if (backgroundRectF == null) {
     backgroundRectF = new RectF();
     backgroundRectF.left = mPadding;
     backgroundRectF.top = mPadding;
     backgroundRectF.right = getWidth() - mPadding;
     backgroundRectF.bottom = getHeight() - mPadding;
   }
   return backgroundRectF;
 }
 /** Called when replaying history to ensure the dirty region includes all points. */
 private void expandDirtyRect(float historicalX, float historicalY) {
   if (historicalX < dirtyRect.left) {
     dirtyRect.left = historicalX;
   } else if (historicalX > dirtyRect.right) {
     dirtyRect.right = historicalX;
   }
   if (historicalY < dirtyRect.top) {
     dirtyRect.top = historicalY;
   } else if (historicalY > dirtyRect.bottom) {
     dirtyRect.bottom = historicalY;
   }
 }
Example #13
0
  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);
    }
  }
 private void doLimits(float x, float y) {
   if (x < limits.left) {
     limits.left = x;
   }
   if (x > limits.right) {
     limits.right = x;
   }
   if (y < limits.top) {
     limits.top = y;
   }
   if (y > limits.bottom) {
     limits.bottom = y;
   }
 }
Example #15
0
  public SVGTileProvider(File file, float dpi) throws IOException {
    mScale = Math.round(dpi + .3f); // Make it look nice on N7 (1.3 dpi)
    mDimension = BASE_TILE_SIZE * mScale;

    mPool = new TileGeneratorPool(POOL_MAX_SIZE);

    SVG svg = new SVGBuilder().readFromInputStream(new FileInputStream(file)).build();
    mSvgPicture = svg.getPicture();
    RectF limits = svg.getLimits();

    mBaseMatrix = new Matrix();
    mBaseMatrix.setPolyToPoly(
        new float[] {0, 0, limits.width(), 0, limits.width(), limits.height()},
        0,
        new float[] {
          40.95635986328125f, 98.94217824936158f,
          40.95730018615723f, 98.94123077396628f,
          40.95791244506836f, 98.94186019897214f
        },
        0,
        3);
  }
Example #16
0
  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);

    float xpad = (float) (getPaddingLeft() + getPaddingRight());
    float ypad = (float) (getPaddingTop() + getPaddingBottom());

    float ww = (float) w - xpad - axisYSpacing;
    float hh = (float) h - ypad - axisXSpacing;

    // Figure out how big we can make the pie.
    mPlotBounds = new RectF(0f, 0f, ww, hh);
    mPlotBounds.offsetTo(getPaddingLeft() + axisYSpacing, getPaddingTop());

    onDataChanged();
  }
Example #17
0
 private int calcX(float x) {
   RectF r = mPlotBounds;
   return Math.round(r.left + r.width() * (x - getXMin()) / (getXMax() - getXMin()));
 }
Example #18
0
  @Override
  public void onDraw(Canvas canvas) {
    int margeLeft, margeRight, margeTop, margeBot, line, calcLine, part;
    if (canvas.getWidth() > canvas.getHeight()) {
      ref = (int) (canvas.getHeight() * 0.85);
      margin = (int) (canvas.getHeight() * 0.15);
    } else {
      ref = (int) (canvas.getWidth() * 0.85);
      margin = (int) (canvas.getWidth() * 0.15);
    }
    part = ref / NB_SQUARE_PAR_LINE;
    line = -1;
    int size = (int) Math.pow(NB_SQUARE_PAR_LINE, 2);
    for (int i = 0; i < size; i++) {
      ISquare square = chessboard.get(i);
      calcLine = (i - i % NB_SQUARE_PAR_LINE) / NB_SQUARE_PAR_LINE;
      margeTop = calcLine * part + margin / 2;
      if (calcLine != line) {
        line = calcLine;
        margeLeft = margin / 2;
      } else {
        margeLeft = margin / 2 + part * (i % NB_SQUARE_PAR_LINE);
      }
      margeBot = margeTop + part;
      margeRight = margeLeft + part;

      if ((line + i) % 2 == 1) {
        paintSquare.setColor(Color.parseColor("#a7823d"));
      } else {
        paintSquare.setColor(Color.parseColor("#e6e6ff"));
      }
      Rect rect = new Rect(margeLeft, margeTop, margeRight, margeBot);

      canvas.drawRect(rect, paintSquare);

      int status = square.getStatus();
      if (status != ISquare.STATUS_DEFAULT) {
        int border_margin = (int) (part * 0.08);
        int inner_margin;
        switch (status) {
          case (ISquare.STATUS_SELECTED):
            paintStatus.setColor(Color.parseColor("#0034E1")); // "#FFA200"));
            paintStatus.setStyle(Paint.Style.STROKE);
            paintStatus.setStrokeWidth(border_margin);
            inner_margin = border_margin / 2;
            rectF.set(
                margeLeft + inner_margin,
                margeTop + inner_margin,
                margeRight - inner_margin,
                margeBot - inner_margin);
            canvas.drawRect(rectF, paintStatus);
            break;
          case (ISquare.STATUS_TARGETABLE):
            paintStatus.setColor(Color.parseColor("#D23939"));
            paintStatus.setStyle(Paint.Style.FILL);
            paintStatus.setStrokeWidth(0);
            inner_margin = (int) (border_margin / 1.5);
            rectF.set(
                margeLeft + inner_margin,
                margeTop + inner_margin,
                margeRight - inner_margin,
                margeBot - inner_margin);
            canvas.drawRect(rectF, paintStatus);
            break;
          case (ISquare.STATUS_MOVE):
            paintStatus.setColor(Color.parseColor("#3899D1"));
            paintStatus.setStyle(Paint.Style.FILL);
            paintStatus.setStrokeWidth(0);
            inner_margin = (int) (border_margin / 1.5);
            rectF.set(
                margeLeft + inner_margin,
                margeTop + inner_margin,
                margeRight - inner_margin,
                margeBot - inner_margin);
            canvas.drawRect(rectF, paintStatus);
            break;
        }
      }

      if (!square.isEmpty()) {
        IPiece piece = square.getPiece();

        int marginDrawable = (int) (part * 0.2);

        RelativeLayout myLayout = (RelativeLayout) this.getParent();

        int width = (margeRight - marginDrawable) - (margeLeft + marginDrawable);
        int height = (margeBot - marginDrawable) - (margeTop + marginDrawable);
        int left = margeLeft + marginDrawable;
        int top = margeTop + marginDrawable;

        piece.setImage(getContext(), myLayout, width, height, left, top);
      }
    }
  }
Example #19
0
  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    Log.d(TAG, "Slice Count: " + mData.size());
    if (mData.size() > 0) {
      //
      // Set dimensions for text, pie chart, etc
      //
      // Account for padding
      float xpad = (float) (getPaddingLeft() + getPaddingRight());
      float ypad = (float) (getPaddingTop() + getPaddingBottom());

      // Account for the label
      if (mShowText) xpad += mTextWidth;

      float ww = (float) w - xpad;
      float hh = (float) h - ypad;

      // Figure out how big we can make the pie.
      float diameter = Math.min(ww, hh);
      mPieBounds = new RectF(0.0f, 0.0f, diameter, diameter);
      mPieBounds.offsetTo(getPaddingLeft(), getPaddingTop());
      //	        Log.d(TAG, "mPieBounds>> "+mPieBounds);

      mPointerY = mTextY - (mTextHeight / 2.0f);
      float pointerOffset = mPieBounds.centerY() - mPointerY;

      // Make adjustments based on text position
      if (mTextPos == TEXTPOS_LEFT) {
        mTextPaint.setTextAlign(Paint.Align.RIGHT);
        if (mShowText) mPieBounds.offset(mTextWidth, 0.0f);
        mTextX = mPieBounds.left;

        if (pointerOffset < 0) {
          pointerOffset = -pointerOffset;
          mCurrentItemAngle = 225;
        } else {
          mCurrentItemAngle = 135;
        }
        mPointerX = mPieBounds.centerX() - pointerOffset;
      } else {
        mTextPaint.setTextAlign(Paint.Align.LEFT);
        mTextX = mPieBounds.right;

        if (pointerOffset < 0) {
          pointerOffset = -pointerOffset;
          mCurrentItemAngle = 315;
        } else {
          mCurrentItemAngle = 45;
        }
        mPointerX = mPieBounds.centerX() + pointerOffset;
      }

      mShadowBounds =
          new RectF(
              mPieBounds.left + 10,
              mPieBounds.bottom + 10,
              mPieBounds.right - 10,
              mPieBounds.bottom + 20);

      // Lay out the child view that actually draws the pie.
      mPieView.layout(
          (int) mPieBounds.left,
          (int) mPieBounds.top,
          (int) mPieBounds.right,
          (int) mPieBounds.bottom);
      mPieView.setPivot(mPieBounds.width() / 2, mPieBounds.height() / 2);

      mPointerView.layout(0, 0, w, h);
      onDataChanged();
    }
  }
 @Override
 public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
     throws SAXException {
   // Reset paint opacity
   paint.setAlpha(255);
   // Ignore everything but rectangles in bounds mode
   if (boundsMode) {
     if (localName.equals("rect")) {
       Float x = getFloatAttr("x", atts);
       if (x == null) {
         x = 0f;
       }
       Float y = getFloatAttr("y", atts);
       if (y == null) {
         y = 0f;
       }
       Float width = getFloatAttr("width", atts);
       Float height = getFloatAttr("height", atts);
       bounds = new RectF(x, y, x + width, y + height);
     }
     return;
   }
   if (localName.equals("svg")) {
     int width = (int) Math.ceil(getFloatAttr("width", atts));
     int height = (int) Math.ceil(getFloatAttr("height", atts));
     canvas = picture.beginRecording(width, height);
   } else if (localName.equals("defs")) {
     // Ignore
   } else if (localName.equals("linearGradient")) {
     gradient = doGradient(true, atts);
   } else if (localName.equals("radialGradient")) {
     gradient = doGradient(false, atts);
   } else if (localName.equals("stop")) {
     if (gradient != null) {
       float offset = getFloatAttr("offset", atts);
       String styles = getStringAttr("style", atts);
       StyleSet styleSet = new StyleSet(styles);
       String colorStyle = styleSet.getStyle("stop-color");
       int color = Color.BLACK;
       if (colorStyle != null) {
         if (colorStyle.startsWith("#")) {
           color = Integer.parseInt(colorStyle.substring(1), 16);
         } else {
           color = Integer.parseInt(colorStyle, 16);
         }
       }
       String opacityStyle = styleSet.getStyle("stop-opacity");
       if (opacityStyle != null) {
         float alpha = Float.parseFloat(opacityStyle);
         int alphaInt = Math.round(255 * alpha);
         color |= (alphaInt << 24);
       } else {
         color |= 0xFF000000;
       }
       gradient.positions.add(offset);
       gradient.colors.add(color);
     }
   } else if (localName.equals("g")) {
     // Check to see if this is the "bounds" layer
     if ("bounds".equalsIgnoreCase(getStringAttr("id", atts))) {
       boundsMode = true;
     }
     if (hidden) {
       hiddenLevel++;
       // Util.debug("Hidden up: " + hiddenLevel);
     }
     // Go in to hidden mode if display is "none"
     if ("none".equals(getStringAttr("display", atts))) {
       if (!hidden) {
         hidden = true;
         hiddenLevel = 1;
         // Util.debug("Hidden up: " + hiddenLevel);
       }
     }
     pushTransform(atts);
   } else if (!hidden && localName.equals("rect")) {
     Float x = getFloatAttr("x", atts);
     if (x == null) {
       x = 0f;
     }
     Float y = getFloatAttr("y", atts);
     if (y == null) {
       y = 0f;
     }
     Float width = getFloatAttr("width", atts);
     Float height = getFloatAttr("height", atts);
     Float rx = getFloatAttr("rx", atts);
     Float ry = getFloatAttr("ry", atts);
     if (rx == null) {
       if (ry == null) rx = ry = 0f;
       else rx = ry;
     } else {
       if (ry == null) ry = rx;
     }
     if (rx > width / 2) rx = width * 0.5f;
     if (ry > height / 2) ry = height * 0.5f;
     pushTransform(atts);
     Properties props = new Properties(atts);
     if (doFill(props, gradientMap)) {
       doLimits(x, y, width, height);
       if (rx > 0 && ry > 0)
         canvas.drawRoundRect(new RectF(x, y, x + width, y + height), rx, ry, paint);
       else canvas.drawRect(x, y, x + width, y + height, paint);
     }
     if (doStroke(props, gradientMap)) {
       if (rx > 0 && ry > 0)
         canvas.drawRoundRect(new RectF(x, y, x + width, y + height), rx, ry, paint);
       else canvas.drawRect(x, y, x + width, y + height, paint);
     }
     popTransform();
   } else if (!hidden && localName.equals("line")) {
     Float x1 = getFloatAttr("x1", atts);
     Float x2 = getFloatAttr("x2", atts);
     Float y1 = getFloatAttr("y1", atts);
     Float y2 = getFloatAttr("y2", atts);
     Properties props = new Properties(atts);
     if (doStroke(props, gradientMap)) {
       pushTransform(atts);
       doLimits(x1, y1);
       doLimits(x2, y2);
       canvas.drawLine(x1, y1, x2, y2, paint);
       popTransform();
     }
   } else if (!hidden && localName.equals("circle")) {
     Float centerX = getFloatAttr("cx", atts);
     Float centerY = getFloatAttr("cy", atts);
     Float radius = getFloatAttr("r", atts);
     if (centerX != null && centerY != null && radius != null) {
       pushTransform(atts);
       Properties props = new Properties(atts);
       if (doFill(props, gradientMap)) {
         doLimits(centerX - radius, centerY - radius);
         doLimits(centerX + radius, centerY + radius);
         canvas.drawCircle(centerX, centerY, radius, paint);
       }
       if (doStroke(props, gradientMap)) {
         canvas.drawCircle(centerX, centerY, radius, paint);
       }
       popTransform();
     }
   } else if (!hidden && localName.equals("ellipse")) {
     Float centerX = getFloatAttr("cx", atts);
     Float centerY = getFloatAttr("cy", atts);
     Float radiusX = getFloatAttr("rx", atts);
     Float radiusY = getFloatAttr("ry", atts);
     if (centerX != null && centerY != null && radiusX != null && radiusY != null) {
       pushTransform(atts);
       Properties props = new Properties(atts);
       rect.set(centerX - radiusX, centerY - radiusY, centerX + radiusX, centerY + radiusY);
       if (doFill(props, gradientMap)) {
         doLimits(centerX - radiusX, centerY - radiusY);
         doLimits(centerX + radiusX, centerY + radiusY);
         canvas.drawOval(rect, paint);
       }
       if (doStroke(props, gradientMap)) {
         canvas.drawOval(rect, paint);
       }
       popTransform();
     }
   } else if (!hidden && (localName.equals("polygon") || localName.equals("polyline"))) {
     NumberParse numbers = getNumberParseAttr("points", atts);
     if (numbers != null) {
       Path p = new Path();
       ArrayList<Float> points = numbers.numbers;
       if (points.size() > 1) {
         pushTransform(atts);
         Properties props = new Properties(atts);
         p.moveTo(points.get(0), points.get(1));
         for (int i = 2; i < points.size(); i += 2) {
           float x = points.get(i);
           float y = points.get(i + 1);
           p.lineTo(x, y);
         }
         // Don't close a polyline
         if (localName.equals("polygon")) {
           p.close();
         }
         if (doFill(props, gradientMap)) {
           doLimits(p);
           canvas.drawPath(p, paint);
         }
         if (doStroke(props, gradientMap)) {
           canvas.drawPath(p, paint);
         }
         popTransform();
       }
     }
   } else if (!hidden && localName.equals("path")) {
     Path p = doPath(getStringAttr("d", atts));
     pushTransform(atts);
     Properties props = new Properties(atts);
     if (doFill(props, gradientMap)) {
       doLimits(p);
       canvas.drawPath(p, paint);
     }
     if (doStroke(props, gradientMap)) {
       canvas.drawPath(p, paint);
     }
     popTransform();
   } else if (!hidden) {
     //                Log.d(TAG, "UNRECOGNIZED SVG COMMAND: " + localName);
   }
 }
Example #21
0
 public static PointF getAnchorCoordinates(RectF widgetRect, Anchor anchor) {
   return PixelUtils.add(
       new PointF(widgetRect.left, widgetRect.top),
       getAnchorOffset(widgetRect.width(), widgetRect.height(), anchor));
 }
  @Override
  protected void onDraw(Canvas canvas) {
    float ringWidth = textHeight + 4;
    int height = getMeasuredHeight();
    int width = getMeasuredWidth();

    int px = width / 2;
    int py = height / 2;
    Point center = new Point(px, py);

    int radius = Math.min(px, py) - 2;

    RectF boundingBox =
        new RectF(center.x - radius, center.y - radius, center.x + radius, center.y + radius);

    RectF innerBoundingBox =
        new RectF(
            center.x - radius + ringWidth,
            center.y - radius + ringWidth,
            center.x + radius - ringWidth,
            center.y + radius - ringWidth);

    float innerRadius = innerBoundingBox.height() / 2;
    RadialGradient borderGradient =
        new RadialGradient(
            px, py, radius, borderGradientColors, borderGradientPositions, TileMode.CLAMP);

    Paint pgb = new Paint();
    pgb.setShader(borderGradient);

    Path outerRingPath = new Path();
    outerRingPath.addOval(boundingBox, Direction.CW);

    canvas.drawPath(outerRingPath, pgb);
    LinearGradient skyShader =
        new LinearGradient(
            center.x,
            innerBoundingBox.top,
            center.x,
            innerBoundingBox.bottom,
            skyHorizonColorFrom,
            skyHorizonColorTo,
            TileMode.CLAMP);

    Paint skyPaint = new Paint();
    skyPaint.setShader(skyShader);

    LinearGradient groundShader =
        new LinearGradient(
            center.x,
            innerBoundingBox.top,
            center.x,
            innerBoundingBox.bottom,
            groundHorizonColorFrom,
            groundHorizonColorTo,
            TileMode.CLAMP);

    Paint groundPaint = new Paint();
    groundPaint.setShader(groundShader);
    float tiltDegree = pitch;
    while (tiltDegree > 90 || tiltDegree < -90) {
      if (tiltDegree > 90) tiltDegree = -90 + (tiltDegree - 90);
      if (tiltDegree < -90) tiltDegree = 90 - (tiltDegree + 90);
    }

    float rollDegree = roll;
    while (rollDegree > 180 || rollDegree < -180) {
      if (rollDegree > 180) rollDegree = -180 + (rollDegree - 180);
      if (rollDegree < -180) rollDegree = 180 - (rollDegree + 180);
    }
    Path skyPath = new Path();
    skyPath.addArc(innerBoundingBox, -rollDegree, (180 + (2 * rollDegree)));
    canvas.rotate(-tiltDegree, px, py);
    canvas.drawOval(innerBoundingBox, groundPaint);
    canvas.drawPath(skyPath, skyPaint);
    canvas.drawPath(skyPath, markerPaint);
    int markWidth = radius / 3;
    int startX = center.x - markWidth;
    int endX = center.x + markWidth;

    Log.d("PAARV ", "Roll " + String.valueOf(rollDegree));
    Log.d("PAARV ", "Pitch " + String.valueOf(tiltDegree));

    double h = innerRadius * Math.cos(Math.toRadians(90 - tiltDegree));
    double justTiltX = center.x - h;

    float pxPerDegree = (innerBoundingBox.height() / 2) / 45f;
    for (int i = 90; i >= -90; i -= 10) {
      double ypos = justTiltX + i * pxPerDegree;

      if ((ypos < (innerBoundingBox.top + textHeight))
          || (ypos > innerBoundingBox.bottom - textHeight)) continue;

      canvas.drawLine(startX, (float) ypos, endX, (float) ypos, markerPaint);
      int displayPos = (int) (tiltDegree - i);
      String displayString = String.valueOf(displayPos);
      float stringSizeWidth = textPaint.measureText(displayString);
      canvas.drawText(
          displayString, (int) (center.x - stringSizeWidth / 2), (int) (ypos) + 1, textPaint);
    }
    markerPaint.setStrokeWidth(2);
    canvas.drawLine(
        center.x - radius / 2,
        (float) justTiltX,
        center.x + radius / 2,
        (float) justTiltX,
        markerPaint);
    markerPaint.setStrokeWidth(1);

    Path rollArrow = new Path();
    rollArrow.moveTo(center.x - 3, (int) innerBoundingBox.top + 14);
    rollArrow.lineTo(center.x, (int) innerBoundingBox.top + 10);
    rollArrow.moveTo(center.x + 3, innerBoundingBox.top + 14);
    rollArrow.lineTo(center.x, innerBoundingBox.top + 10);
    canvas.drawPath(rollArrow, markerPaint);
    String rollText = String.valueOf(rollDegree);
    double rollTextWidth = textPaint.measureText(rollText);
    canvas.drawText(
        rollText,
        (float) (center.x - rollTextWidth / 2),
        innerBoundingBox.top + textHeight + 2,
        textPaint);
    canvas.restore();

    canvas.save();
    canvas.rotate(180, center.x, center.y);
    for (int i = -180; i < 180; i += 10) {
      if (i % 30 == 0) {
        String rollString = String.valueOf(i * -1);
        float rollStringWidth = textPaint.measureText(rollString);
        PointF rollStringCenter =
            new PointF(center.x - rollStringWidth / 2, innerBoundingBox.top + 1 + textHeight);
        canvas.drawText(rollString, rollStringCenter.x, rollStringCenter.y, textPaint);
      } else {
        canvas.drawLine(
            center.x,
            (int) innerBoundingBox.top,
            center.x,
            (int) innerBoundingBox.top + 5,
            markerPaint);
      }

      canvas.rotate(10, center.x, center.y);
    }
    canvas.restore();
    canvas.save();
    canvas.rotate(-1 * (bearing), px, py);

    double increment = 22.5;

    for (double i = 0; i < 360; i += increment) {
      CompassDirection cd = CompassDirection.values()[(int) (i / 22.5)];
      String headString = cd.toString();

      float headStringWidth = textPaint.measureText(headString);
      PointF headStringCenter =
          new PointF(center.x - headStringWidth / 2, boundingBox.top + 1 + textHeight);

      if (i % increment == 0)
        canvas.drawText(headString, headStringCenter.x, headStringCenter.y, textPaint);
      else
        canvas.drawLine(
            center.x, (int) boundingBox.top, center.x, (int) boundingBox.top + 3, markerPaint);

      canvas.rotate((int) increment, center.x, center.y);
    }
    canvas.restore();
    RadialGradient glassShader =
        new RadialGradient(
            px, py, (int) innerRadius, glassGradientColors, glassGradientPositions, TileMode.CLAMP);
    Paint glassPaint = new Paint();
    glassPaint.setShader(glassShader);

    canvas.drawOval(innerBoundingBox, glassPaint);
    canvas.drawOval(boundingBox, circlePaint);

    circlePaint.setStrokeWidth(2);
    canvas.drawOval(innerBoundingBox, circlePaint);

    canvas.restore();
  }
  // 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();
  }
Example #24
0
 private int calcY(float y) {
   RectF r = mPlotBounds;
   return Math.round(r.top + r.height() * (1 - (y - getYMin()) / (getYMax() - getYMin())));
 }
Example #25
0
    public void build(DialogWireframe description, int w, int h, TelegramApplication application) {
      layoutH = h;
      layoutW = w;

      if (description.getPeerType() == PeerType.PEER_USER) {
        if (description.getPeerId() == 333000) {
          isHighlighted = false;
        } else {
          User user = description.getDialogUser();
          isHighlighted = user.getLinkType() == LinkType.FOREIGN;
        }
        isGroup = false;
        isEncrypted = false;
      } else if (description.getPeerType() == PeerType.PEER_CHAT) {
        isHighlighted = false;
        isGroup = true;
        isEncrypted = false;
      } else if (description.getPeerType() == PeerType.PEER_USER_ENCRYPTED) {
        isHighlighted = false;
        isGroup = false;
        isEncrypted = true;
      }

      isBodyHighlighted = description.getContentType() != ContentType.MESSAGE_TEXT;

      if (description.getUnreadCount() != 0 && !description.isMine()) {
        isUnreadIn = true;
      } else {
        isUnreadIn = false;
      }

      time = org.telegram.android.ui.TextUtil.formatDate(description.getDate(), application);
      isRtl = application.isRTL();

      if (IS_LARGE) {
        layoutAvatarWidth = px(64);
        layoutPadding = application.getResources().getDimensionPixelSize(R.dimen.dialogs_padding);
        layoutBodyPadding = layoutAvatarWidth + layoutPadding + px(12);
        layoutAvatarTop = px(8);
        layoutTitleTop = px(34);
        layoutMainTop = px(60);
        layoutTimeTop = px(34);

        layoutMarkTop = px(44);
        layoutMarkBottom = layoutMarkTop + px(22);
        layoutMarkTextTop = layoutMarkTop + px(18);
      } else {
        layoutAvatarWidth = px(54);
        layoutPadding = application.getResources().getDimensionPixelSize(R.dimen.dialogs_padding);
        layoutBodyPadding = layoutAvatarWidth + layoutPadding + px(12);
        layoutAvatarTop = px(8);
        layoutTitleTop = px(30);
        layoutMainTop = px(54);
        layoutTimeTop = px(30);

        layoutMarkTop = px(38);
        layoutMarkBottom = layoutMarkTop + px(22);
        layoutMarkTextTop = layoutMarkTop + px(18);
      }

      layoutMainContentTop = (int) (layoutMainTop + bodyPaint.getFontMetrics().ascent);
      layoutTitleLayoutTop = (int) (layoutTitleTop + titlePaint.getFontMetrics().ascent);
      layoutStateTop = layoutTimeTop - px(10);
      layoutClockTop = layoutTimeTop - px(12);
      layoutEncryptedTop = layoutTimeTop - px(14);

      if (isRtl) {
        layoutAvatarLeft = w - layoutPadding - layoutAvatarWidth;
      } else {
        layoutAvatarLeft = layoutPadding;
      }

      int timeWidth = (int) unreadClockPaint.measureText(time);
      if (isRtl) {
        layoutTimeLeft = layoutPadding;
        layoutStateLeftDouble = layoutPadding + timeWidth + px(2);
        layoutStateLeft = layoutStateLeftDouble + px(6);
        layoutClockLeft = layoutPadding + timeWidth + px(2);
      } else {
        layoutTimeLeft = w - layoutPadding - timeWidth;
        layoutClockLeft = w - layoutPadding - timeWidth - px(14);
        layoutStateLeft = w - layoutPadding - timeWidth - px(16);
        layoutStateLeftDouble = w - layoutPadding - timeWidth - px(6 + 16);
      }

      layoutMarkRadius = px(2);
      if (description.isErrorState()
          || (description.getMessageState() == MessageState.FAILURE && description.isMine())) {
        layoutMarkWidth = px(22);
        if (isRtl) {
          layoutMarkLeft = layoutPadding; // getMeasuredWidth() - layoutMarkWidth - getPx(80);
        } else {
          layoutMarkLeft = w - layoutMarkWidth - layoutPadding;
        }
      } else {
        if (description.getUnreadCount() > 0) {
          if (description.getUnreadCount() >= 1000) {
            unreadCountText =
                I18nUtil.getInstance().correctFormatNumber(description.getUnreadCount() / 1000)
                    + "K";
          } else {
            unreadCountText =
                I18nUtil.getInstance().correctFormatNumber(description.getUnreadCount());
          }
          int width = (int) counterTitlePaint.measureText(unreadCountText);
          Rect r = new Rect();
          counterTitlePaint.getTextBounds(unreadCountText, 0, unreadCountText.length(), r);
          layoutMarkTextTop =
              layoutMarkTop + (layoutMarkBottom - layoutMarkTop + r.top) / 2 - r.top;
          if (width < px(22 - 14)) {
            layoutMarkWidth = px(22);
          } else {
            layoutMarkWidth = px(14) + width;
          }
          layoutMarkTextLeft = (layoutMarkWidth - width) / 2;

          if (isRtl) {
            layoutMarkLeft = layoutPadding; // getMeasuredWidth() - layoutMarkWidth - getPx(80);
          } else {
            layoutMarkLeft = w - layoutMarkWidth - layoutPadding;
          }
        } else {
          layoutMarkLeft = 0;
          layoutMarkWidth = 0;
        }
      }
      layoutMarkRect.set(
          layoutMarkLeft, layoutMarkTop, layoutMarkLeft + layoutMarkWidth, layoutMarkBottom);

      if (description.getPeerType() == PeerType.PEER_USER_ENCRYPTED) {
        if (isRtl) {
          if (description.isMine()) {
            layoutTitleLeft = timeWidth + px(16) + px(16);
          } else {
            layoutTitleLeft = timeWidth + px(12);
          }
          layoutTitleWidth = w - layoutTitleLeft - layoutBodyPadding - px(14) - px(6);
          layoutEncryptedLeft = w - layoutBodyPadding - px(12);
        } else {
          layoutTitleLeft = layoutBodyPadding + px(16);
          if (description.isMine()) {
            layoutTitleWidth = w - layoutTitleLeft - timeWidth - px(24);
          } else {
            layoutTitleWidth = w - layoutTitleLeft - timeWidth - px(12);
          }

          layoutEncryptedLeft = layoutBodyPadding + px(2);
        }
      } else {
        if (isRtl) {
          if (description.isMine()) {
            layoutTitleLeft = timeWidth + px(16) + px(16);
          } else {
            layoutTitleLeft = timeWidth + px(12);
          }
          layoutTitleWidth = w - layoutTitleLeft - layoutBodyPadding;
        } else {
          layoutTitleLeft = layoutBodyPadding;
          if (description.isMine()) {
            layoutTitleWidth = w - layoutTitleLeft - timeWidth - px(24) - px(12);
          } else {
            layoutTitleWidth = w - layoutTitleLeft - timeWidth - px(12);
          }
        }
      }

      layoutMainWidth = w - layoutBodyPadding - layoutPadding;
      if (isRtl) {
        layoutMainLeft = w - layoutMainWidth - layoutBodyPadding;
        if (layoutMarkWidth != 0) {
          layoutMainLeft += layoutMarkWidth + px(8);
          layoutMainWidth -= layoutMarkWidth + px(8);
        }
      } else {
        layoutMainLeft = layoutBodyPadding;
        if (layoutMarkWidth != 0) {
          layoutMainWidth -= layoutMarkWidth + px(8);
        }
      }

      avatarRect.set(
          layoutAvatarLeft,
          layoutAvatarTop,
          layoutAvatarLeft + layoutAvatarWidth,
          layoutAvatarTop + layoutAvatarWidth);

      // Building text layouts
      {
        String message = description.getMessage();
        if (message.length() > 150) {
          message = message.substring(0, 150) + "...";
        }
        message = message.replace("\n", " ");

        TextPaint bodyTextPaint;
        if (isBodyHighlighted) {
          bodyTextPaint = bodyHighlightPaint;
        } else {
          if (HIGHLIGHT_UNDEAD) {
            if (isUnreadIn) {
              bodyTextPaint = bodyUnreadPaint;
            } else {
              bodyTextPaint = bodyPaint;
            }
          } else {
            bodyTextPaint = bodyPaint;
          }
        }

        int nameLength = 0;

        if (description.getContentType() != ContentType.MESSAGE_SYSTEM) {
          if (description.isMine()) {
            String name = application.getResources().getString(R.string.st_dialog_you);
            nameLength = BidiFormatter.getInstance().unicodeWrap(name).length();
            message =
                BidiFormatter.getInstance().unicodeWrap(name)
                    + ": "
                    + BidiFormatter.getInstance().unicodeWrap(message);
          } else {
            if (isGroup) {
              User user = description.getSender();
              nameLength = BidiFormatter.getInstance().unicodeWrap(user.getFirstName()).length();
              message =
                  BidiFormatter.getInstance().unicodeWrap(user.getFirstName().replace("\n", " "))
                      + ": "
                      + BidiFormatter.getInstance().unicodeWrap(message);
            }
          }
        }

        String preSequence =
            TextUtils.ellipsize(message, bodyTextPaint, layoutMainWidth, TextUtils.TruncateAt.END)
                .toString();

        //                Spannable sequence =
        // application.getEmojiProcessor().processEmojiCutMutable(preSequence,
        // EmojiProcessor.CONFIGURATION_DIALOGS);
        //                if (nameLength != 0) {
        //                    sequence.setSpan(new ForegroundColorSpan(HIGHLIGHT_COLOR), 0,
        // Math.min(nameLength, sequence.length()), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        //                }
        //                CharSequence resSequence = TextUtils.ellipsize(sequence, bodyTextPaint,
        // layoutMainWidth, TextUtils.TruncateAt.END);
        //                bodyLayout = new StaticLayout(resSequence, bodyTextPaint, layoutMainWidth,
        // Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
        //                bodyString = null;

        Spannable sequence =
            application
                .getEmojiProcessor()
                .processEmojiCutMutable(preSequence, EmojiProcessor.CONFIGURATION_DIALOGS);
        if (nameLength != 0) {
          sequence.setSpan(
              new ForegroundColorSpan(HIGHLIGHT_COLOR),
              0,
              Math.min(nameLength, sequence.length()),
              Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        }

        CharSequence resSequence =
            TextUtils.ellipsize(sequence, bodyTextPaint, layoutMainWidth, TextUtils.TruncateAt.END);
        bodyLayout =
            new StaticLayout(
                resSequence,
                bodyTextPaint,
                layoutMainWidth,
                Layout.Alignment.ALIGN_NORMAL,
                1.0f,
                0.0f,
                false);
        bodyString = null;
        //                if (EmojiProcessor.containsEmoji(message)) {
        //                    Spannable sequence =
        // application.getEmojiProcessor().processEmojiCutMutable(preSequence,
        // EmojiProcessor.CONFIGURATION_DIALOGS);
        //                    if (nameLength != 0) {
        //                        sequence.setSpan(new ForegroundColorSpan(HIGHLIGHT_COLOR), 0,
        // Math.min(nameLength, sequence.length()), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        //                    }
        //
        //                    CharSequence resSequence = TextUtils.ellipsize(sequence,
        // bodyTextPaint, layoutMainWidth, TextUtils.TruncateAt.END);
        //                    bodyLayout = new StaticLayout(resSequence, bodyTextPaint,
        // layoutMainWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
        //                    bodyString = null;
        //                } else {
        //                    bodyString = preSequence;
        //                    bodyLayout = null;
        //                }
      }

      // Title
      {
        String title = description.getDialogTitle();
        if (title.length() > 150) {
          title = title.substring(150) + "...";
        }
        title = title.replace("\n", " ");

        TextPaint paint =
            isEncrypted ? titleEncryptedPaint : (isHighlighted ? titleHighlightPaint : titlePaint);

        //                Spannable preSequence =
        // application.getEmojiProcessor().processEmojiCutMutable(title,
        // EmojiProcessor.CONFIGURATION_DIALOGS);
        //                CharSequence sequence = TextUtils.ellipsize(preSequence, paint,
        // layoutTitleWidth, TextUtils.TruncateAt.END);
        //                titleLayout = new StaticLayout(sequence, paint, layoutTitleWidth,
        // Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
        //                titleString = null;

        if (EmojiProcessor.containsEmoji(title)) {
          Spannable preSequence =
              application
                  .getEmojiProcessor()
                  .processEmojiCutMutable(title, EmojiProcessor.CONFIGURATION_DIALOGS);
          CharSequence sequence =
              TextUtils.ellipsize(preSequence, paint, layoutTitleWidth, TextUtils.TruncateAt.END);
          titleLayout =
              new StaticLayout(
                  sequence,
                  paint,
                  layoutTitleWidth,
                  Layout.Alignment.ALIGN_NORMAL,
                  1.0f,
                  0.0f,
                  false);
          titleString = null;
        } else {
          titleString =
              TextUtils.ellipsize(title, paint, layoutTitleWidth, TextUtils.TruncateAt.END)
                  .toString();
          titleLayout = null;
        }
      }

      // Placeholder
      placeHolderName = description.getDialogName();
      placeHolderColor = Placeholders.getBgColor(description.getPeerId());

      if (placeHolderName.length() > 0) {
        usePlaceholder = true;
        placeholderLeft = layoutAvatarLeft + layoutAvatarWidth / 2;
        Rect rect = new Rect();
        placeholderTextPaint.getTextBounds(placeHolderName, 0, placeHolderName.length(), rect);
        placeholderTop = layoutAvatarTop + (layoutAvatarWidth / 2 + ((rect.bottom - rect.top) / 2));
      } else {
        usePlaceholder = false;
      }
    }