Example usage for android.text StaticLayout StaticLayout

List of usage examples for android.text StaticLayout StaticLayout

Introduction

In this page you can find the example usage for android.text StaticLayout StaticLayout.

Prototype

@Deprecated
public StaticLayout(CharSequence source, TextPaint paint, int width, Alignment align, float spacingmult,
        float spacingadd, boolean includepad) 

Source Link

Usage

From source file:net.opacapp.multilinecollapsingtoolbar.CollapsingTextHelper.java

private void calculateUsingTextSize(final float textSize) {
    if (mText == null)
        return;/*from ww  w  . ja  va2 s. c o  m*/
    final float availableWidth;
    final float newTextSize;
    boolean updateDrawText = false;
    // BEGIN MODIFICATION: Add maxLines variable
    int maxLines;
    // END MODIFICATION
    if (isClose(textSize, mCollapsedTextSize)) {
        availableWidth = mCollapsedBounds.width();
        newTextSize = mCollapsedTextSize;
        mScale = 1f;
        if (mCurrentTypeface != mCollapsedTypeface) {
            mCurrentTypeface = mCollapsedTypeface;
            updateDrawText = true;
        }
        // BEGIN MODIFICATION: Set maxLines variable
        maxLines = 1;
        // END MODIFICATION
    } else {
        availableWidth = mExpandedBounds.width();
        newTextSize = mExpandedTextSize;
        if (mCurrentTypeface != mExpandedTypeface) {
            mCurrentTypeface = mExpandedTypeface;
            updateDrawText = true;
        }
        if (isClose(textSize, mExpandedTextSize)) {
            // If we're close to the expanded text size, snap to it and use a scale of 1
            mScale = 1f;
        } else {
            // Else, we'll scale down from the expanded text size
            mScale = textSize / mExpandedTextSize;
        }
        // BEGIN MODIFICATION: Set maxLines variable
        maxLines = this.maxLines;
        // END MODIFICATION
    }
    if (availableWidth > 0) {
        updateDrawText = (mCurrentTextSize != newTextSize) || mBoundsChanged || updateDrawText;
        mCurrentTextSize = newTextSize;
        mBoundsChanged = false;
    }
    if (mTextToDraw == null || updateDrawText) {
        mTextPaint.setTextSize(mCurrentTextSize);
        mTextPaint.setTypeface(mCurrentTypeface);

        // BEGIN MODIFICATION: Text layout creation and text truncation
        StaticLayout layout = new StaticLayout(mText, mTextPaint, (int) availableWidth,
                Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
        CharSequence truncatedText;
        if (layout.getLineCount() > maxLines) {
            int lastLine = maxLines - 1;
            CharSequence textBefore = lastLine > 0 ? mText.subSequence(0, layout.getLineEnd(lastLine - 1)) : "";
            CharSequence lineText = mText.subSequence(layout.getLineStart(lastLine),
                    layout.getLineEnd(lastLine));
            // if last char in line is space, move it behind the ellipsis
            CharSequence lineEnd = "";
            if (lineText.charAt(lineText.length() - 1) == ' ') {
                lineEnd = lineText.subSequence(lineText.length() - 1, lineText.length());
                lineText = lineText.subSequence(0, lineText.length() - 1);
            }
            // insert ellipsis character
            lineText = TextUtils.concat(lineText, "\u2026", lineEnd);
            // if the text is too long, truncate it
            CharSequence truncatedLineText = TextUtils.ellipsize(lineText, mTextPaint, availableWidth,
                    TextUtils.TruncateAt.END);
            truncatedText = TextUtils.concat(textBefore, truncatedLineText);

        } else {
            truncatedText = mText;
        }
        if (!TextUtils.equals(truncatedText, mTextToDraw)) {
            mTextToDraw = truncatedText;
            mIsRtl = calculateIsRtl(mTextToDraw);
        }

        final Layout.Alignment alignment;

        // Don't rectify gravity for RTL languages, Layout.Alignment does it already.
        switch (mExpandedTextGravity & GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK) {
        case Gravity.CENTER_HORIZONTAL:
            alignment = Layout.Alignment.ALIGN_CENTER;
            break;
        case Gravity.RIGHT:
        case Gravity.END:
            alignment = Layout.Alignment.ALIGN_OPPOSITE;
            break;
        case Gravity.LEFT:
        case Gravity.START:
        default:
            alignment = Layout.Alignment.ALIGN_NORMAL;
            break;
        }

        mTextLayout = new StaticLayout(mTextToDraw, mTextPaint, (int) availableWidth, alignment, 1, 0, false);
        // END MODIFICATION
    }
}

From source file:org.telegram.ui.Cells.DialogCell.java

public void buildLayout() {
    String nameString = "";
    String timeString = "";
    String countString = null;/*from   ww w  .  j a  v  a  2  s  .com*/
    CharSequence messageString = "";
    CharSequence printingString = null;
    if (isDialogCell) {
        printingString = MessagesController.getInstance().printingStrings.get(currentDialogId);
    }
    TextPaint currentNamePaint = namePaint;
    TextPaint currentMessagePaint = messagePaint;
    boolean checkMessage = true;

    drawNameGroup = false;
    drawNameBroadcast = false;
    drawNameLock = false;
    drawNameBot = false;
    drawVerified = false;

    if (encryptedChat != null) {
        drawNameLock = true;
        nameLockTop = AndroidUtilities.dp(16.5f);
        if (!LocaleController.isRTL) {
            nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
            nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4)
                    + lockDrawable.getIntrinsicWidth();
        } else {
            nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline)
                    - lockDrawable.getIntrinsicWidth();
            nameLeft = AndroidUtilities.dp(14);
        }
    } else {
        if (chat != null) {
            if (chat.id < 0 || ChatObject.isChannel(chat) && !chat.megagroup) {
                drawNameBroadcast = true;
                nameLockTop = AndroidUtilities.dp(16.5f);
            } else {
                drawNameGroup = true;
                nameLockTop = AndroidUtilities.dp(17.5f);
            }
            drawVerified = chat.verified;

            if (!LocaleController.isRTL) {
                nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
                nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4)
                        + (drawNameGroup ? groupDrawable.getIntrinsicWidth()
                                : broadcastDrawable.getIntrinsicWidth());
            } else {
                nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline)
                        - (drawNameGroup ? groupDrawable.getIntrinsicWidth()
                                : broadcastDrawable.getIntrinsicWidth());
                nameLeft = AndroidUtilities.dp(14);
            }
        } else {
            if (!LocaleController.isRTL) {
                nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
            } else {
                nameLeft = AndroidUtilities.dp(14);
            }
            if (user != null) {
                if (user.bot) {
                    drawNameBot = true;
                    nameLockTop = AndroidUtilities.dp(16.5f);
                    if (!LocaleController.isRTL) {
                        nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
                        nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4)
                                + botDrawable.getIntrinsicWidth();
                    } else {
                        nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline)
                                - botDrawable.getIntrinsicWidth();
                        nameLeft = AndroidUtilities.dp(14);
                    }
                }
                drawVerified = user.verified;
            }
        }
    }

    int lastDate = lastMessageDate;
    if (lastMessageDate == 0 && message != null) {
        lastDate = message.messageOwner.date;
    }

    if (isDialogCell) {
        draftMessage = DraftQuery.getDraft(currentDialogId);
        if (draftMessage != null
                && (TextUtils.isEmpty(draftMessage.message) && draftMessage.reply_to_msg_id == 0
                        || lastDate > draftMessage.date && unreadCount != 0)
                || ChatObject.isChannel(chat) && !chat.megagroup && !chat.creator && !chat.editor
                || chat != null && (chat.left || chat.kicked)) {
            draftMessage = null;
        }
    } else {
        draftMessage = null;
    }

    if (printingString != null) {
        lastPrintString = messageString = printingString;
        currentMessagePaint = messagePrintingPaint;
    } else {
        lastPrintString = null;

        if (draftMessage != null) {
            checkMessage = false;
            if (TextUtils.isEmpty(draftMessage.message)) {
                String draftString = LocaleController.getString("Draft", R.string.Draft);
                SpannableStringBuilder stringBuilder = SpannableStringBuilder.valueOf(draftString);
                stringBuilder.setSpan(new ForegroundColorSpan(Theme.DIALOGS_DRAFT_TEXT_COLOR), 0,
                        draftString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                messageString = stringBuilder;
            } else {
                String mess = draftMessage.message;
                if (mess.length() > 150) {
                    mess = mess.substring(0, 150);
                }
                String draftString = LocaleController.getString("Draft", R.string.Draft);
                SpannableStringBuilder stringBuilder = SpannableStringBuilder
                        .valueOf(String.format("%s: %s", draftString, mess.replace('\n', ' ')));
                stringBuilder.setSpan(new ForegroundColorSpan(Theme.DIALOGS_DRAFT_TEXT_COLOR), 0,
                        draftString.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                messageString = Emoji.replaceEmoji(stringBuilder, messagePaint.getFontMetricsInt(),
                        AndroidUtilities.dp(20), false);
            }
        } else {
            if (message == null) {
                if (encryptedChat != null) {
                    currentMessagePaint = messagePrintingPaint;
                    if (encryptedChat instanceof TLRPC.TL_encryptedChatRequested) {
                        messageString = LocaleController.getString("EncryptionProcessing",
                                R.string.EncryptionProcessing);
                    } else if (encryptedChat instanceof TLRPC.TL_encryptedChatWaiting) {
                        if (user != null && user.first_name != null) {
                            messageString = LocaleController.formatString("AwaitingEncryption",
                                    R.string.AwaitingEncryption, user.first_name);
                        } else {
                            messageString = LocaleController.formatString("AwaitingEncryption",
                                    R.string.AwaitingEncryption, "");
                        }
                    } else if (encryptedChat instanceof TLRPC.TL_encryptedChatDiscarded) {
                        messageString = LocaleController.getString("EncryptionRejected",
                                R.string.EncryptionRejected);
                    } else if (encryptedChat instanceof TLRPC.TL_encryptedChat) {
                        if (encryptedChat.admin_id == UserConfig.getClientUserId()) {
                            if (user != null && user.first_name != null) {
                                messageString = LocaleController.formatString("EncryptedChatStartedOutgoing",
                                        R.string.EncryptedChatStartedOutgoing, user.first_name);
                            } else {
                                messageString = LocaleController.formatString("EncryptedChatStartedOutgoing",
                                        R.string.EncryptedChatStartedOutgoing, "");
                            }
                        } else {
                            messageString = LocaleController.getString("EncryptedChatStartedIncoming",
                                    R.string.EncryptedChatStartedIncoming);
                        }
                    }
                }
            } else {
                TLRPC.User fromUser = null;
                TLRPC.Chat fromChat = null;
                if (message.isFromUser()) {
                    fromUser = MessagesController.getInstance().getUser(message.messageOwner.from_id);
                } else {
                    fromChat = MessagesController.getInstance().getChat(message.messageOwner.to_id.channel_id);
                }
                if (message.messageOwner instanceof TLRPC.TL_messageService) {
                    messageString = message.messageText;
                    currentMessagePaint = messagePrintingPaint;
                } else {
                    if (chat != null && chat.id > 0 && fromChat == null) {
                        String name;
                        if (message.isOutOwner()) {
                            name = LocaleController.getString("FromYou", R.string.FromYou);
                        } else if (fromUser != null) {
                            name = UserObject.getFirstName(fromUser).replace("\n", "");
                        } else if (fromChat != null) {
                            name = fromChat.title.replace("\n", "");
                        } else {
                            name = "DELETED";
                        }
                        checkMessage = false;
                        SpannableStringBuilder stringBuilder;
                        if (message.caption != null) {
                            String mess = message.caption.toString();
                            if (mess.length() > 150) {
                                mess = mess.substring(0, 150);
                            }
                            stringBuilder = SpannableStringBuilder
                                    .valueOf(String.format("%s: %s", name, mess.replace('\n', ' ')));
                        } else if (message.messageOwner.media != null && !message.isMediaEmpty()) {
                            currentMessagePaint = messagePrintingPaint;
                            if (message.messageOwner.media instanceof TLRPC.TL_messageMediaGame) {
                                stringBuilder = SpannableStringBuilder.valueOf(String.format("%s: %s", name,
                                        "\uD83C\uDFAE " + message.messageOwner.media.game.title));
                            } else {
                                stringBuilder = SpannableStringBuilder
                                        .valueOf(String.format("%s: %s", name, message.messageText));
                            }
                            stringBuilder.setSpan(new ForegroundColorSpan(Theme.DIALOGS_ATTACH_TEXT_COLOR),
                                    name.length() + 2, stringBuilder.length(),
                                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                        } else if (message.messageOwner.message != null) {
                            String mess = message.messageOwner.message;
                            if (mess.length() > 150) {
                                mess = mess.substring(0, 150);
                            }
                            stringBuilder = SpannableStringBuilder
                                    .valueOf(String.format("%s: %s", name, mess.replace('\n', ' ')));
                        } else {
                            stringBuilder = SpannableStringBuilder.valueOf("");
                        }
                        if (stringBuilder.length() > 0) {
                            stringBuilder.setSpan(new ForegroundColorSpan(Theme.DIALOGS_NAME_TEXT_COLOR), 0,
                                    name.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                        }
                        messageString = Emoji.replaceEmoji(stringBuilder, messagePaint.getFontMetricsInt(),
                                AndroidUtilities.dp(20), false);
                    } else {
                        if (message.caption != null) {
                            messageString = message.caption;
                        } else {
                            if (message.messageOwner.media instanceof TLRPC.TL_messageMediaGame) {
                                messageString = "\uD83C\uDFAE " + message.messageOwner.media.game.title;
                            } else {
                                messageString = message.messageText;
                            }
                            if (message.messageOwner.media != null && !message.isMediaEmpty()) {
                                currentMessagePaint = messagePrintingPaint;
                            }
                        }
                    }
                }
            }
        }
    }

    if (draftMessage != null) {
        timeString = LocaleController.stringForMessageListDate(draftMessage.date);
    } else if (lastMessageDate != 0) {
        timeString = LocaleController.stringForMessageListDate(lastMessageDate);
    } else if (message != null) {
        timeString = LocaleController.stringForMessageListDate(message.messageOwner.date);
    }

    if (message == null) {
        drawCheck1 = false;
        drawCheck2 = false;
        drawClock = false;
        drawCount = false;
        drawError = false;
    } else {
        if (unreadCount != 0) {
            drawCount = true;
            countString = String.format("%d", unreadCount);
        } else {
            drawCount = false;
        }

        if (message.isOut() && draftMessage == null) {
            if (message.isSending()) {
                drawCheck1 = false;
                drawCheck2 = false;
                drawClock = true;
                drawError = false;
            } else if (message.isSendError()) {
                drawCheck1 = false;
                drawCheck2 = false;
                drawClock = false;
                drawError = true;
                drawCount = false;
            } else if (message.isSent()) {
                drawCheck1 = !message.isUnread() || ChatObject.isChannel(chat) && !chat.megagroup;
                drawCheck2 = true;
                drawClock = false;
                drawError = false;
            }
        } else {
            drawCheck1 = false;
            drawCheck2 = false;
            drawClock = false;
            drawError = false;
        }
    }

    int timeWidth = (int) Math.ceil(timePaint.measureText(timeString));
    timeLayout = new StaticLayout(timeString, timePaint, timeWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f,
            false);
    if (!LocaleController.isRTL) {
        timeLeft = getMeasuredWidth() - AndroidUtilities.dp(15) - timeWidth;
    } else {
        timeLeft = AndroidUtilities.dp(15);
    }

    if (chat != null) {
        nameString = chat.title;
    } else if (user != null) {
        if (user.id == UserConfig.getClientUserId()) {
            nameString = LocaleController.getString("ChatYourSelfName", R.string.ChatYourSelfName);
        } else if (user.id / 1000 != 777 && user.id / 1000 != 333
                && ContactsController.getInstance().contactsDict.get(user.id) == null) {
            if (ContactsController.getInstance().contactsDict.size() == 0
                    && (!ContactsController.getInstance().contactsLoaded
                            || ContactsController.getInstance().isLoadingContacts())) {
                nameString = UserObject.getUserName(user);
            } else {
                if (user.phone != null && user.phone.length() != 0) {
                    nameString = PhoneFormat.getInstance().format("+" + user.phone);
                } else {
                    nameString = UserObject.getUserName(user);
                }
            }
        } else {
            nameString = UserObject.getUserName(user);
        }
        if (encryptedChat != null) {
            currentNamePaint = nameEncryptedPaint;
        }
    }
    if (nameString.length() == 0) {
        nameString = LocaleController.getString("HiddenName", R.string.HiddenName);
    }

    int nameWidth;

    if (!LocaleController.isRTL) {
        nameWidth = getMeasuredWidth() - nameLeft - AndroidUtilities.dp(14) - timeWidth;
    } else {
        nameWidth = getMeasuredWidth() - nameLeft - AndroidUtilities.dp(AndroidUtilities.leftBaseline)
                - timeWidth;
        nameLeft += timeWidth;
    }
    if (drawNameLock) {
        nameWidth -= AndroidUtilities.dp(4) + lockDrawable.getIntrinsicWidth();
    } else if (drawNameGroup) {
        nameWidth -= AndroidUtilities.dp(4) + groupDrawable.getIntrinsicWidth();
    } else if (drawNameBroadcast) {
        nameWidth -= AndroidUtilities.dp(4) + broadcastDrawable.getIntrinsicWidth();
    } else if (drawNameBot) {
        nameWidth -= AndroidUtilities.dp(4) + botDrawable.getIntrinsicWidth();
    }
    if (drawClock) {
        int w = clockDrawable.getIntrinsicWidth() + AndroidUtilities.dp(5);
        nameWidth -= w;
        if (!LocaleController.isRTL) {
            checkDrawLeft = timeLeft - w;
        } else {
            checkDrawLeft = timeLeft + timeWidth + AndroidUtilities.dp(5);
            nameLeft += w;
        }
    } else if (drawCheck2) {
        int w = checkDrawable.getIntrinsicWidth() + AndroidUtilities.dp(5);
        nameWidth -= w;
        if (drawCheck1) {
            nameWidth -= halfCheckDrawable.getIntrinsicWidth() - AndroidUtilities.dp(8);
            if (!LocaleController.isRTL) {
                halfCheckDrawLeft = timeLeft - w;
                checkDrawLeft = halfCheckDrawLeft - AndroidUtilities.dp(5.5f);
            } else {
                checkDrawLeft = timeLeft + timeWidth + AndroidUtilities.dp(5);
                halfCheckDrawLeft = checkDrawLeft + AndroidUtilities.dp(5.5f);
                nameLeft += w + halfCheckDrawable.getIntrinsicWidth() - AndroidUtilities.dp(8);
            }
        } else {
            if (!LocaleController.isRTL) {
                checkDrawLeft = timeLeft - w;
            } else {
                checkDrawLeft = timeLeft + timeWidth + AndroidUtilities.dp(5);
                nameLeft += w;
            }
        }
    }

    if (dialogMuted && !drawVerified) {
        int w = AndroidUtilities.dp(6) + muteDrawable.getIntrinsicWidth();
        nameWidth -= w;
        if (LocaleController.isRTL) {
            nameLeft += w;
        }
    } else if (drawVerified) {
        int w = AndroidUtilities.dp(6) + verifiedDrawable.getIntrinsicWidth();
        nameWidth -= w;
        if (LocaleController.isRTL) {
            nameLeft += w;
        }
    }

    nameWidth = Math.max(AndroidUtilities.dp(12), nameWidth);
    try {
        CharSequence nameStringFinal = TextUtils.ellipsize(nameString.replace('\n', ' '), currentNamePaint,
                nameWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
        nameLayout = new StaticLayout(nameStringFinal, currentNamePaint, nameWidth,
                Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
    } catch (Exception e) {
        FileLog.e("tmessages", e);
    }

    int messageWidth = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline + 16);
    int avatarLeft;
    if (!LocaleController.isRTL) {
        messageLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
        avatarLeft = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 13 : 9);
    } else {
        messageLeft = AndroidUtilities.dp(16);
        avatarLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 65 : 61);
    }
    avatarImage.setImageCoords(avatarLeft, avatarTop, AndroidUtilities.dp(52), AndroidUtilities.dp(52));
    if (drawError) {
        int w = errorDrawable.getIntrinsicWidth() + AndroidUtilities.dp(8);
        messageWidth -= w;
        if (!LocaleController.isRTL) {
            errorLeft = getMeasuredWidth() - errorDrawable.getIntrinsicWidth() - AndroidUtilities.dp(11);
        } else {
            errorLeft = AndroidUtilities.dp(11);
            messageLeft += w;
        }
    } else if (countString != null) {
        countWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(countPaint.measureText(countString)));
        countLayout = new StaticLayout(countString, countPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f,
                0.0f, false);
        int w = countWidth + AndroidUtilities.dp(18);
        messageWidth -= w;
        if (!LocaleController.isRTL) {
            countLeft = getMeasuredWidth() - countWidth - AndroidUtilities.dp(19);
        } else {
            countLeft = AndroidUtilities.dp(19);
            messageLeft += w;
        }
        drawCount = true;
    } else {
        drawCount = false;
    }

    if (checkMessage) {
        if (messageString == null) {
            messageString = "";
        }
        String mess = messageString.toString();
        if (mess.length() > 150) {
            mess = mess.substring(0, 150);
        }
        mess = mess.replace('\n', ' ');
        messageString = Emoji.replaceEmoji(mess, messagePaint.getFontMetricsInt(), AndroidUtilities.dp(17),
                false);
    }
    messageWidth = Math.max(AndroidUtilities.dp(12), messageWidth);
    CharSequence messageStringFinal = TextUtils.ellipsize(messageString, currentMessagePaint,
            messageWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
    try {
        messageLayout = new StaticLayout(messageStringFinal, currentMessagePaint, messageWidth,
                Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
    } catch (Exception e) {
        FileLog.e("tmessages", e);
    }

    double widthpx;
    float left;
    if (LocaleController.isRTL) {
        if (nameLayout != null && nameLayout.getLineCount() > 0) {
            left = nameLayout.getLineLeft(0);
            widthpx = Math.ceil(nameLayout.getLineWidth(0));
            if (dialogMuted && !drawVerified) {
                nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - AndroidUtilities.dp(6)
                        - muteDrawable.getIntrinsicWidth());
            } else if (drawVerified) {
                nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - AndroidUtilities.dp(6)
                        - verifiedDrawable.getIntrinsicWidth());
            }
            if (left == 0) {
                if (widthpx < nameWidth) {
                    nameLeft += (nameWidth - widthpx);
                }
            }
        }
        if (messageLayout != null && messageLayout.getLineCount() > 0) {
            left = messageLayout.getLineLeft(0);
            if (left == 0) {
                widthpx = Math.ceil(messageLayout.getLineWidth(0));
                if (widthpx < messageWidth) {
                    messageLeft += (messageWidth - widthpx);
                }
            }
        }
    } else {
        if (nameLayout != null && nameLayout.getLineCount() > 0) {
            left = nameLayout.getLineRight(0);
            if (left == nameWidth) {
                widthpx = Math.ceil(nameLayout.getLineWidth(0));
                if (widthpx < nameWidth) {
                    nameLeft -= (nameWidth - widthpx);
                }
            }
            if (dialogMuted || drawVerified) {
                nameMuteLeft = (int) (nameLeft + left + AndroidUtilities.dp(6));
            }
        }
        if (messageLayout != null && messageLayout.getLineCount() > 0) {
            left = messageLayout.getLineRight(0);
            if (left == messageWidth) {
                widthpx = Math.ceil(messageLayout.getLineWidth(0));
                if (widthpx < messageWidth) {
                    messageLeft -= (messageWidth - widthpx);
                }
            }
        }
    }
}

From source file:com.mixiaoxiao.support.widget.SmoothSwitch.java

private Layout makeLayout(CharSequence text) {
    final CharSequence transformed = (mSwitchTransformationMethod != null)
            ? mSwitchTransformationMethod.getTransformation(text, this)
            : text;//  ww  w .jav a  2  s .  c  om

    return new StaticLayout(transformed, mTextPaint,
            (int) Math.ceil(Layout.getDesiredWidth(transformed, mTextPaint)), Layout.Alignment.ALIGN_NORMAL,
            1.f, 0, true);
}

From source file:com.mjhram.geodata.GpsMainActivity.java

public Bitmap drawMultilineTextToBitmap(Context gContext, Bitmap bitmap, String gText) {
    // prepare canvas
    Resources resources = gContext.getResources();
    float scale = resources.getDisplayMetrics().density;
    //Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId);

    android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
    // set default bitmap config if none
    if (bitmapConfig == null) {
        bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
    }//w w w.j av a  2  s.co m
    // resource bitmaps are imutable,
    // so we need to convert it to mutable one
    bitmap = bitmap.copy(bitmapConfig, true);

    Canvas canvas = new Canvas(bitmap);

    // new antialiased Paint
    TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
    // text color - #3D3D3D
    paint.setColor(Color.rgb(61, 61, 61));
    // text size in pixels
    paint.setTextSize((int) (20 * scale));
    // text shadow
    paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
    //canvas.drawText("This is", 100, 100, paint);
    //canvas.drawText("multi-line", 100, 150, paint);
    //canvas.drawText("text", 100, 200, paint);

    // set text width to canvas width minus 16dp padding
    int textWidth = canvas.getWidth() - (int) (16 * scale);

    // init StaticLayout for text
    StaticLayout textLayout = new StaticLayout(gText, paint, textWidth, Layout.Alignment.ALIGN_CENTER, 1.0f,
            0.0f, false);

    // get height of multiline text
    int textHeight = textLayout.getHeight();

    // get position of text's top left corner
    float x = (bitmap.getWidth() - textWidth) / 2;
    float y = bitmap.getHeight() - textHeight;

    // draw text to the Canvas center
    canvas.save();
    canvas.translate(x, y);
    textLayout.draw(canvas);
    canvas.restore();

    return bitmap;
}

From source file:android.support.v7.widget.AppCompatTextViewAutoSizeHelper.java

@TargetApi(14)
private StaticLayout createStaticLayoutForMeasuringPre23(CharSequence text, Layout.Alignment alignment,
        int availableWidth) {
    // Setup defaults.
    float lineSpacingMultiplier = 1.0f;
    float lineSpacingAdd = 0.0f;
    boolean includePad = true;

    if (Build.VERSION.SDK_INT >= 16) {
        // Call public methods.
        lineSpacingMultiplier = mTextView.getLineSpacingMultiplier();
        lineSpacingAdd = mTextView.getLineSpacingExtra();
        includePad = mTextView.getIncludeFontPadding();
    } else {/* w w w. jav a2s .  c o  m*/
        // Call private methods and make sure to provide fallback defaults in case something
        // goes wrong. The default values have been inlined with the StaticLayout defaults.
        lineSpacingMultiplier = invokeAndReturnWithDefault(mTextView, "getLineSpacingMultiplier",
                lineSpacingMultiplier);
        lineSpacingAdd = invokeAndReturnWithDefault(mTextView, "getLineSpacingExtra", lineSpacingAdd);
        includePad = invokeAndReturnWithDefault(mTextView, "getIncludeFontPadding", includePad);
    }

    // The layout could not be constructed using the builder so fall back to the
    // most broad constructor.
    return new StaticLayout(text, mTempTextPaint, availableWidth, alignment, lineSpacingMultiplier,
            lineSpacingAdd, includePad);
}

From source file:com.android.mail.browse.ConversationItemView.java

private void calculateCoordinates() {
    startTimer(PERF_TAG_CALCULATE_COORDINATES);

    sPaint.setTextSize(mCoordinates.dateFontSize);
    sPaint.setTypeface(Typeface.DEFAULT);

    final boolean isRtl = ViewUtils.isViewRtl(this);

    mDateWidth = (int) sPaint.measureText(mHeader.dateText != null ? mHeader.dateText.toString() : "");
    if (mHeader.infoIcon != null) {
        mInfoIconX = (isRtl) ? mCoordinates.infoIconX
                : mCoordinates.infoIconXRight - mHeader.infoIcon.getWidth();

        // If we have an info icon, we start drawing the date text:
        // At the end of the date TextView minus the width of the date text
        // In RTL mode, we just use dateX
        mDateX = (isRtl) ? mCoordinates.dateX : mCoordinates.dateXRight - mDateWidth;
    } else {/* w  w  w  .  j a v a2  s  . c o m*/
        // If there is no info icon, we start drawing the date text:
        // At the end of the info icon ImageView minus the width of the date text
        // We use the info icon ImageView for positioning, since we want the date text to be
        // at the right, since there is no info icon
        // In RTL, we just use infoIconX
        mDateX = (isRtl) ? mCoordinates.infoIconX : mCoordinates.infoIconXRight - mDateWidth;
    }

    // The paperclip is drawn starting at the start of the date text minus
    // the width of the paperclip and the date padding.
    // In RTL mode, it is at the end of the date (mDateX + mDateWidth) plus the
    // start date padding.
    mPaperclipX = (isRtl) ? mDateX + mDateWidth + mCoordinates.datePaddingStart
            : mDateX - ATTACHMENT.getWidth() - mCoordinates.datePaddingStart;

    // In normal mode, the senders x and width is based
    // on where the date/attachment icon start.
    final int dateAttachmentStart;
    // Have this end near the paperclip or date, not the folders.
    if (mHeader.paperclip != null) {
        // If there is a paperclip, the date/attachment start is at the start
        // of the paperclip minus the paperclip padding.
        // In RTL, it is at the end of the paperclip plus the paperclip padding.
        dateAttachmentStart = (isRtl) ? mPaperclipX + ATTACHMENT.getWidth() + mCoordinates.paperclipPaddingStart
                : mPaperclipX - mCoordinates.paperclipPaddingStart;
    } else {
        // If no paperclip, just use the start of the date minus the date padding start.
        // In RTL mode, this is just the paperclipX.
        dateAttachmentStart = (isRtl) ? mPaperclipX : mDateX - mCoordinates.datePaddingStart;
    }
    // Senders width is the dateAttachmentStart - sendersX.
    // In RTL, it is sendersWidth + sendersX - dateAttachmentStart.
    mSendersWidth = (isRtl) ? mCoordinates.sendersWidth + mCoordinates.sendersX - dateAttachmentStart
            : dateAttachmentStart - mCoordinates.sendersX;
    mSendersX = (isRtl) ? dateAttachmentStart : mCoordinates.sendersX;

    // Second pass to layout each fragment.
    sPaint.setTextSize(mCoordinates.sendersFontSize);
    sPaint.setTypeface(Typeface.DEFAULT);

    // First pass to calculate width of each fragment.
    if (mSendersWidth < 0) {
        mSendersWidth = 0;
    }

    // sendersDisplayText is only set when preserveSendersText is true.
    if (mHeader.preserveSendersText) {
        mHeader.sendersDisplayLayout = new StaticLayout(mHeader.sendersDisplayText, sPaint, mSendersWidth,
                Alignment.ALIGN_NORMAL, 1, 0, true);
    } else {
        final SpannableStringBuilder participantText = elideParticipants(mHeader.styledNames);
        layoutParticipantText(participantText);
    }

    pauseTimer(PERF_TAG_CALCULATE_COORDINATES);
}

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

@CallSuper
protected void onBufferDraw(Canvas canvas, final Paint paint) {
    if (mKeyboardChanged) {
        invalidateAllKeys();//from   w  w  w  .  ja va  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();
}

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

@CallSuper
protected void onBufferDraw(Canvas canvas, final Paint paint) {
    if (mKeyboardChanged) {
        invalidateAllKeys();//from   w  ww. ja  v  a2s .c  om
        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 Key[] keys = mKeys;
    final 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 (Key keyBase : keys) {
        final AnyKey key = (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 (mKeyboardNameFontMetrics == null)
                    mKeyboardNameFontMetrics = paint.getFontMetrics();
                fm = mKeyboardNameFontMetrics;
            } else if (label.length() > 1 && key.getCodesCount() < 2) {
                setPaintForLabelText(paint);
                if (mLabelFontMetrics == null)
                    mLabelFontMetrics = paint.getFontMetrics();
                fm = mLabelFontMetrics;
            } else {
                setPaintToKeyText(paint);
                if (mTextFontMetrics == null)
                    mTextFontMetrics = paint.getFontMetrics();
                fm = mTextFontMetrics;
            }

            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 (mHintTextFontMetrics == null) {
                    mHintTextFontMetrics = 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 - mHintTextFontMetrics.top + 0.5f;
                } else {
                    // below
                    hintY = key.height - mKeyBackgroundPadding.bottom - mHintTextFontMetrics.bottom - 0.5f;
                }

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

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

    mDirtyRect.setEmpty();
}

From source file:org.telegram.ui.ArticleViewer.java

private StaticLayout createLayoutForText(CharSequence plainText, TLRPC.RichText richText, int width,
        TLRPC.PageBlock parentBlock) {//w  w  w  .j a va  2 s  .com
    if (plainText == null && (richText == null || richText instanceof TLRPC.TL_textEmpty)) {
        return null;
    }

    if (quoteLinePaint == null) {
        quoteLinePaint = new Paint();
        quoteLinePaint.setColor(0xff000000);

        preformattedBackgroundPaint = new Paint();
        preformattedBackgroundPaint.setColor(0xfff5f8fc);

        urlPaint = new Paint();
        urlPaint.setColor(0x3362a9e3);
    }

    CharSequence text;
    if (plainText != null) {
        text = plainText;
    } else {
        text = getText(richText, richText, parentBlock);
    }
    if (TextUtils.isEmpty(text)) {
        return null;
    }
    TextPaint paint;
    if (parentBlock instanceof TLRPC.TL_pageBlockEmbedPost && richText == null) {
        if (parentBlock.author == plainText) {
            if (embedPostAuthorPaint == null) {
                embedPostAuthorPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
                embedPostAuthorPaint.setColor(0xff000000);
            }
            embedPostAuthorPaint.setTextSize(AndroidUtilities.dp(15));
            paint = embedPostAuthorPaint;
        } else {
            if (embedPostDatePaint == null) {
                embedPostDatePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
                embedPostDatePaint.setColor(0xff8f97a0);
            }
            embedPostDatePaint.setTextSize(AndroidUtilities.dp(14));
            paint = embedPostDatePaint;
        }
    } else {
        paint = getTextPaint(richText, richText, parentBlock);
    }
    if (parentBlock instanceof TLRPC.TL_pageBlockPullquote) {
        return new StaticLayout(text, paint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
    } else {
        return new StaticLayout(text, paint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, AndroidUtilities.dp(4),
                false);
    }
}

From source file:com.tct.mail.browse.ConversationItemView.java

private void calculateCoordinates() {
    startTimer(PERF_TAG_CALCULATE_COORDINATES);

    sPaint.setTextSize(mCoordinates.dateFontSize);
    sPaint.setTypeface(Typeface.DEFAULT);

    final boolean isRtl = ViewUtils.isViewRtl(this);

    mDateWidth = (int) sPaint.measureText(mHeader.dateText != null ? mHeader.dateText.toString() : "");
    if (mHeader.infoIcon != null) {
        mInfoIconX = (isRtl) ? mCoordinates.infoIconX
                : mCoordinates.infoIconXRight - mHeader.infoIcon.getWidth();

        // If we have an info icon, we start drawing the date text:
        // At the end of the date TextView minus the width of the date text
        // In RTL mode, we just use dateX
        mDateX = (isRtl) ? mCoordinates.dateX : mCoordinates.dateXRight - mDateWidth;
    } else {/*from w  ww .j a v  a  2  s .  com*/
        // If there is no info icon, we start drawing the date text:
        // At the end of the info icon ImageView minus the width of the date text
        // We use the info icon ImageView for positioning, since we want the date text to be
        // at the right, since there is no info icon
        // In RTL, we just use infoIconX
        mDateX = (isRtl) ? mCoordinates.infoIconX : mCoordinates.infoIconXRight - mDateWidth;
    }

    // TS: zhaotianyong 2014-12-15 EMAIL BUGFIX_859814 MOD_S
    // The paperclip is drawn starting at the start of the date text minus
    // the width of the paperclip and the date padding.
    // In RTL mode, it is at the end of the date (mDateX + mDateWidth) plus the
    // start date padding.
    mPaperclipX = (isRtl) ? mDateX + mDateWidth + mCoordinates.datePaddingStart
            : mDateX - ATTACHMENT.getWidth() - mCoordinates.datePaddingStart;

    //TS: junwei-xu 2015-06-01 EMAIL BUGFIX_989906 MOD_S
    Bitmap priorityBitmap = sNormalPriorityIcon;
    mPriority = mHeader.conversation.flagPriority;
    if (mPriority == HIGH_PRIORITY) {
        priorityBitmap = sHighPriorityIcon;
    } else if (mPriority == LOW_PRIORITY) {
        priorityBitmap = sLowPriorityIcon;
    }
    //[FEATURE]-Add-BEGIN by TSCD.chao zhang,04/17/2014,FR 631895(porting from FR514398)
    /*
    if (mHeader.paperclip != null) {
    mPriorityX = mPaperclipX - priorityBitmap.getWidth();
    } else {
    mPriorityX = mDateX - priorityBitmap.getWidth();
    }
    */
    if (mHeader.paperclip != null) {
        mPriorityX = (isRtl) ? mPaperclipX + ATTACHMENT.getWidth() + mCoordinates.paperclipPaddingStart
                : mPaperclipX - priorityBitmap.getWidth();
    } else {
        mPriorityX = (isRtl) ? mDateX + mDateWidth + mCoordinates.datePaddingStart
                : mDateX - priorityBitmap.getWidth();
    }
    //[FEATURE]-Add-END by TSCD.chao zhang
    //TS: junwei-xu 2015-06-01 EMAIL BUGFIX_989906 MOD_E
    // TS: zhaotianyong 2014-12-15 EMAIL BUGFIX_859814 MOD_E

    // In normal mode, the senders x and width is based
    // on where the date/attachment icon start.

    // Have this end near the paperclip or date, not the folders.

    //TS: junwei-xu 2015-06-01 EMAIL BUGFIX_989906 MOD_S
    if (mHeader.paperclip != null) {
        // If there is a paperclip, the date/attachment start is at the start
        // of the paperclip minus the paperclip padding.
        // In RTL, it is at the end of the paperclip plus the paperclip padding.
        dateAttachmentStart = (isRtl)
                ? mPaperclipX + ATTACHMENT.getWidth() + mCoordinates.paperclipPaddingStart
                        + priorityBitmap.getWidth()
                : mPaperclipX - mCoordinates.paperclipPaddingStart;
    } else {
        // If no paperclip, just use the start of the date minus the date padding start.
        // In RTL mode, this is just the paperclipX.
        dateAttachmentStart = (isRtl) ? mPaperclipX + priorityBitmap.getWidth()
                : mDateX - mCoordinates.datePaddingStart;
    }
    //TS: yanhua.chen 2015-9-2 EMAIL CR_540046 MOD_S
    // TS: chao.zhang 2015-09-14 EMAIL FEATURE-585337 ADD_S
    // NOTE:use measureText to get the status's length. and we only want draw the status textView when in OUTBOX
    // that in other box,user can see more subject.
    int statusWdithWithPanding = 0;
    if (mDisplayedFolder != null && mDisplayedFolder.isOutbox()) {
        String status = mHeader.conversation.getMaxLengthStatusDisplay(mContext);
        mStatusWidth = (int) mStatusTextView.getPaint().measureText(status);
        statusWdithWithPanding = mStatusWidth + mCoordinates.statusPaddingStart
                + mCoordinates.statusPanddingEnd;
    }
    // TS: chao.zhang 2015-09-14 EMAIL FEATURE-585337 ADD_E
    // Subject width is the dateAttachmentStart - subjectX.
    // In RTL, it is subjectWidth + subjectX - dateAttachmentStart.
    mSubjectWidth = (isRtl) ? mCoordinates.subjectWidth + mCoordinates.subjectX - dateAttachmentStart
            : mPriorityX - mCoordinates.subjectX - statusWdithWithPanding;
    mSubjectX = (isRtl) ? dateAttachmentStart : mCoordinates.subjectX;
    //TS: junwei-xu 2015-06-01 EMAIL BUGFIX_989906 MOD_E

    // Second pass to layout each fragment.
    sPaint.setTextSize(mCoordinates.subjectFontSize);
    sPaint.setTypeface(Typeface.DEFAULT);

    if (mHeader.styledNames != null) {
        final SpannableStringBuilder participantText = elideParticipants(mHeader.styledNames);
        layoutParticipantText(participantText);
    } else {
        // First pass to calculate width of each fragment.
        if (mSubjectWidth < 0) {
            mSubjectWidth = 0;
        }

        mHeader.subjectDisplayLayout = new StaticLayout(mHeader.subjectDisplayText, sPaint, mSubjectWidth,
                Alignment.ALIGN_NORMAL, 1, 0, true);
    }

    if (mSubjectWidth < 0) {
        mSubjectWidth = 0;
    }
    //TS: yanhua.chen 2015-9-2 EMAIL CR_540046 MOD_E
    // TS: chao.zhang 2015-09-14 EMAIL FEATURE-585337 ADD_S
    //NOTE: currently,use calculateStatus after subject created.
    //calculateStatus(isRtl);
    // TS: chao.zhang 2015-09-14 EMAIL FEATURE-585337 ADD_E
    pauseTimer(PERF_TAG_CALCULATE_COORDINATES);
}