コード例 #1
0
ファイル: FontFitTextView.java プロジェクト: aril1111/Osmand
  private void refitText(String text, int textWidth, int textHeight, boolean layout) {
    if (textWidth > 0) {
      //			Drawable left = getCompoundDrawables()[0];
      //			Drawable right = getCompoundDrawables()[2];
      //			float availableWidth = textWidth - this.getPaddingLeft()
      //					- this.getPaddingRight() - this.getCompoundDrawablePadding()
      //					- (left != null ? left.getMinimumWidth() : 0)
      //					- (right != null ? right.getMinimumWidth() : 0);

      float availableWidth = textWidth;
      TextPaint tp = getPaint();
      tp.setTextSize(MAX_TEXT_SIZE);
      int lines = text.length() / 25 + 1;

      Rect rect = new Rect();
      tp.getTextBounds(text, 0, text.length(), rect);
      while (rect.width() > (availableWidth + 5) * lines || rect.height() * lines > textHeight) {
        tp.setTextSize(tp.getTextSize() - 1);
        tp.getTextBounds(text, 0, text.length(), rect);
        // setTextScaleX(availableWidth / size);
      }

      // if (getLineCount() != lines) {
      setLines(lines);
      setMaxLines(lines);
      setGravity(Gravity.TOP);
      // }
      setTextSize(TypedValue.COMPLEX_UNIT_PX, tp.getTextSize());
    }
  }
コード例 #2
0
  // 下面代码是利用上面计算的显示行数,将文字画在画布上,实时更新。
  @Override
  public void onDraw(Canvas canvas) {
    if (textList.size() == 0) return;
    for (int i = 0; i < textList.size(); i++) {

      if (step < this.getHeight() + textList.size() * tp.getTextSize()) {
        canvas.drawText(
            textList.get(i), 0, this.getHeight() + (i + 1) * tp.getTextSize() - step, tp);
        canvas.drawText(" ", 0, 40, tp);
      } else {
        step = 0;
      }
    }

    invalidate();
    // System.out.println("this.getHeight(): " + this.getHeight());
    if (this.getHeight() < textList.size() * textSize) {
      step = step + speed;
    } else {
      step = this.getHeight();
    }

    // if (step >= this.getHeight() + textList.size() * tp.getTextSize()) {
    // step = 0;
    // }
  }
コード例 #3
0
 protected void updateTextPaint(TextPaint ds) {
   if (isVisible()) {
     ds.setTextSize(ds.getTextSize() * 1.0f);
     ds.setAlpha(ds.getAlpha());
   } else {
     ds.setTextSize(ds.getTextSize() * mInvisibleSize);
     ds.setAlpha(0); // ensure the text is not visible
   }
 }
コード例 #4
0
ファイル: TextUtils.java プロジェクト: omegasoft7/wATL
 private static String glyphMetricsString(TextPaint paint) {
   int metricsInt = paint.getFontMetricsInt(paint.getFontMetricsInt());
   float textSize = paint.getTextSize();
   float textScale = paint.getTextScaleX();
   float textSkew = paint.getTextSkewX();
   Typeface typeface = paint.getTypeface();
   return String.format("%i%.2f%.2f%.2f", metricsInt, textSize, textScale, textSkew);
 }
コード例 #5
0
ファイル: TextFitView.java プロジェクト: ExCiteS/Sapelli
  /**
   * @param textSizePx
   * @param applyNow
   */
  private void setTextSizePx(float textSizePx, boolean applyNow) {
    // update text size field (checked elsewhere)
    this.textSizePx = textSizePx;

    if (applyNow && paint.getTextSize() != textSizePx) {
      paint.setTextSize(textSizePx);
      updateLayout();
    }
  }
コード例 #6
0
    public void initPaint(@NonNull TextPaint base) {
      paint.set(base);
      paint.setColor(color);
      paint.setAlpha(intAlpha());
      final Typeface typeface = base.getTypeface();
      if (typeface != null && typeface.getStyle() != Typeface.NORMAL) {
        paint.setTypeface(Typeface.create(typeface, Typeface.NORMAL));
      }

      // pre-calculate fixed height
      paint.setTextSize(Math.max(base.getTextSize() * DEF_SCALE, minTextSize));
      paint.getTextBounds("|", 0, 1, bounds);
      fixedTextHeight = bounds.height();

      // set real text size value
      paint.setTextSize(Math.max(base.getTextSize() * scale, minTextSize));

      initPaintShadow();
      invalidate(true);
    }
コード例 #7
0
ファイル: Switch.java プロジェクト: 30962088/c11_as
  /**
   * Sets the switch text color, size, style, hint color, and highlight color from the specified
   * TextAppearance resource.
   *
   * @attr ref android.R.styleable#Switch_switchTextAppearance
   */
  public void setSwitchTextAppearance(Context context, int resid) {
    TypedArray appearance = context.obtainStyledAttributes(resid, R.styleable.TextAppearanceSwitch);

    ColorStateList colors;
    int ts;

    colors = appearance.getColorStateList(R.styleable.TextAppearanceSwitch_textColor);
    if (colors != null) {
      mTextColors = colors;
    } else {
      // If no color set in TextAppearance, default to the view's textColor
      mTextColors = getTextColors();
    }

    ts = appearance.getDimensionPixelSize(R.styleable.TextAppearanceSwitch_textSize, 0);
    if (ts != 0) {
      if (ts != mTextPaint.getTextSize()) {
        mTextPaint.setTextSize(ts);
        requestLayout();
      }
    }

    int typefaceIndex, styleIndex;

    typefaceIndex = appearance.getInt(R.styleable.TextAppearanceSwitch_typeface, -1);
    styleIndex = appearance.getInt(R.styleable.TextAppearanceSwitch_textStyle, -1);

    setSwitchTypefaceByIndex(typefaceIndex, styleIndex);

    boolean allCaps = appearance.getBoolean(R.styleable.TextAppearanceSwitch_textAllCaps, false);
    if (allCaps) {
      mSwitchTransformationMethod = new AllCapsTransformationMethod(getContext());
      mSwitchTransformationMethod.setLengthChangesAllowed(true);
    } else {
      mSwitchTransformationMethod = null;
    }

    appearance.recycle();
  }
コード例 #8
0
  @Override
  protected void drawCallout(Canvas canvas, NMapView mapView, boolean shadow, long when) {

    adjustTextBounds(mapView);

    stepAnimations(canvas, mapView, when);

    drawBackground(canvas);

    float left, top;

    // draw title
    mOffsetX = mTempPoint.x - mTempRect.width() / 2;
    mOffsetX -= mPaddingOffset;
    mOffsetY = mTempRectF.top + mPaddingY + mTextPaint.getTextSize() + mTitleOffsetY;
    canvas.drawText(mTitleTruncated, mOffsetX, mOffsetY, mTextPaint);

    // draw right button
    if (mDrawableRightButton != null) {
      left = mTempRectF.right - mPaddingX - mCalloutRightButtonWidth;
      top = mTempRectF.top + (mBackgroundHeight - mCalloutRightButtonHeight) / 2;

      // Use background drawables depends on current state
      mRightButtonRect.left = (int) (left + 0.5F);
      mRightButtonRect.top = (int) (top + 0.5F);
      mRightButtonRect.right = (int) (left + mCalloutRightButtonWidth + 0.5F);
      mRightButtonRect.bottom = (int) (top + mCalloutRightButtonHeight + 0.5F);

      int itemState = super.getItemState(0);
      Drawable drawable = getDrawable(0, itemState);
      if (drawable != null) {
        drawable.setBounds(mRightButtonRect);
        drawable.draw(canvas);
      }

      if (mRightButtonText != null) {
        mTextPaint.getTextBounds(mRightButtonText, 0, mRightButtonText.length(), mTempRect);

        left = mRightButtonRect.left + (mCalloutRightButtonWidth - mTempRect.width()) / 2;
        top =
            mRightButtonRect.top
                + (mCalloutRightButtonHeight - mTempRect.height()) / 2
                + mTempRect.height()
                + mTitleOffsetY;
        canvas.drawText(mRightButtonText, left, top, mTextPaint);
      }
    }

    // draw tail text
    if (mTailText != null) {
      if (mRightButtonRect != null) {
        left = mRightButtonRect.left;
      } else {
        left = mTempRectF.right;
      }
      left -= mPaddingX + mTailTextWidth;
      top = mOffsetY;

      canvas.drawText(mTailText, left, top, mTextPaint);
    }
  }
コード例 #9
0
  /**
   * Resize the text size with specified width and height
   *
   * @param width
   * @param height
   */
  public void resizeText(int width, int height) {
    CharSequence text = getText();
    // Do not resize if the view does not have dimensions or there is no text
    if (text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) {
      return;
    }

    // Get the text view's paint object
    TextPaint textPaint = getPaint();

    // Store the current text size
    float oldTextSize = textPaint.getTextSize();
    // If there is a max text size set, use the lesser of that and the default text size
    float targetTextSize = mMaxTextSize > 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize;

    // Get the required text height
    int textHeight = getTextHeight(text, textPaint, width, targetTextSize);

    // Until we either fit within our text view or we had reached our min text size, incrementally
    // try smaller sizes
    while (textHeight > height && targetTextSize > mMinTextSize) {
      targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
      textHeight = getTextHeight(text, textPaint, width, targetTextSize);
    }

    // If we had reached our minimum text size and still don't fit, append an ellipsis
    if (mAddEllipsis && targetTextSize == mMinTextSize && textHeight > height) {
      // Draw using a static layout
      StaticLayout layout =
          new StaticLayout(
              text, textPaint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);
      // Check that we have a least one line of rendered text
      if (layout.getLineCount() > 0) {
        // Since the line at the specific vertical position would be cut off,
        // we must trim up to the previous line
        int lastLine = layout.getLineForVertical(height) - 1;
        // If the text would not even fit on a single line, clear it
        if (lastLine < 0) {
          setText("");
        }
        // Otherwise, trim to the previous line and add an ellipsis
        else {
          int start = layout.getLineStart(lastLine);
          int end = layout.getLineEnd(lastLine);
          float lineWidth = layout.getLineWidth(lastLine);
          float ellipseWidth = textPaint.measureText(mEllipsis);

          // Trim characters off until we have enough room to draw the ellipsis
          while (width < lineWidth + ellipseWidth) {
            lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString());
          }
          setText(text.subSequence(0, end) + mEllipsis);
        }
      }
    }

    // Some devices try to auto adjust line spacing, so force default line spacing
    // and invalidate the layout as a side effect
    textPaint.setTextSize(targetTextSize);
    setLineSpacing(mSpacingAdd, mSpacingMult);

    // Notify the listener if registered
    if (mTextResizeListener != null) {
      mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize);
    }

    // Reset force resize flag
    mNeedsResize = false;
  }
コード例 #10
0
ファイル: TextLine.java プロジェクト: JokeLook/framework
  /**
   * Utility function for measuring and rendering text. The text must not include a tab or emoji.
   *
   * @param wp the working paint
   * @param start the start of the text
   * @param end the end of the text
   * @param runIsRtl true if the run is right-to-left
   * @param c the canvas, can be null if rendering is not needed
   * @param x the edge of the run closest to the leading margin
   * @param top the top of the line
   * @param y the baseline
   * @param bottom the bottom of the line
   * @param fmi receives metrics information, can be null
   * @param needWidth true if the width of the run is needed
   * @return the signed width of the run based on the run direction; only valid if needWidth is true
   */
  private float handleText(
      TextPaint wp,
      int start,
      int end,
      int contextStart,
      int contextEnd,
      boolean runIsRtl,
      Canvas c,
      float x,
      int top,
      int y,
      int bottom,
      FontMetricsInt fmi,
      boolean needWidth) {

    // Get metrics first (even for empty strings or "0" width runs)
    if (fmi != null) {
      /// M: new FontMetrics method for complex text support.
      expandMetricsFromPaint(fmi, wp, mText);
    }

    int runLen = end - start;
    // No need to do anything if the run width is "0"
    if (runLen == 0) {
      return 0f;
    }

    float ret = 0;

    int contextLen = contextEnd - contextStart;
    if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) {
      int flags = runIsRtl ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR;
      if (mCharsValid) {
        ret =
            wp.getTextRunAdvances(mChars, start, runLen, contextStart, contextLen, flags, null, 0);
      } else {
        int delta = mStart;
        ret =
            wp.getTextRunAdvances(
                mText,
                delta + start,
                delta + end,
                delta + contextStart,
                delta + contextEnd,
                flags,
                null,
                0);
      }
    }

    if (c != null) {
      if (runIsRtl) {
        x -= ret;
      }

      if (wp.bgColor != 0) {
        int previousColor = wp.getColor();
        Paint.Style previousStyle = wp.getStyle();

        wp.setColor(wp.bgColor);
        wp.setStyle(Paint.Style.FILL);
        c.drawRect(x, top, x + ret, bottom, wp);

        wp.setStyle(previousStyle);
        wp.setColor(previousColor);
      }

      if (wp.underlineColor != 0) {
        // kStdUnderline_Offset = 1/9, defined in SkTextFormatParams.h
        float underlineTop = y + wp.baselineShift + (1.0f / 9.0f) * wp.getTextSize();

        int previousColor = wp.getColor();
        Paint.Style previousStyle = wp.getStyle();
        boolean previousAntiAlias = wp.isAntiAlias();

        wp.setStyle(Paint.Style.FILL);
        wp.setAntiAlias(true);

        wp.setColor(wp.underlineColor);
        c.drawRect(x, underlineTop, x + ret, underlineTop + wp.underlineThickness, wp);

        wp.setStyle(previousStyle);
        wp.setColor(previousColor);
        wp.setAntiAlias(previousAntiAlias);
      }

      drawTextRun(c, wp, start, end, contextStart, contextEnd, runIsRtl, x, y + wp.baselineShift);
    }

    return runIsRtl ? -ret : ret;
  }
コード例 #11
0
 public float getTextSize() {
   return baseTextPaint.getTextSize();
 }
コード例 #12
0
ファイル: TextResizeView.java プロジェクト: androvdr/AndroVDR
  /**
   * Resize the text size with specified width and height
   *
   * @param width
   * @param height
   */
  public void resizeText(int width, int height) {
    CharSequence text = getText();
    // Do not resize if the view does not have dimensions or there is no
    // text
    // or if mTextSize has not been initialized
    if (text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) {
      return;
    }

    // Get the text view's paint object
    TextPaint textPaint = getPaint();

    // Store the current text size
    float oldTextSize = textPaint.getTextSize();

    // If there is a max text size set, use the lesser of that and the
    // default text size
    float targetTextSize = mMaxTextSize > 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize;

    // Get the required text height
    int textHeight = getTextHeight(text, textPaint, width, targetTextSize);
    int textWidth = getTextWidth(text, textPaint, width, targetTextSize);
    int lineHeight = getTextHeight(text, textPaint, width * 10, targetTextSize);

    // Until we either fit within our text view or we had reached our min
    // text size, incrementally try smaller sizes
    while (((textHeight > height) || (textWidth > width) || (textHeight > lineHeight))
        && targetTextSize > mMinTextSize) {
      targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
      textHeight = getTextHeight(text, textPaint, width, targetTextSize);
      textWidth = getTextWidth(text, textPaint, width, targetTextSize);
      lineHeight = getTextHeight(text, textPaint, width * 10, targetTextSize);
    }

    // If we had reached our minimum text size and still don't fit, append
    // an ellipsis
    if (mAddEllipsis && targetTextSize == mMinTextSize && textHeight > height) {
      // Draw using a static layout
      StaticLayout layout =
          new StaticLayout(
              text, textPaint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);
      layout.draw(sTextResizeCanvas);
      int lastLine = layout.getLineForVertical(height) - 1;
      int start = layout.getLineStart(lastLine);
      int end = layout.getLineEnd(lastLine);
      float lineWidth = layout.getLineWidth(lastLine);
      float ellipseWidth = textPaint.measureText(mEllipsis);

      // Trim characters off until we have enough room to draw the
      // ellipsis
      while (width < lineWidth + ellipseWidth) {
        lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString());
      }
      setText(text.subSequence(0, end) + mEllipsis);
    }

    // Some devices try to auto adjust line spacing, so force default line
    // spacing
    // and invalidate the layout as a side effect
    textPaint.setTextSize(targetTextSize);
    setLineSpacing(mSpacingAdd, mSpacingMult);

    // Notify the listener if registered
    if (mTextResizeListener != null) {
      mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize);
    }

    // Reset force resize flag
    mNeedsResize = false;
  }
コード例 #13
0
 public int getTextSize() {
   return (int) textPaint.getTextSize();
 }
コード例 #14
0
ファイル: MessageView.java プロジェクト: markadam/telegram
    public void build(MessageWireframe wireframe, int desiredWidth, StelsApplication application) {

      Logger.d(TAG, "Build layout start");

      checkResources(application);

      senderPaint = initTextPaint();
      senderPaint.setTypeface(FontController.loadTypeface(application, "regular"));
      senderPaint.setTextSize(bodyPaint.getTextSize());
      senderPaint.setColor(0xff000000);

      forwardingPaint = initTextPaint();
      forwardingPaint.setTypeface(FontController.loadTypeface(application, "light"));
      forwardingPaint.setTextSize(bodyPaint.getTextSize());
      forwardingPaint.setColor(0xff000000);

      this.layoutDesiredWidth = desiredWidth;
      this.isOut = wireframe.message.isOut();
      this.showState = isOut;
      this.isGroup = wireframe.message.getPeerType() == PeerType.PEER_CHAT && !isOut;
      if (isGroup) {
        User user = wireframe.senderUser;
        this.senderName = user.getDisplayName();
        if (!wireframe.message.isForwarded()) {
          senderPaint.setColor(
              Placeholders.USER_PLACEHOLDERS_COLOR[
                  wireframe.message.getSenderId() % Placeholders.USER_PLACEHOLDERS_COLOR.length]);
          forwardingPaint.setColor(
              Placeholders.USER_PLACEHOLDERS_COLOR[
                  wireframe.message.getSenderId() % Placeholders.USER_PLACEHOLDERS_COLOR.length]);
        }
      }

      if (wireframe.message.isForwarded()) {
        isForwarded = true;
        this.forwarderName = wireframe.forwardUser.getDisplayName();
        if (isOut) {
          forwardingPaint.setColor(0xff739f53);
          senderPaint.setColor(0xff739f53);
        } else {
          forwardingPaint.setColor(0xff4884cf);
          senderPaint.setColor(0xff4884cf);
        }
      } else {
        isForwarded = false;
      }

      if (isGroup) {
        User user = application.getEngine().getUser(wireframe.message.getSenderId());
        this.senderName = user.getDisplayName();
      }
      if (wireframe.message.isForwarded()) {
        isForwarded = true;
        this.forwarderName = wireframe.forwardUser.getDisplayName();
      } else {
        isForwarded = false;
      }

      layoutDesiredWidth = desiredWidth;
      long start = SystemClock.uptimeMillis();

      this.spannable =
          application
              .getEmojiProcessor()
              .processEmojiCompatMutable(
                  wireframe.message.getMessage(), EmojiProcessor.CONFIGURATION_BUBBLES);

      // spannable = new SpannableString(wireframe.message.getMessage());
      Logger.d(TAG, "Emoji processed in " + (SystemClock.uptimeMillis() - start) + " ms");
      start = SystemClock.uptimeMillis();
      Linkify.addLinks(
          this.spannable, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS | Linkify.EMAIL_ADDRESSES);
      fixLinks(spannable);
      Logger.d(TAG, "Added links in " + (SystemClock.uptimeMillis() - start) + " ms");
      start = SystemClock.uptimeMillis();
      layout =
          new StaticLayout(
              spannable, bodyPaint, desiredWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true);
      Logger.d(TAG, "Built base layout in " + (SystemClock.uptimeMillis() - start) + " ms");

      if (layout.getLineCount() < 20) {
        int layoutTextWidth = 0;

        for (int i = 0; i < layout.getLineCount(); i++) {
          layoutTextWidth = (int) Math.max(layout.getLineWidth(i), layoutTextWidth);
        }

        if (layoutTextWidth < layout.getWidth() - px(10)) {
          layout =
              new StaticLayout(
                  spannable,
                  bodyPaint,
                  layoutTextWidth + px(2),
                  Layout.Alignment.ALIGN_NORMAL,
                  1.0f,
                  0.0f,
                  true);
        }
      }

      layoutRealWidth = layout.getWidth();

      timeWidth = (int) clockOutPaint.measureText(wireframe.date) + px((showState ? 23 : 0) + 6);

      if (layout.getLineCount() == 1) {
        boolean isLastRtl = layout.getParagraphDirection(0) == Layout.DIR_RIGHT_TO_LEFT;
        if (!isLastRtl && desiredWidth - layoutRealWidth > timeWidth) {
          layoutRealWidth += timeWidth;
          layoutHeight = layout.getHeight() + px(3);
        } else if (isLastRtl && desiredWidth - layout.getWidth() > timeWidth) {
          layoutRealWidth = layout.getWidth() + timeWidth;
          layoutHeight = layout.getHeight() + px(3);
        } else {
          if (isLastRtl) {
            layoutRealWidth = layout.getWidth();
          }

          layoutHeight = layout.getHeight() + px(17);
        }
      } else {
        boolean isLastRtl =
            layout.getParagraphDirection(layout.getLineCount() - 1) == Layout.DIR_RIGHT_TO_LEFT;
        if (!isLastRtl
            && (desiredWidth - layout.getLineWidth(layout.getLineCount() - 1) > timeWidth)) {
          layoutRealWidth =
              (int)
                  Math.max(
                      layoutRealWidth, layout.getLineWidth(layout.getLineCount() - 1) + timeWidth);
          layoutHeight = layout.getHeight() + px(3);
        } else if (isLastRtl && (desiredWidth - layout.getWidth() > timeWidth)) {
          layoutRealWidth = (int) Math.max(layoutRealWidth, layout.getWidth() + timeWidth);
          layoutHeight = layout.getHeight() + px(3);
        } else {
          layoutHeight = layout.getHeight() + px(17);
        }
      }

      if (layoutRealWidth < timeWidth) {
        layoutRealWidth = timeWidth;
      }

      if (isForwarded) {
        layoutHeight += px(19) * 2;
        forwardOffset = (int) forwardingPaintBase.measureText("From ");
        layoutRealWidth =
            (int) Math.max(layoutRealWidth, forwardingPaintBase.measureText("Forwarded message"));
        forwarderNameMeasured =
            TextUtils.ellipsize(
                    forwarderName,
                    senderPaintBase,
                    desiredWidth - forwardOffset,
                    TextUtils.TruncateAt.END)
                .toString();
        layoutRealWidth =
            (int)
                Math.max(
                    layoutRealWidth,
                    forwardOffset + senderPaintBase.measureText(forwarderNameMeasured));
      }

      if (isGroup && !isOut && !isForwarded) {
        layoutHeight += px(19);
        senderNameMeasured =
            TextUtils.ellipsize(senderName, senderPaintBase, desiredWidth, TextUtils.TruncateAt.END)
                .toString();
        int width = (int) senderPaintBase.measureText(senderNameMeasured);
        layoutRealWidth = Math.max(layoutRealWidth, width);
      }

      Logger.d(TAG, "Build layout end");
    }
コード例 #15
0
  @Override
  protected void onDraw(Canvas canvas) {
    // Location
    x = getWidth() / 2;
    y = getHeight() / 2;
    int pos = (int) (textSize / 2);
    int framesPerSecond = 60;

    // Brushes
    Paint blueBrush = new Paint(Paint.ANTI_ALIAS_FLAG);
    blueBrush.setColor(mContext.getResources().getColor(R.color.sunshine_blue));
    blueBrush.setStrokeWidth(3f);

    Paint whiteBrush = new Paint(Paint.ANTI_ALIAS_FLAG);
    whiteBrush.setColor(mContext.getResources().getColor(R.color.background_wind_speed));
    whiteBrush.setStrokeWidth(3f);

    Paint redBrush = new Paint(Paint.ANTI_ALIAS_FLAG);
    redBrush.setColor(Color.RED);
    redBrush.setStrokeWidth(3f);

    TextPaint textPaint = new TextPaint();
    textPaint.setColor(Color.YELLOW);
    textPaint.setFakeBoldText(true);
    textPaint.setStrokeWidth(2f);
    textPaint.setTextSize(textSize);
    textSize = textPaint.getTextSize();

    // External Circle
    canvas.drawCircle(x, y, height / 2, blueBrush);
    // Internal Circle
    canvas.drawCircle(x, y, (height / 2) - textSize, whiteBrush);
    // Indicator Circle
    canvas.drawCircle(x, y, (height / 17), redBrush);

    mCanvas = canvas;
    mCanvas.save();

    // Direction labels
    canvas.drawText(mContext.getString(R.string.north), x - pos, textSize, textPaint);
    canvas.drawText(mContext.getString(R.string.south), x - pos, y * 2 - 2, textPaint);
    canvas.drawText(mContext.getString(R.string.east), (x * 2) - textSize + 2, y + pos, textPaint);
    canvas.drawText(mContext.getString(R.string.west), textSize - (pos * 2), y + pos, textPaint);

    // Layers for rotated labels
    Canvas canNE = canvas;
    Canvas canNW = canvas;
    canNE.save();
    canNW.save();

    // Indicator
    setWindSpeedDirection(direction);

    canNE.rotate(45, x, y);
    canNE.drawText(mContext.getString(R.string.north_east), x - (pos * 2), textSize, textPaint);
    canNE.drawText(mContext.getString(R.string.south_west), x - (pos * 2), y * 2 - 2, textPaint);
    canNW.rotate(270, x, y);
    canNW.drawText(mContext.getString(R.string.north_west), x - (pos * 2), textSize, textPaint);
    canNW.drawText(mContext.getString(R.string.south_east), x - (pos * 2), y * 2 - 2, textPaint);
    canvas.restore();

    if (!finishAnimation) {
      postInvalidateDelayed(1000 / framesPerSecond);
    }
  }