Example usage for android.graphics Paint getTextSize

List of usage examples for android.graphics Paint getTextSize

Introduction

In this page you can find the example usage for android.graphics Paint getTextSize.

Prototype

public float getTextSize() 

Source Link

Document

Return the paint's text size.

Usage

From source file:org.mariotaku.twidere.text.OriginalStatusSpan.java

@Override
public int getSize(final Paint paint, final CharSequence text, final int start, final int end,
        final Paint.FontMetricsInt fm) {
    paint.setTextSize(paint.getTextSize() * 0.8f);
    return (int) paint.measureText(text, start, end) + mPadding * 2;
}

From source file:fr.magistry.taigime.CandidateView.java

private float reduceTextSizeFromWidth(Paint p, String str, float maxWidth) {
    float size = p.getTextSize();
    if (str.length() == 0)
        return size;
    while (p.measureText(str) > maxWidth) {
        p.setTextSize(--size);/*from  w  ww .j  a  v a  2  s  .  com*/
    }
    return size;
}

From source file:me.futuretechnology.util.ui.TitlePageIndicator.java

/**
 * Calculate the bounds for a view's title
 *///from   w ww. jav  a 2s.c o  m
private Rect calcBounds(int index, Paint paint) {
    // calculate the text bounds
    Rect bounds = new Rect();
    CharSequence title = getTitle(index);
    bounds.right = (int) paint.measureText(title, 0, title.length());
    bounds.bottom = (int) paint.getTextSize(); // (paint.descent() - paint.ascent());
    return bounds;
}

From source file:com.tr4android.support.extension.picker.date.SimpleMonthView.java

/**
 * Applies the specified text appearance resource to a paint, returning the
 * text color if one is set in the text appearance.
 *
 * @param p the paint to modify/*www .  jav a 2s . c om*/
 * @param resId the resource ID of the text appearance
 * @return the text color, if available
 */
private ColorStateList applyTextAppearance(Paint p, int resId) {
    final TypedArray ta = getContext().obtainStyledAttributes(null, R.styleable.TextAppearance, 0, resId);

    final String fontFamily = ta.getString(R.styleable.TextAppearance_android_fontFamily);
    if (fontFamily != null) {
        p.setTypeface(Typeface.create(fontFamily, 0));
    }

    p.setTextSize(ta.getDimensionPixelSize(R.styleable.TextAppearance_android_textSize, (int) p.getTextSize()));

    final ColorStateList textColor = ta.getColorStateList(R.styleable.TextAppearance_android_textColor);
    if (textColor != null) {
        final int enabledColor = textColor.getColorForState(ENABLED_STATE_SET, 0);
        p.setColor(enabledColor);
    }

    ta.recycle();

    return textColor;
}

From source file:com.mukesh.OtpView.java

private void drawCircle(Canvas canvas, int i) {
    Paint paint = getPaintByIndex(i);
    float cx = itemCenterPoint.x;
    float cy = itemCenterPoint.y;
    if (rtlTextDirection) {
        int reversedItemPosition = otpViewItemCount - i;
        int reversedCharPosition = reversedItemPosition - getHint().length();
        if (reversedCharPosition <= 0) {
            canvas.drawCircle(cx, cy, paint.getTextSize() / 2, paint);
        }//from  ww w.  j ava2 s.  c om
    } else {
        canvas.drawCircle(cx, cy, paint.getTextSize() / 2, paint);
    }
}

From source file:net.toload.main.hd.candidate.CandidateView.java

private void doDraw(Canvas canvas) {

    if (mSuggestions == null)
        return;/*  w  ww.  j  a v  a  2 s .  c o  m*/
    if (DEBUG)
        Log.i(TAG, "CandidateView:doDraw():Suggestion mCount:" + mCount + " mSuggestions.size:"
                + mSuggestions.size());
    mTotalWidth = 0;

    updateFontSize();

    if (mBgPadding == null) {
        mBgPadding = new Rect(0, 0, 0, 0);
        if (getBackground() != null) {
            getBackground().getPadding(mBgPadding);
        }
    }

    final int height = mHeight;
    final Rect bgPadding = mBgPadding;
    final Paint candidatePaint = mCandidatePaint;
    final Paint candidateEmojiPaint = mCandidatePaint;
    candidateEmojiPaint.setTextSize((float) (candidateEmojiPaint.getTextSize() * 0.9));

    final Paint selKeyPaint = mSelKeyPaint;
    final int touchX = mTouchX;
    final int scrollX = getScrollX();
    final boolean scrolled = mScrolled;

    final int textBaseLine = (int) (((height - mCandidatePaint.getTextSize()) / 2) - mCandidatePaint.ascent());

    // Modified by jeremy '10, 3, 29.  Update mselectedindex if touched and build wordX[i] and wordwidth[i]
    int x = 0;
    final int count = mCount; //Cache count here '11,8,18
    for (int i = 0; i < count; i++) {
        if (count != mCount || mSuggestions == null || count != mSuggestions.size() || mSuggestions.size() == 0
                || i >= mSuggestions.size())
            return; // mSuggestion is updated, force abort

        String suggestion = mSuggestions.get(i).getWord();
        if (i == 0 && mSuggestions.size() > 1 && mSuggestions.get(1).isRuntimeBuiltPhraseRecord()
                && suggestion.length() > 8) {
            suggestion = suggestion.substring(0, 2) + "..";
        }
        float base = (suggestion == null) ? 0 : candidatePaint.measureText("");
        float textWidth = (suggestion == null) ? 0 : candidatePaint.measureText(suggestion);

        if (textWidth < base) {
            textWidth = base;
        }

        final int wordWidth = (int) textWidth + X_GAP * 2;

        mWordX[i] = x;

        mWordWidth[i] = wordWidth;

        if (touchX + scrollX >= x && touchX + scrollX < x + wordWidth && !scrolled) {
            mSelectedIndex = i;
        }
        x += wordWidth;
    }

    mTotalWidth = x;

    if (DEBUG)
        Log.i(TAG,
                "CandidateView:doDraw():mTotalWidth :" + mTotalWidth + "  this.getWidth():" + this.getWidth());

    //Jeremy '11,8,11. If the candidate list is within 1 page and has more records, get full records first.
    if (mTotalWidth < this.getWidth())
        checkHasMoreRecords();

    // Paint all the suggestions and lines.
    if (canvas != null) {

        // Moved from above by jeremy '10 3, 29. Paint mSelectedindex in highlight here
        if (count > 0 && mSelectedIndex >= 0) {
            //    candidatePaint.setColor(mColorComposingCode);
            //    canvas.drawRect(mWordX[mSelectedIndex],bgPadding.top, mWordWidth[mSelectedIndex] , height, candidatePaint);

            canvas.translate(mWordX[mSelectedIndex], 0);
            mDrawableSuggestHighlight.setBounds(0, bgPadding.top, mWordWidth[mSelectedIndex], height);
            mDrawableSuggestHighlight.draw(canvas);
            canvas.translate(-mWordX[mSelectedIndex], 0);

        }
        if (mTransparentCandidateView) {
            canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

            Paint backgroundPaint = new Paint();
            backgroundPaint.setColor(ContextCompat.getColor(mContext, R.color.third_background_light));
            backgroundPaint.setAlpha(33);
            backgroundPaint.setStyle(Paint.Style.FILL);

            canvas.drawRect(0.5f, bgPadding.top, mScreenWidth, height, backgroundPaint);
        }

        for (int i = 0; i < count; i++) {

            if (count != mCount || mSuggestions == null || count != mSuggestions.size()
                    || mSuggestions.size() == 0 || i >= mSuggestions.size())
                break;

            boolean isEmoji = mSuggestions.get(i).isEmojiRecord();
            String suggestion = mSuggestions.get(i).getWord();
            if (i == 0 && mSuggestions.size() > 1 && mSuggestions.get(1).isRuntimeBuiltPhraseRecord()
                    && suggestion.length() > 8) {
                suggestion = suggestion.substring(0, 2) + "..";
            }

            int c = i + 1;
            switch (mSuggestions.get(i).getRecordType()) {
            case Mapping.RECORD_COMPOSING_CODE:
                if (mSelectedIndex == 0) {

                    if (mTransparentCandidateView) {
                        candidatePaint.setColor(mColorInvertedTextTransparent);
                    } else {
                        candidatePaint.setColor(mColorComposingCodeHighlight);
                    }
                } else
                    candidatePaint.setColor(mColorComposingCode);
                break;
            case Mapping.RECORD_CHINESE_PUNCTUATION_SYMBOL:
            case Mapping.RECORD_RELATED_PHRASE:
                selKeyPaint.setColor(mColorSelKeyShifted);
                if (i == mSelectedIndex)
                    candidatePaint.setColor(mColorNormalTextHighlight);
                else
                    candidatePaint.setColor(mColorNormalText);
                break;
            case Mapping.RECORD_EXACT_MATCH_TO_CODE:
            case Mapping.RECORD_PARTIAL_MATCH_TO_CODE:
            case Mapping.RECORD_RUNTIME_BUILT_PHRASE:
            case Mapping.RECORD_ENGLISH_SUGGESTION:
            default:
                selKeyPaint.setColor(mColorSelKey);
                if (i == mSelectedIndex)
                    candidatePaint.setColor(mColorNormalTextHighlight);
                else
                    candidatePaint.setColor(mColorNormalText);
                break;

            }

            if (isEmoji) {
                canvas.drawText(suggestion, mWordX[i] + X_GAP, Math.round(textBaseLine * 0.95),
                        candidateEmojiPaint);
            } else {
                canvas.drawText(suggestion, mWordX[i] + X_GAP, textBaseLine, candidatePaint);
            }
            if (mShowNumber) {
                //Jeremy '11,6,17 changed from <=10 to mDisplaySelkey length. The length maybe 11 or 12 if shifted with space.
                if (c <= mDisplaySelkey.length()) {
                    //Jeremy '11,6,11 Drawing text using relative font dimensions.
                    canvas.drawText(mDisplaySelkey.substring(c - 1, c),
                            mWordX[i] + mWordWidth[i] - height * 0.3f, height * 0.4f, selKeyPaint);
                }
            }
            //Draw spacer
            candidatePaint.setColor(mColorSpacer);
            canvas.drawLine(mWordX[i] + mWordWidth[i] + 0.5f, bgPadding.top + (mVerticalPadding / 2),
                    mWordX[i] + mWordWidth[i] + 0.5f, height - (mVerticalPadding / 2), candidatePaint);
            candidatePaint.setFakeBoldText(false);

        }

        if (mTargetScrollX != getScrollX()) {
            if (DEBUG)
                Log.i(TAG, "CandidateView:doDraw():mTargetScrollX :" + mTargetScrollX + "  getScrollX():"
                        + getScrollX());
            scrollToTarget();
        }

    }

}

From source file:com.anysoftkeyboard.keyboards.views.AnyKeyboardViewBase.java

private float adjustTextSizeForLabel(final Paint paint, final CharSequence label, final int width) {
    TextWidthCacheKey cacheKey = new TextWidthCacheKey(label, width);
    if (mTextWidthCache.containsKey(cacheKey)) {
        return mTextWidthCache.get(cacheKey).setCachedValues(paint);
    }//from  ww  w .  java  2  s  . co m
    float textSize = paint.getTextSize();
    float textWidth = paint.measureText(label, 0, label.length());
    // I'm going to try something if the key is too small for the
    // text:
    // 1) divide the text size by 1.5
    // 2) if still too large, divide by 2.5
    // 3) show no text
    if (textWidth > width) {
        textSize = mKeyTextSize / 1.5f;
        paint.setTextSize(textSize);
        textWidth = paint.measureText(label, 0, label.length());
        if (textWidth > width) {
            textSize = mKeyTextSize / 2.5f;
            paint.setTextSize(textSize);
            textWidth = paint.measureText(label, 0, label.length());
            if (textWidth > width) {
                textSize = 0f;
                paint.setTextSize(textSize);
                textWidth = paint.measureText(label, 0, label.length());
            }
        }
    }

    mTextWidthCache.put(cacheKey, new TextWidthCacheValue(textSize, textWidth));
    return textWidth;
}

From source file:com.yek.keyboard.keyboards.views.CandidateView.java

/**
 * If the canvas is null, then only touch calculations are performed to pick
 * the target candidate./*from  ww  w  . j a  va  2  s.  c om*/
 */
@Override
protected void onDraw(Canvas canvas) {
    if (canvas != null) {
        super.onDraw(canvas);
    }
    mTotalWidth = 0;

    final int height = getHeight();
    if (mBgPadding == null) {
        mBgPadding = new Rect(0, 0, 0, 0);
        if (getBackground() != null) {
            getBackground().getPadding(mBgPadding);
        }
        mDivider.setBounds(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight());
    }

    final int dividerYOffset = (height - mDivider.getMinimumHeight()) / 2;
    final int count = mSuggestions.size();
    final Rect bgPadding = mBgPadding;
    final Paint paint = mPaint;
    final int touchX = mTouchX;
    final int scrollX = getScrollX();
    final boolean scrolled = mScrolled;
    final boolean typedWordValid = mTypedWordValid;

    int x = 0;
    for (int i = 0; i < count; i++) {
        CharSequence suggestion = mSuggestions.get(i);
        if (suggestion == null)
            continue;
        final int wordLength = suggestion.length();

        paint.setColor(mColorNormal);
        if (mHaveMinimalSuggestion && ((i == 1 && !typedWordValid) || (i == 0 && typedWordValid))) {
            paint.setTypeface(Typeface.DEFAULT_BOLD);
            paint.setColor(mColorRecommended);
            // existsAutoCompletion = true;
        } else if (i != 0 || (wordLength == 1 && count > 1)) {
            // HACK: even if i == 0, we use mColorOther when this
            // suggestion's length is 1 and
            // there are multiple suggestions, such as the default
            // punctuation list.
            paint.setColor(mColorOther);
        }

        // now that we set the typeFace, we can measure
        int wordWidth;
        if ((wordWidth = mWordWidth[i]) == 0) {
            float textWidth = paint.measureText(suggestion, 0, wordLength);
            // wordWidth = Math.max(0, (int) textWidth + X_GAP * 2);
            wordWidth = (int) (textWidth + mXGap * 2);
            mWordWidth[i] = wordWidth;
        }

        mWordX[i] = x;

        if (touchX != OUT_OF_BOUNDS_X_CORD && !scrolled && touchX + scrollX >= x
                && touchX + scrollX < x + wordWidth) {
            if (canvas != null && !mShowingAddToDictionary) {
                canvas.translate(x, 0);
                mSelectionHighlight.setBounds(0, bgPadding.top, wordWidth, height);
                mSelectionHighlight.draw(canvas);
                canvas.translate(-x, 0);
            }
            mSelectedString = suggestion;
            mSelectedIndex = i;
        }

        if (canvas != null) {
            // (+)This is the trick to get RTL/LTR text correct
            if (AnyApplication.getConfig().workaround_alwaysUseDrawText()) {
                final int y = (int) (height + paint.getTextSize() - paint.descent()) / 2;
                canvas.drawText(suggestion, 0, wordLength, x + wordWidth / 2, y, paint);
            } else {
                final int y = (int) (height - paint.getTextSize() + paint.descent()) / 2;
                // no matter what: StaticLayout
                float textX = x + (wordWidth / 2) - mXGap;
                float textY = y - bgPadding.bottom - bgPadding.top;

                canvas.translate(textX, textY);
                mTextPaint.setTypeface(paint.getTypeface());
                mTextPaint.setColor(paint.getColor());

                StaticLayout suggestionText = new StaticLayout(suggestion, mTextPaint, wordWidth,
                        Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
                suggestionText.draw(canvas);

                canvas.translate(-textX, -textY);
            }
            // (-)
            paint.setColor(mColorOther);
            canvas.translate(x + wordWidth, 0);
            // Draw a divider unless it's after the hint
            //or the last suggested word
            if (count > 1 && (!mShowingAddToDictionary) && i != (count - 1)) {
                canvas.translate(0, dividerYOffset);
                mDivider.draw(canvas);
                canvas.translate(0, -dividerYOffset);
            }
            canvas.translate(-x - wordWidth, 0);
        }
        paint.setTypeface(Typeface.DEFAULT);
        x += wordWidth;
    }
    mTotalWidth = x;
    if (mTargetScrollX != scrollX) {
        scrollToTarget();
    }
}

From source file:com.anysoftkeyboard.keyboards.views.CandidateView.java

/**
 * If the canvas is null, then only touch calculations are performed to pick
 * the target candidate.// w  ww . ja  va2 s.co m
 */
@Override
protected void onDraw(Canvas canvas) {
    if (canvas != null) {
        super.onDraw(canvas);
    }
    mTotalWidth = 0;

    final int height = getHeight();
    if (mBgPadding == null) {
        mBgPadding = new Rect(0, 0, 0, 0);
        if (getBackground() != null) {
            getBackground().getPadding(mBgPadding);
        }
        mDivider.setBounds(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight());
    }

    final int dividerYOffset = (height - mDivider.getMinimumHeight()) / 2;
    final int count = mSuggestions.size();
    final Rect bgPadding = mBgPadding;
    final Paint paint = mPaint;
    final int touchX = mTouchX;
    final int scrollX = getScrollX();
    final boolean scrolled = mScrolled;
    final boolean typedWordValid = mTypedWordValid;

    int x = 0;
    for (int i = 0; i < count; i++) {
        CharSequence suggestion = mSuggestions.get(i);
        if (suggestion == null)
            continue;
        final int wordLength = suggestion.length();

        paint.setColor(mColorNormal);
        if (mHaveMinimalSuggestion && ((i == 1 && !typedWordValid) || (i == 0 && typedWordValid))) {
            paint.setTypeface(Typeface.DEFAULT_BOLD);
            paint.setColor(mColorRecommended);
            // existsAutoCompletion = true;
        } else if (i != 0 || (wordLength == 1 && count > 1)) {
            // HACK: even if i == 0, we use mColorOther when this
            // suggestion's length is 1 and
            // there are multiple suggestions, such as the default
            // punctuation list.
            paint.setColor(mColorOther);
        }

        // now that we set the typeFace, we can measure
        int wordWidth;
        if ((wordWidth = mWordWidth[i]) == 0) {
            float textWidth = paint.measureText(suggestion, 0, wordLength);
            // wordWidth = Math.max(0, (int) textWidth + X_GAP * 2);
            wordWidth = (int) (textWidth + mHorizontalGap * 2);
            mWordWidth[i] = wordWidth;
        }

        mWordX[i] = x;

        if (touchX != OUT_OF_BOUNDS_X_CORD && !scrolled && touchX + scrollX >= x
                && touchX + scrollX < x + wordWidth) {
            if (canvas != null && !mShowingAddToDictionary) {
                canvas.translate(x, 0);
                mSelectionHighlight.setBounds(0, bgPadding.top, wordWidth, height);
                mSelectionHighlight.draw(canvas);
                canvas.translate(-x, 0);
            }
            mSelectedString = suggestion;
            mSelectedIndex = i;
        }

        if (canvas != null) {
            // (+)This is the trick to get RTL/LTR text correct
            if (AnyApplication.getConfig().workaround_alwaysUseDrawText()) {
                final int y = (int) (height + paint.getTextSize() - paint.descent()) / 2;
                canvas.drawText(suggestion, 0, wordLength, x + wordWidth / 2, y, paint);
            } else {
                final int y = (int) (height - paint.getTextSize() + paint.descent()) / 2;
                // no matter what: StaticLayout
                float textX = x + (wordWidth / 2) - mHorizontalGap;
                float textY = y - bgPadding.bottom - bgPadding.top;

                canvas.translate(textX, textY);
                mTextPaint.setTypeface(paint.getTypeface());
                mTextPaint.setColor(paint.getColor());

                StaticLayout suggestionText = new StaticLayout(suggestion, mTextPaint, wordWidth,
                        Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
                suggestionText.draw(canvas);

                canvas.translate(-textX, -textY);
            }
            // (-)
            paint.setColor(mColorOther);
            canvas.translate(x + wordWidth, 0);
            // Draw a divider unless it's after the hint
            //or the last suggested word
            if (count > 1 && (!mShowingAddToDictionary) && i != (count - 1)) {
                canvas.translate(0, dividerYOffset);
                mDivider.draw(canvas);
                canvas.translate(0, -dividerYOffset);
            }
            canvas.translate(-x - wordWidth, 0);
        }
        paint.setTypeface(Typeface.DEFAULT);
        x += wordWidth;
    }
    mTotalWidth = x;
    if (mTargetScrollX != scrollX) {
        scrollToTarget();
    }
}

From source file:com.yek.keyboard.keyboards.views.AnyKeyboardViewBase.java

@CallSuper
protected void onBufferDraw(Canvas canvas, final Paint paint) {
    if (mKeyboardChanged) {
        invalidateAllKeys();/*  w  w  w.  j av  a 2  s  . c  o m*/
        mKeyboardChanged = false;
    }

    canvas.getClipBounds(mDirtyRect);

    if (mKeyboard == null)
        return;

    final boolean drawKeyboardNameText = (mKeyboardNameTextSize > 1f)
            && AnyApplication.getConfig().getShowKeyboardNameText();

    final boolean drawHintText = (mHintTextSize > 1) && AnyApplication.getConfig().getShowHintTextOnKeys();

    final boolean useCustomKeyTextColor = false;
    // TODO: final boolean useCustomKeyTextColor =
    // AnyApplication.getConfig().getUseCustomTextColorOnKeys();
    final ColorStateList keyTextColor = useCustomKeyTextColor
            ? new ColorStateList(new int[][] { { 0 } }, new int[] { 0xFF6666FF })
            : mKeyTextColor;

    final boolean useCustomHintColor = drawHintText && false;
    // TODO: final boolean useCustomHintColor = drawHintText &&
    final ColorStateList hintColor = useCustomHintColor
            ? new ColorStateList(new int[][] { { 0 } }, new int[] { 0xFFFF6666 })
            : mHintTextColor;

    // allow preferences to override theme settings for hint text position
    final boolean useCustomHintAlign = drawHintText && AnyApplication.getConfig().getUseCustomHintAlign();
    final int hintAlign = useCustomHintAlign ? AnyApplication.getConfig().getCustomHintAlign()
            : mHintLabelAlign;
    final int hintVAlign = useCustomHintAlign ? AnyApplication.getConfig().getCustomHintVAlign()
            : mHintLabelVAlign;

    final Drawable keyBackground = mKeyBackground;
    final Rect clipRegion = mClipRegion;
    final int kbdPaddingLeft = getPaddingLeft();
    final int kbdPaddingTop = getPaddingTop();
    final Keyboard.Key[] keys = mKeys;
    final Keyboard.Key invalidKey = mInvalidatedKey;

    boolean drawSingleKey = false;
    if (invalidKey != null && canvas.getClipBounds(clipRegion)) {
        // TODO we should use Rect.inset and Rect.contains here.
        // Is clipRegion completely contained within the invalidated key?
        if (invalidKey.x + kbdPaddingLeft - 1 <= clipRegion.left
                && invalidKey.y + kbdPaddingTop - 1 <= clipRegion.top
                && invalidKey.x + invalidKey.width + kbdPaddingLeft + 1 >= clipRegion.right
                && invalidKey.y + invalidKey.height + kbdPaddingTop + 1 >= clipRegion.bottom) {
            drawSingleKey = true;
        }
    }

    for (Keyboard.Key keyBase : keys) {
        final AnyKeyboard.AnyKey key = (AnyKeyboard.AnyKey) keyBase;
        final boolean keyIsSpace = isSpaceKey(key);

        if (drawSingleKey && (invalidKey != key)) {
            continue;
        }
        if (!mDirtyRect.intersects(key.x + kbdPaddingLeft, key.y + kbdPaddingTop,
                key.x + key.width + kbdPaddingLeft, key.y + key.height + kbdPaddingTop)) {
            continue;
        }
        int[] drawableState = key.getCurrentDrawableState(mDrawableStatesProvider);

        if (keyIsSpace)
            paint.setColor(mKeyboardNameTextColor);
        else
            paint.setColor(keyTextColor.getColorForState(drawableState, 0xFF000000));
        keyBackground.setState(drawableState);

        // Switch the character to uppercase if shift is pressed
        CharSequence label = key.label == null ? null : adjustLabelToShiftState(key);

        final Rect bounds = keyBackground.getBounds();
        if ((key.width != bounds.right) || (key.height != bounds.bottom)) {
            keyBackground.setBounds(0, 0, key.width, key.height);
        }
        canvas.translate(key.x + kbdPaddingLeft, key.y + kbdPaddingTop);
        keyBackground.draw(canvas);

        if (TextUtils.isEmpty(label)) {
            Drawable iconToDraw = getIconToDrawForKey(key, false);
            if (iconToDraw != null/* && shouldDrawIcon */) {
                //http://developer.android.com/reference/android/graphics/drawable/Drawable.html#getCurrent()
                //http://stackoverflow.com/a/103600/1324235
                final boolean is9Patch = iconToDraw.getCurrent() instanceof NinePatchDrawable;

                // Special handing for the upper-right number hint icons
                final int drawableWidth;
                final int drawableHeight;
                final int drawableX;
                final int drawableY;

                drawableWidth = is9Patch ? key.width : iconToDraw.getIntrinsicWidth();
                drawableHeight = is9Patch ? key.height : iconToDraw.getIntrinsicHeight();
                drawableX = (key.width + mKeyBackgroundPadding.left - mKeyBackgroundPadding.right
                        - drawableWidth) / 2;
                drawableY = (key.height + mKeyBackgroundPadding.top - mKeyBackgroundPadding.bottom
                        - drawableHeight) / 2;

                canvas.translate(drawableX, drawableY);
                iconToDraw.setBounds(0, 0, drawableWidth, drawableHeight);
                iconToDraw.draw(canvas);
                canvas.translate(-drawableX, -drawableY);
                if (keyIsSpace && drawKeyboardNameText) {
                    // now a little hack, I'll set the label now, so it get
                    // drawn.
                    label = mKeyboardName;
                }
            } else {
                // ho... no icon.
                // I'll try to guess the text
                label = guessLabelForKey(key.getPrimaryCode());
            }
        }

        if (label != null) {
            // For characters, use large font. For labels like "Done", use
            // small font.
            final FontMetrics fm;
            if (keyIsSpace) {
                paint.setTextSize(mKeyboardNameTextSize);
                paint.setTypeface(Typeface.DEFAULT_BOLD);
                if (mKeyboardNameFM == null)
                    mKeyboardNameFM = paint.getFontMetrics();
                fm = mKeyboardNameFM;
            } else if (label.length() > 1 && key.getCodesCount() < 2) {
                setPaintForLabelText(paint);
                if (mLabelFM == null)
                    mLabelFM = paint.getFontMetrics();
                fm = mLabelFM;
            } else {
                setPaintToKeyText(paint);
                if (mTextFM == null)
                    mTextFM = paint.getFontMetrics();
                fm = mTextFM;
            }

            if (isLabelOfPictographic(label)) {
                paint.setTextSize(2f * paint.getTextSize());
            }

            final float labelHeight = -fm.top;
            // Draw a drop shadow for the text
            paint.setShadowLayer(mShadowRadius, mShadowOffsetX, mShadowOffsetY, mShadowColor);

            final float textWidth = adjustTextSizeForLabel(paint, label, key.width);

            // the center of the drawable space, which is value used
            // previously for vertically
            // positioning the key label
            final float centerY = mKeyBackgroundPadding.top
                    + ((key.height - mKeyBackgroundPadding.top - mKeyBackgroundPadding.bottom)
                            / (keyIsSpace ? 3 : 2));// the label on the space is a bit higher

            // the X coordinate for the center of the main label text is
            // unaffected by the hints
            final float textX = mKeyBackgroundPadding.left
                    + (key.width - mKeyBackgroundPadding.left - mKeyBackgroundPadding.right) / 2;
            final float textY;
            // Some devices (mostly pre-Honeycomb, have issues with RTL text
            // drawing.
            // Of course, there is no issue with a single character :)
            // so, we'll use the RTL secured drawing (via StaticLayout) for
            // labels.
            if (label.length() > 1 && !AnyApplication.getConfig().workaround_alwaysUseDrawText()) {
                // calculate Y coordinate of top of text based on center
                // location
                textY = centerY - ((labelHeight - paint.descent()) / 2);
                canvas.translate(textX, textY);
                // RTL fix. But it costs, let do it when in need (more than
                // 1 character)
                StaticLayout labelText = new StaticLayout(label, new TextPaint(paint), (int) textWidth,
                        Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
                labelText.draw(canvas);
            } else {
                // to get Y coordinate of baseline from center of text,
                // first add half the height (to get to
                // bottom of text), then subtract the part below the
                // baseline. Note that fm.top is negative.
                textY = centerY + ((labelHeight - paint.descent()) / 2);
                canvas.translate(textX, textY);
                canvas.drawText(label, 0, label.length(), 0, 0, paint);
            }
            canvas.translate(-textX, -textY);
            // (-)

            // Turn off drop shadow
            paint.setShadowLayer(0, 0, 0, 0);
        }

        if (drawHintText) {
            if ((key.popupCharacters != null && key.popupCharacters.length() > 0) || (key.popupResId != 0)
                    || (key.longPressCode != 0)) {
                Align oldAlign = paint.getTextAlign();

                String hintText = null;

                if (key.hintLabel != null && key.hintLabel.length() > 0) {
                    hintText = key.hintLabel.toString();
                    // it is the responsibility of the keyboard layout
                    // designer to ensure that they do
                    // not put too many characters in the hint label...
                } else if (key.longPressCode != 0) {
                    if (Character.isLetterOrDigit(key.longPressCode))
                        hintText = Character.toString((char) key.longPressCode);
                } else if (key.popupCharacters != null) {
                    final String hintString = key.popupCharacters.toString();
                    final int hintLength = hintString.length();
                    if (hintLength <= 3)
                        hintText = hintString;
                }

                // if hintText is still null, it means it didn't fit one of
                // the above
                // cases, so we should provide the hint using the default
                if (hintText == null) {
                    if (mHintOverflowLabel != null)
                        hintText = mHintOverflowLabel;
                    else {
                        // theme does not provide a defaultHintLabel
                        // use  if hints are above, ... if hints are
                        // below
                        // (to avoid being too close to main label/icon)
                        if (hintVAlign == Gravity.TOP)
                            hintText = "";
                        else
                            hintText = "...";
                    }
                }

                if (mKeyboard.isShifted())
                    hintText = hintText.toUpperCase(getKeyboard().getLocale());

                // now draw hint
                paint.setTypeface(Typeface.DEFAULT);
                paint.setColor(hintColor.getColorForState(drawableState, 0xFF000000));
                paint.setTextSize(mHintTextSize);
                // get the hint text font metrics so that we know the size
                // of the hint when
                // we try to position the main label (to try to make sure
                // they don't overlap)
                if (mHintTextFM == null) {
                    mHintTextFM = paint.getFontMetrics();
                }

                final float hintX;
                final float hintY;

                // the (float) 0.5 value is added or subtracted to just give
                // a little more room
                // in case the theme designer didn't account for the hint
                // label location
                if (hintAlign == Gravity.START) {
                    // left
                    paint.setTextAlign(Align.LEFT);
                    hintX = mKeyBackgroundPadding.left + 0.5f;
                } else if (hintAlign == Gravity.CENTER) {
                    // center
                    paint.setTextAlign(Align.CENTER);
                    hintX = mKeyBackgroundPadding.left
                            + (key.width - mKeyBackgroundPadding.left - mKeyBackgroundPadding.right) / 2;
                } else {
                    // right
                    paint.setTextAlign(Align.RIGHT);
                    hintX = key.width - mKeyBackgroundPadding.right - 0.5f;
                }

                if (hintVAlign == Gravity.TOP) {
                    // above
                    hintY = mKeyBackgroundPadding.top - mHintTextFM.top + 0.5f;
                } else {
                    // below
                    hintY = key.height - mKeyBackgroundPadding.bottom - mHintTextFM.bottom - 0.5f;
                }

                canvas.drawText(hintText, hintX, hintY, paint);
                paint.setTextAlign(oldAlign);
            }
        }

        canvas.translate(-key.x - kbdPaddingLeft, -key.y - kbdPaddingTop);
    }
    mInvalidatedKey = null;

    mDirtyRect.setEmpty();
}