Exemplo n.º 1
0
  /**
   * Computes (using "simulated" drawing/measuring) whether or not the (possibly multi-line) text,
   * will fit within a bounding box defined by the supplied parameters, when rendered at the
   * supplied text (font) size.
   *
   * @param textSize - the text/font size to use
   * @param targetWidth - the width of the containing box
   * @param targetHeight - the height of the containing box
   * @return whether or not the text will fit into the containing box with the provided text size
   */
  private boolean textFits(float textSize, float targetWidth, float targetHeight) {
    // Log.d("TFV", "text: "+text+" text height: "+layout.getHeight()+" target: "+targetHeight+"
    // fits: "+(layout.getWidth() <= targetWidth && layout.getHeight() <= targetHeight));

    // Set the paint's text size to the value used for simulation:
    paint.setTextSize(textSize);

    // Compute maximum width across the lines:
    float width = 0;
    for (String line : textLines)
      // measure bounds for each line of text:
      width =
          Math.max(
              width,
              paint.measureText(line)); // max width is max(previous max width, this line width)
    // determine height by doing no. lines * interline spacing (= font height + spacing between
    // bottom of one line and top of another)
    // NOTE: do not use Paint#getTextBounds because this ignores any spacing above or below the
    // character, which will be included by the
    // StaticLayout regardless (e.g. the bounds height of "." would be very low as it excludes the
    // space above the character)

    // Check whether the text fits:
    boolean fits =
        width <= targetWidth && textLines.length * paint.getFontMetrics(null) <= targetHeight;

    // Reset the paint's text size to match the value held by the view:
    paint.setTextSize(this.textSizePx);

    // Return result:
    return fits;
  }
Exemplo n.º 2
0
  private void invalidateTextPaintAndMeasurements() {
    mTextPaint.setTextSize(mExampleDimension);
    mTextPaint.setColor(mExampleColor);
    mTextWidth = mTextPaint.measureText(mExampleString);

    Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
    mTextHeight = fontMetrics.bottom;
  }
 private void init(Context context) {
   DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
   float textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 17.0F, displayMetrics);
   mTextPaint.setTextSize(textSize);
   Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
   cent1 = (int) (fontMetrics.descent - fontMetrics.ascent);
   cent2 = (int) fontMetrics.descent + 1 >> 1;
 }
 private void initPadding() {
   extraPaddingTop =
       floatingLabelEnabled ? floatingLabelTextSize + floatingLabelPadding : floatingLabelPadding;
   textPaint.setTextSize(bottomTextSize);
   Paint.FontMetrics textMetrics = textPaint.getFontMetrics();
   extraPaddingBottom =
       (int) ((textMetrics.descent - textMetrics.ascent) * currentBottomLines)
           + (hideUnderline ? bottomSpacing : bottomSpacing * 2);
   extraPaddingLeft = iconLeftBitmaps == null ? 0 : (iconOuterWidth + iconPadding);
   extraPaddingRight = iconRightBitmaps == null ? 0 : (iconOuterWidth + iconPadding);
   correctPaddings();
 }
Exemplo n.º 5
0
 private void drawText(Canvas canvas) {
   Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
   float fontHeight = fontMetrics.bottom - fontMetrics.top;
   float textBaseY = getHeight() - (getHeight() - fontHeight) / 2 - fontMetrics.bottom;
   double offset = mSlantedLength / 4 - 1;
   float toY = (float) (textBaseY - offset);
   int angle = 45;
   if (mMode == 1) {
     angle = -45;
     offset = -offset;
   }
   float toX = (float) (getWidth() / 2 + offset);
   canvas.rotate(angle, toX, toY);
   canvas.drawText(mSlantedText, toX, toY, mTextPaint);
 }
  private void init(Context context) {
    this.context = context;

    setBackgroundColor(Color.TRANSPARENT);

    // 设置绘制flag的paint
    paint = new Paint();
    paint.setColor(patientColor);
    paint.setAntiAlias(true);

    // 设置绘制文字的paint
    textPaint = new TextPaint();
    textPaint.setAntiAlias(true);
    textPaint.setColor(Color.WHITE);
    textPaint.setTextSize(ABTextUtil.sp2px(context, 12));
    textPaint.setTextAlign(Paint.Align.CENTER);
    textFontMetrics = textPaint.getFontMetrics();
  }
 public TextListWithMoreComputer.Result a(List<String> paramList, int paramInt1, int paramInt2, int paramInt3, TextPaint paramTextPaint, int[] paramArrayOfInt)
 {
   Paint.FontMetrics localFontMetrics = paramTextPaint.getFontMetrics();
   float f1 = localFontMetrics.bottom - localFontMetrics.top;
   float f2 = Math.max(paramInt3, f1);
   ArrayList localArrayList = Lists.a();
   TextListWithMoreComputer.PeekingIteratorWithCount localPeekingIteratorWithCount = TextListWithMoreComputer.PeekingIteratorWithCount.a(paramList);
   int i = -1;
   float f3 = paramTextPaint.measureText(",");
   StringBuilder localStringBuilder1 = new StringBuilder(100);
   float f4;
   float f6;
   int j;
   String str1;
   boolean bool1;
   label141: float f7;
   float f8;
   if ((paramInt2 > 0) && (localPeekingIteratorWithCount.b() > 0) && (f2 >= f1))
   {
     paramInt2--;
     f4 = f2 - f1;
     float f5 = paramInt1;
     localStringBuilder1.setLength(0);
     f6 = f5;
     j = i;
     if (localPeekingIteratorWithCount.hasNext())
     {
       str1 = (String)localPeekingIteratorWithCount.a();
       if (localStringBuilder1.length() != 0)
       {
         bool1 = true;
         f7 = a(str1, bool1, paramTextPaint);
         if ((localPeekingIteratorWithCount.b() <= 1) || (paramInt2 <= 0))
           break label599;
         f8 = f7 + f3;
       }
     }
   }
   while (true)
   {
     int n;
     if ((paramInt2 > 0) && (f4 >= f1))
     {
       if (f8 < f6)
       {
         localPeekingIteratorWithCount.next();
         if (localStringBuilder1.length() > 0);
         for (boolean bool5 = true; ; bool5 = false)
         {
           a(localStringBuilder1, str1, bool5);
           n = j;
           label224: f6 -= f7;
           j = n;
           break;
           bool1 = false;
           break label141;
         }
       }
       localStringBuilder1.append(",");
     }
     label258: int k;
     int m;
     while (true)
     {
       if (localStringBuilder1.length() != 0)
         localArrayList.add(localStringBuilder1.toString());
       i = j;
       f2 = f4;
       break;
       if (localPeekingIteratorWithCount.b() == 1)
       {
         if (f6 < f7)
         {
           j = 1;
           localPeekingIteratorWithCount.next();
           n = j;
           break label224;
         }
         if (localStringBuilder1.length() > 0);
         for (boolean bool4 = true; ; bool4 = false)
         {
           a(localStringBuilder1, str1, bool4);
           break;
         }
       }
       k = localPeekingIteratorWithCount.b();
       m = a(paramArrayOfInt, localPeekingIteratorWithCount.b());
       if (f6 - f7 >= m)
         break label540;
       if (k >= 5)
         break label482;
       StringBuilder localStringBuilder2 = new StringBuilder();
       if (localPeekingIteratorWithCount.hasNext())
       {
         String str3 = (String)localPeekingIteratorWithCount.next();
         if ((localStringBuilder1.length() != 0) || (localStringBuilder2.length() != 0));
         for (boolean bool3 = true; ; bool3 = false)
         {
           a(localStringBuilder2, str3, bool3);
           break;
         }
       }
       if (a(localStringBuilder2, false, paramTextPaint) > f6)
         break label482;
       localStringBuilder1.append(localStringBuilder2);
     }
     label482: if (localStringBuilder1.length() == 0)
     {
       String str2 = a(str1, paramTextPaint, f6 - m);
       if (str2 != null)
       {
         localStringBuilder1.append(str2);
         localStringBuilder1.append("…");
       }
     }
     for (int i1 = k - 1; ; i1 = k)
     {
       j = i1;
       break label258;
       label540: localPeekingIteratorWithCount.next();
       if (localStringBuilder1.length() > 0);
       for (boolean bool2 = true; ; bool2 = false)
       {
         a(localStringBuilder1, str1, bool2);
         n = j;
         break;
       }
       return new TextListWithMoreComputer.Result(localArrayList, i);
     }
     label599: f8 = f7;
   }
 }
Exemplo n.º 8
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;
      }
    }
  @Override
  protected void onDraw(@NonNull Canvas canvas) {
    int startX = getScrollX() + (iconLeftBitmaps == null ? 0 : (iconOuterWidth + iconPadding));
    int endX =
        getScrollX()
            + (iconRightBitmaps == null ? getWidth() : getWidth() - iconOuterWidth - iconPadding);
    int lineStartY = getScrollY() + getHeight() - getPaddingBottom();

    // draw the icon(s)
    paint.setAlpha(255);
    if (iconLeftBitmaps != null) {
      Bitmap icon = iconLeftBitmaps[!isInternalValid() ? 3 : !isEnabled() ? 2 : hasFocus() ? 1 : 0];
      int iconLeft = startX - iconPadding - iconOuterWidth + (iconOuterWidth - icon.getWidth()) / 2;
      int iconTop =
          lineStartY + bottomSpacing - iconOuterHeight + (iconOuterHeight - icon.getHeight()) / 2;
      canvas.drawBitmap(icon, iconLeft, iconTop, paint);
    }
    if (iconRightBitmaps != null) {
      Bitmap icon =
          iconRightBitmaps[!isInternalValid() ? 3 : !isEnabled() ? 2 : hasFocus() ? 1 : 0];
      int iconRight = endX + iconPadding + (iconOuterWidth - icon.getWidth()) / 2;
      int iconTop =
          lineStartY + bottomSpacing - iconOuterHeight + (iconOuterHeight - icon.getHeight()) / 2;
      canvas.drawBitmap(icon, iconRight, iconTop, paint);
    }

    // draw the clear button
    if (hasFocus() && showClearButton && !TextUtils.isEmpty(getText()) && isEnabled()) {
      paint.setAlpha(255);
      int buttonLeft;
      if (isRTL()) {
        buttonLeft = startX;
      } else {
        buttonLeft = endX - iconOuterWidth;
      }
      Bitmap clearButtonBitmap = clearButtonBitmaps[0];
      buttonLeft += (iconOuterWidth - clearButtonBitmap.getWidth()) / 2;
      int iconTop =
          lineStartY
              + bottomSpacing
              - iconOuterHeight
              + (iconOuterHeight - clearButtonBitmap.getHeight()) / 2;
      canvas.drawBitmap(clearButtonBitmap, buttonLeft, iconTop, paint);
    }

    // draw the underline
    if (!hideUnderline) {
      lineStartY += bottomSpacing;
      if (!isInternalValid()) { // not valid
        paint.setColor(errorColor);
        canvas.drawRect(startX, lineStartY, endX, lineStartY + getPixel(2), paint);
      } else if (!isEnabled()) { // disabled
        paint.setColor(underlineColor != -1 ? underlineColor : baseColor & 0x00ffffff | 0x44000000);
        float interval = getPixel(1);
        for (float xOffset = 0; xOffset < getWidth(); xOffset += interval * 3) {
          canvas.drawRect(
              startX + xOffset,
              lineStartY,
              startX + xOffset + interval,
              lineStartY + getPixel(1),
              paint);
        }
      } else if (hasFocus()) { // focused
        paint.setColor(primaryColor);
        canvas.drawRect(startX, lineStartY, endX, lineStartY + getPixel(2), paint);
      } else { // normal
        paint.setColor(underlineColor != -1 ? underlineColor : baseColor & 0x00ffffff | 0x1E000000);
        canvas.drawRect(startX, lineStartY, endX, lineStartY + getPixel(1), paint);
      }
    }

    textPaint.setTextSize(bottomTextSize);
    Paint.FontMetrics textMetrics = textPaint.getFontMetrics();
    float relativeHeight = -textMetrics.ascent - textMetrics.descent;
    float bottomTextPadding = bottomTextSize + textMetrics.ascent + textMetrics.descent;

    // draw the characters counter
    if ((hasFocus() && hasCharactersCounter()) || !isCharactersCountValid()) {
      textPaint.setColor(
          isCharactersCountValid() ? (baseColor & 0x00ffffff | 0x44000000) : errorColor);
      String charactersCounterText = getCharactersCounterText();
      canvas.drawText(
          charactersCounterText,
          isRTL() ? startX : endX - textPaint.measureText(charactersCounterText),
          lineStartY + bottomSpacing + relativeHeight,
          textPaint);
    }

    // draw the bottom text
    if (textLayout != null) {
      if (tempErrorText != null
          || ((helperTextAlwaysShown || hasFocus())
              && !TextUtils.isEmpty(helperText))) { // error text or helper text
        textPaint.setColor(
            tempErrorText != null
                ? errorColor
                : helperTextColor != -1 ? helperTextColor : (baseColor & 0x00ffffff | 0x44000000));
        canvas.save();
        if (isRTL()) {
          canvas.translate(
              endX - textLayout.getWidth(), lineStartY + bottomSpacing - bottomTextPadding);
        } else {
          canvas.translate(
              startX + getBottomTextLeftOffset(), lineStartY + bottomSpacing - bottomTextPadding);
        }
        textLayout.draw(canvas);
        canvas.restore();
      }
    }

    // draw the floating label
    if (floatingLabelEnabled && !TextUtils.isEmpty(floatingLabelText)) {
      textPaint.setTextSize(floatingLabelTextSize);
      // calculate the text color
      textPaint.setColor(
          (Integer)
              focusEvaluator.evaluate(
                  focusFraction * (isEnabled() ? 1 : 0),
                  floatingLabelTextColor != -1
                      ? floatingLabelTextColor
                      : (baseColor & 0x00ffffff | 0x44000000),
                  primaryColor));

      // calculate the horizontal position
      float floatingLabelWidth = textPaint.measureText(floatingLabelText.toString());
      int floatingLabelStartX;
      if ((getGravity() & Gravity.RIGHT) == Gravity.RIGHT || isRTL()) {
        floatingLabelStartX = (int) (endX - floatingLabelWidth);
      } else if ((getGravity() & Gravity.LEFT) == Gravity.LEFT) {
        floatingLabelStartX = startX;
      } else {
        floatingLabelStartX =
            startX
                + (int)
                    (getInnerPaddingLeft()
                        + (getWidth()
                                - getInnerPaddingLeft()
                                - getInnerPaddingRight()
                                - floatingLabelWidth)
                            / 2);
      }

      // calculate the vertical position
      int distance = floatingLabelPadding;
      int floatingLabelStartY =
          (int)
              (innerPaddingTop
                  + floatingLabelTextSize
                  + floatingLabelPadding
                  - distance * (floatingLabelAlwaysShown ? 1 : floatingLabelFraction)
                  + getScrollY());

      // calculate the alpha
      int alpha =
          ((int)
              ((floatingLabelAlwaysShown ? 1 : floatingLabelFraction)
                  * 0xff
                  * (0.74f * focusFraction * (isEnabled() ? 1 : 0) + 0.26f)
                  * (floatingLabelTextColor != -1
                      ? 1
                      : Color.alpha(floatingLabelTextColor) / 256f)));
      textPaint.setAlpha(alpha);

      // draw the floating label
      canvas.drawText(
          floatingLabelText.toString(), floatingLabelStartX, floatingLabelStartY, textPaint);
    }

    // draw the bottom ellipsis
    if (hasFocus() && singleLineEllipsis && getScrollX() != 0) {
      paint.setColor(isInternalValid() ? primaryColor : errorColor);
      float startY = lineStartY + bottomSpacing;
      int ellipsisStartX;
      if (isRTL()) {
        ellipsisStartX = endX;
      } else {
        ellipsisStartX = startX;
      }
      int signum = isRTL() ? -1 : 1;
      canvas.drawCircle(
          ellipsisStartX + signum * bottomEllipsisSize / 2,
          startY + bottomEllipsisSize / 2,
          bottomEllipsisSize / 2,
          paint);
      canvas.drawCircle(
          ellipsisStartX + signum * bottomEllipsisSize * 5 / 2,
          startY + bottomEllipsisSize / 2,
          bottomEllipsisSize / 2,
          paint);
      canvas.drawCircle(
          ellipsisStartX + signum * bottomEllipsisSize * 9 / 2,
          startY + bottomEllipsisSize / 2,
          bottomEllipsisSize / 2,
          paint);
    }

    // draw the original things
    super.onDraw(canvas);
  }