public void expand(boolean animate) { if (!truncated) { return; } truncated = false; if (!animate) { requestLayout(); return; } ResizeAnimation expandAnimation = new ResizeAnimation(getHeight() + expandedLayout.getHeight() - truncatedLayout.getHeight()); expandAnimation.setDuration(400); expandAnimation.setAnimationListener( new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { animating = true; } @Override public void onAnimationEnd(Animation animation) { animating = false; } @Override public void onAnimationRepeat(Animation animation) {} }); startAnimation(expandAnimation); }
@Override public void onDraw(Canvas canvas) { // Log.d("TFV", "Font metrics float: "+paint.getFontMetrics(null) * textLines.length +" font // metrics int: "+paint.getFontMetricsInt(null)*textLines.length+" layout height: // "+layout.getHeight()+" layout line bottom: "+layout.getLineBottom(layout.getLineCount() - // 1)+" pad top: "+layout.getTopPadding()+" pad bottom: "+layout.getBottomPadding()+" attempt: // "+(paint.getFontMetricsInt(null)*textLines.length - layout.getTopPadding() + // layout.getBottomPadding())); // canvas.drawColor(backgroundColor); // wipe canvas (just in case)-- doesn't seem necessary but // try this in case of bugs! // Just in case (do not remove!): if (layout == null) updateLayout(); // Calculate new height offset for vertical text centering -- want to start drawing text at // (container height - text height) /2 = (container height - (text box height - (negative // padding)) / 2 = (container height - text box height + negative padding) / 2 float heightOffset = 0.5f * (this.getHeight() - layout.getHeight() + layout.getTopPadding() /* this is negative! */); // Shift canvas downwards and rightwards so that the text will be vertically and horizontally // centred: canvas.translate(this.getPaddingLeft(), heightOffset); // Draw text on shifted canvas: layout.draw(canvas); // Undo translate: canvas.restore(); }
protected void drawCenterText(Canvas c) { SpannableString centerText = mChart.getCenterText(); if (mChart.isDrawCenterTextEnabled() && centerText != null) { PointF center = mChart.getCenterCircleBox(); float innerRadius = mChart.isDrawHoleEnabled() && mChart.isHoleTransparent() ? mChart.getRadius() * (mChart.getHoleRadius() / 100f) : mChart.getRadius(); RectF holeRect = mRectBuffer[0]; holeRect.left = center.x - innerRadius; holeRect.top = center.y - innerRadius; holeRect.right = center.x + innerRadius; holeRect.bottom = center.y + innerRadius; RectF boundingRect = mRectBuffer[1]; boundingRect.set(holeRect); float radiusPercent = mChart.getCenterTextRadiusPercent(); if (radiusPercent > 0.0) { boundingRect.inset( (boundingRect.width() - boundingRect.width() * radiusPercent) / 2.f, (boundingRect.height() - boundingRect.height() * radiusPercent) / 2.f); } if (!centerText.equals(mCenterTextLastValue) || !boundingRect.equals(mCenterTextLastBounds)) { // Next time we won't recalculate StaticLayout... mCenterTextLastBounds.set(boundingRect); mCenterTextLastValue = centerText; float width = mCenterTextLastBounds.width(); // If width is 0, it will crash. Always have a minimum of 1 mCenterTextLayout = new StaticLayout( centerText, 0, centerText.length(), mCenterTextPaint, (int) Math.max(Math.ceil(width), 1.f), Layout.Alignment.ALIGN_CENTER, 1.f, 0.f, false); } float layoutHeight = mCenterTextLayout.getHeight(); c.save(); c.translate( boundingRect.left, boundingRect.top + (boundingRect.height() - layoutHeight) / 2.f); mCenterTextLayout.draw(c); c.restore(); } }
/** @param popupText the popupText to set */ public void setText(String text) { if (text == null) this.text = ""; else this.text = text; layout = new StaticLayout(this.text, tp, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1f, 0f, true); this.width = layout.getWidth(); this.height = layout.getHeight(); }
// Set the text size of the text paint object and use a static layout to render text off screen // before measuring private int getTextHeight(CharSequence source, TextPaint paint, int width, float textSize) { // Update the text paint object paint.setTextSize(textSize); // Measure using a static layout StaticLayout layout = new StaticLayout( source, paint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true); return layout.getHeight(); }
// Set the text size of the text paint object and use a static layout to render text off screen // before measuring private int getTextHeight(CharSequence source, TextPaint paint, int width, float textSize) { // modified: make a copy of the original TextPaint object for measuring // (apparently the object gets modified while measuring, see also the // docs for TextView.getPaint() (which states to access it read-only) TextPaint paintCopy = new TextPaint(paint); // Update the text paint object paintCopy.setTextSize(textSize); // Measure using a static layout StaticLayout layout = new StaticLayout( source, paintCopy, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true); return layout.getHeight(); }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public int onTestSize(int suggestedSize, RectF availableSPace) { mPaint.setTextSize(suggestedSize); String text = getText().toString(); boolean singleline = getMaxLines() == 1; if (singleline) { mTextRect.bottom = mPaint.getFontSpacing(); mTextRect.right = mPaint.measureText(text); } else { StaticLayout layout = new StaticLayout( text, mPaint, mWidthLimit, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true); // return early if we have more lines if (getMaxLines() != NO_LINE_LIMIT && layout.getLineCount() > getMaxLines()) { return 1; } mTextRect.bottom = layout.getHeight(); int maxWidth = -1; for (int i = 0; i < layout.getLineCount(); i++) { if (maxWidth < layout.getLineWidth(i)) { maxWidth = (int) layout.getLineWidth(i); } } mTextRect.right = maxWidth; } mTextRect.offsetTo(0, 0); if (availableSPace.contains(mTextRect)) { // may be too small, don't worry we will find the best match return -1; } else { // too big return 1; } }
public void setText(String text) { if (text == null || text.length() == 0) { setVisibility(GONE); return; } if (text != null && oldText != null && text.equals(oldText)) { return; } oldText = text; setVisibility(VISIBLE); if (AndroidUtilities.isTablet()) { width = (int) (AndroidUtilities.getMinTabletSide() * 0.7f); } else { width = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.7f); } SpannableStringBuilder stringBuilder = new SpannableStringBuilder(); String help = LocaleController.getString("BotInfoTitle", R.string.BotInfoTitle); stringBuilder.append(help); stringBuilder.append("\n\n"); stringBuilder.append(text); MessageObject.addLinks(stringBuilder); stringBuilder.setSpan( new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), 0, help.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textLayout = new StaticLayout( stringBuilder, textPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); width = 0; height = textLayout.getHeight() + AndroidUtilities.dp(4 + 18); int count = textLayout.getLineCount(); for (int a = 0; a < count; a++) { width = (int) Math.ceil(Math.max(width, textLayout.getLineWidth(a) - textLayout.getLineLeft(a))); } width += AndroidUtilities.dp(4 + 18); }
private void renderBottomLabel( Canvas canvas, RadRect dataPointSlot, String labelText, StaticLayout textBounds) { RectF labelBounds = new RectF(); double height = textBounds.getHeight() + this.labelPadding * 2; double top = dataPointSlot.getBottom() + this.labelMargin; labelBounds.set( (float) dataPointSlot.x, (float) top, (float) dataPointSlot.getRight(), (float) (top + height)); canvas.drawRect( labelBounds.left, labelBounds.top, labelBounds.right, labelBounds.bottom, this.lowFill); canvas.drawRect( labelBounds.left, labelBounds.top, labelBounds.right, labelBounds.bottom, this.stroke); canvas.drawText( labelText, (float) (dataPointSlot.x + (dataPointSlot.width / 2.0) - textBounds.getLineWidth(0) / 2.0f), labelBounds.centerY() + textBounds.getLineBottom(0) - textBounds.getLineBaseline(0), paint); }
static Bitmap smartLines( Context context, Bitmap icon, String header, String[] lines, FontCache.FontSize size) { Properties props = BitmapCache.getProperties(context, "notification.xml"); final int textTop = Integer.parseInt(props.getProperty("textTop", "24")); final int textLeft = Integer.parseInt(props.getProperty("textLeft", "3")); final int textWidth = Integer.parseInt(props.getProperty("textWidth", "90")); final int textHeight = Integer.parseInt(props.getProperty("textHeight", "69")); final int iconTop = Integer.parseInt(props.getProperty("iconTop", "0")); final int iconLeft = Integer.parseInt(props.getProperty("iconLeft", "0")); final int headerLeft = Integer.parseInt(props.getProperty("headerLeft", "20")); final int headerBaseline = Integer.parseInt(props.getProperty("headerBaseline", "15")); final int headerColor = props.getProperty("headerColor", "white").equalsIgnoreCase("black") ? Color.BLACK : Color.WHITE; final int textColor = props.getProperty("textColor", "black").equalsIgnoreCase("black") ? Color.BLACK : Color.WHITE; FontInfo font = FontCache.instance(context).Get(size); Bitmap bitmap = Bitmap.createBitmap(96, 96, Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); Paint paintHead = new Paint(); paintHead.setColor(headerColor); paintHead.setTextSize(FontCache.instance(context).Large.size); paintHead.setTypeface(FontCache.instance(context).Large.face); Paint paint = new Paint(); paint.setColor(textColor); paint.setTextSize(font.size); paint.setTypeface(font.face); canvas.drawColor(Color.WHITE); canvas.drawBitmap(Utils.getBitmap(context, "notify_background.png"), 0, 0, null); int iconHeight = 16; if (icon != null) { iconHeight = Math.max(16, icon.getHeight()); // make sure the text fits // align icon to bottom of text canvas.drawBitmap(icon, iconLeft, iconTop + iconHeight - icon.getHeight(), paint); } canvas.drawText(header, headerLeft, headerBaseline, paintHead); String body = ""; for (String line : lines) { if (body.length() > 0) body += "\n\n"; body += line; } TextPaint textPaint = new TextPaint(paint); StaticLayout staticLayout = new StaticLayout( body, textPaint, textWidth, android.text.Layout.Alignment.ALIGN_CENTER, 1.3f, 0, false); int layoutHeight = staticLayout.getHeight(); int textY = textTop + (textHeight / 2) - (layoutHeight / 2); if (textY < textTop) textY = textTop; canvas.translate(textLeft, textY); // position the text staticLayout.draw(canvas); return bitmap; }
/** * draws the description text in the center of the pie chart makes most sense when center-hole is * enabled */ protected void drawCenterText(Canvas c) { CharSequence centerText = mChart.getCenterText(); if (mChart.isDrawCenterTextEnabled() && centerText != null) { PointF center = mChart.getCenterCircleBox(); float innerRadius = mChart.isDrawHoleEnabled() ? mChart.getRadius() * (mChart.getHoleRadius() / 100f) : mChart.getRadius(); RectF holeRect = mRectBuffer[0]; holeRect.left = center.x - innerRadius; holeRect.top = center.y - innerRadius; holeRect.right = center.x + innerRadius; holeRect.bottom = center.y + innerRadius; RectF boundingRect = mRectBuffer[1]; boundingRect.set(holeRect); float radiusPercent = mChart.getCenterTextRadiusPercent() / 100f; if (radiusPercent > 0.0) { boundingRect.inset( (boundingRect.width() - boundingRect.width() * radiusPercent) / 2.f, (boundingRect.height() - boundingRect.height() * radiusPercent) / 2.f); } if (!centerText.equals(mCenterTextLastValue) || !boundingRect.equals(mCenterTextLastBounds)) { // Next time we won't recalculate StaticLayout... mCenterTextLastBounds.set(boundingRect); mCenterTextLastValue = centerText; float width = mCenterTextLastBounds.width(); // If width is 0, it will crash. Always have a minimum of 1 mCenterTextLayout = new StaticLayout( centerText, 0, centerText.length(), mCenterTextPaint, (int) Math.max(Math.ceil(width), 1.f), Layout.Alignment.ALIGN_CENTER, 1.f, 0.f, false); } // I wish we could make an ellipse clipping path on Android to clip to the hole... // If we ever find out how, this is the place to add it, based on holeRect // float layoutWidth = Utils.getStaticLayoutMaxWidth(mCenterTextLayout); float layoutHeight = mCenterTextLayout.getHeight(); c.save(); c.translate( boundingRect.left, boundingRect.top + (boundingRect.height() - layoutHeight) / 2.f); mCenterTextLayout.draw(c); c.restore(); // } // // else { // // // // get all lines from the text // String[] lines = centerText.toString().split("\n"); // // float maxlineheight = 0f; // // // calc the maximum line height // for (String line : lines) { // float curHeight = Utils.calcTextHeight(mCenterTextPaint, line); // if (curHeight > maxlineheight) // maxlineheight = curHeight; // } // // float linespacing = maxlineheight * 0.25f; // // float totalheight = maxlineheight * lines.length - linespacing * // (lines.length - 1); // // int cnt = lines.length; // // float y = center.y; // // for (int i = 0; i < lines.length; i++) { // // String line = lines[lines.length - i - 1]; // // // // c.drawText(line, center.x, y // + maxlineheight * cnt - totalheight / 2f, // mCenterTextPaint); // cnt--; // y -= linespacing; // } // } } }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { measureWidth(widthMeasureSpec); this.imgSize = (int) ((JokerView.windowH / 5) * 0.6); this.rightBorder = (int) (JokerView.windowH / 5); int TextWidth = this.width - this.imgSize - this.rightBorder; Rect bounds = new Rect(); LayoutTextPaint = new TextPaint(); LayoutTextPaint.setTextSize((float) (UI_Size_Base.that.getScaledFontSize() * 1.3)); LayoutTextPaint.getTextBounds("T", 0, 1, bounds); LineSep = bounds.height() / 3; LayoutTextPaint.setAntiAlias(true); LayoutTextPaint.setColor(Global.getColor(R.attr.TextColor)); if (joker.Tage == -1) // this Joker is Owner { LayoutTage = new StaticLayout( "Owner von diesem Cache", LayoutTextPaint, TextWidth, Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); } else { LayoutTage = new StaticLayout( "gefunden vor " + String.valueOf(joker.Tage) + " Tagen", LayoutTextPaint, TextWidth, Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); } LayoutTelefon = new StaticLayout( "Tel: " + joker.Telefon, LayoutTextPaint, TextWidth, Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); LayoutBemerkung = new StaticLayout( "Bem.:" + joker.Bemerkung, LayoutTextPaint, TextWidth, Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); LayoutTextPaintBold = new TextPaint(LayoutTextPaint); LayoutTextPaintBold.setFakeBoldText(true); LayoutName = new StaticLayout( joker.GCLogin + " (" + joker.Vorname + ", " + joker.Name + ")", LayoutTextPaintBold, TextWidth, Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); this.height = (LineSep * 5) + LayoutTage.getHeight() + LayoutTelefon.getHeight() + LayoutBemerkung.getHeight() + LayoutName.getHeight(); setMeasuredDimension(this.width, this.height); }
public Bitmap update(Context context, boolean preview, int watchType) { TextPaint paintSmall = new TextPaint(); paintSmall.setColor(Color.BLACK); paintSmall.setTextSize(FontCache.instance(context).Small.size); paintSmall.setTypeface(FontCache.instance(context).Small.face); TextPaint paintSmallOutline = new TextPaint(); paintSmallOutline.setColor(Color.WHITE); paintSmallOutline.setTextSize(FontCache.instance(context).Small.size); paintSmallOutline.setTypeface(FontCache.instance(context).Small.face); TextPaint paintLarge = new TextPaint(); paintLarge.setColor(Color.BLACK); paintLarge.setTextSize(FontCache.instance(context).Large.size); paintLarge.setTypeface(FontCache.instance(context).Large.face); TextPaint paintLargeOutline = new TextPaint(); paintLargeOutline.setColor(Color.WHITE); paintLargeOutline.setTextSize(FontCache.instance(context).Large.size); paintLargeOutline.setTypeface(FontCache.instance(context).Large.face); MediaControl.TrackInfo lastTrack = MediaControl.getLastTrack(); if (watchType == WatchType.DIGITAL) { Bitmap bitmap = Bitmap.createBitmap(96, 96, Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); canvas.drawColor(Color.WHITE); if (lastTrack.isEmpty()) { canvas.drawBitmap(Utils.getBitmap(context, "media_player_idle.png"), 0, 0, null); } else { canvas.drawBitmap(Utils.getBitmap(context, "media_player.png"), 0, 0, null); StringBuilder lowerText = new StringBuilder(); if (!lastTrack.artist.equals("")) { lowerText.append(lastTrack.artist); } if (!lastTrack.album.equals("")) { if (lowerText.length() > 0) lowerText.append("\n\n"); lowerText.append(lastTrack.album); } Utils.autoText( context, canvas, lastTrack.track, 0, 8, 96, 35, Layout.Alignment.ALIGN_CENTER, Color.BLACK); Utils.autoText( context, canvas, lowerText.toString(), 0, 54, 96, 35, Layout.Alignment.ALIGN_CENTER, Color.BLACK); } drawDigitalAppSwitchIcon(context, canvas, preview); return bitmap; } else if (watchType == WatchType.ANALOG) { Bitmap bitmap = Bitmap.createBitmap(80, 32, Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); canvas.drawColor(Color.WHITE); if (lastTrack.isEmpty()) { canvas.drawBitmap(Utils.getBitmap(context, "media_player_idle_oled.png"), 0, 0, null); } else { canvas.drawBitmap(Utils.getBitmap(context, "media_player_oled.png"), 0, 0, null); TextPaint tp = null; if (paintLarge.measureText(lastTrack.track) < 75) { tp = paintLarge; } else { tp = paintSmall; } canvas.save(); StaticLayout layout = new StaticLayout( lastTrack.track, tp, 75, Layout.Alignment.ALIGN_CENTER, 1.2f, 0, false); int height = layout.getHeight(); int textY = 8 - (height / 2); if (textY < 0) { textY = 0; } canvas.translate(0, textY); // position the text canvas.clipRect(0, 0, 75, 16); layout.draw(canvas); canvas.restore(); canvas.save(); StringBuilder lowerText = new StringBuilder(); if (!lastTrack.artist.equals("")) { lowerText.append(lastTrack.artist); } if (!lastTrack.album.equals("")) { if (lowerText.length() > 0) lowerText.append("\n\n"); lowerText.append(lastTrack.album); } if (paintLarge.measureText(lowerText.toString()) < 75) { tp = paintLarge; } else { tp = paintSmall; } layout = new StaticLayout( lowerText.toString(), tp, 75, Layout.Alignment.ALIGN_CENTER, 1.0f, 0, false); height = layout.getHeight(); textY = 24 - (height / 2); if (textY < 16) { textY = 16; } canvas.translate(0, textY); // position the text canvas.clipRect(0, 0, 75, 16); layout.draw(canvas); canvas.restore(); } return bitmap; } return null; }
public void build(MessageWireframe wireframe, int desiredWidth, StelsApplication application) { Logger.d(TAG, "Build layout start"); checkResources(application); senderPaint = initTextPaint(); senderPaint.setTypeface(FontController.loadTypeface(application, "regular")); senderPaint.setTextSize(bodyPaint.getTextSize()); senderPaint.setColor(0xff000000); forwardingPaint = initTextPaint(); forwardingPaint.setTypeface(FontController.loadTypeface(application, "light")); forwardingPaint.setTextSize(bodyPaint.getTextSize()); forwardingPaint.setColor(0xff000000); this.layoutDesiredWidth = desiredWidth; this.isOut = wireframe.message.isOut(); this.showState = isOut; this.isGroup = wireframe.message.getPeerType() == PeerType.PEER_CHAT && !isOut; if (isGroup) { User user = wireframe.senderUser; this.senderName = user.getDisplayName(); if (!wireframe.message.isForwarded()) { senderPaint.setColor( Placeholders.USER_PLACEHOLDERS_COLOR[ wireframe.message.getSenderId() % Placeholders.USER_PLACEHOLDERS_COLOR.length]); forwardingPaint.setColor( Placeholders.USER_PLACEHOLDERS_COLOR[ wireframe.message.getSenderId() % Placeholders.USER_PLACEHOLDERS_COLOR.length]); } } if (wireframe.message.isForwarded()) { isForwarded = true; this.forwarderName = wireframe.forwardUser.getDisplayName(); if (isOut) { forwardingPaint.setColor(0xff739f53); senderPaint.setColor(0xff739f53); } else { forwardingPaint.setColor(0xff4884cf); senderPaint.setColor(0xff4884cf); } } else { isForwarded = false; } if (isGroup) { User user = application.getEngine().getUser(wireframe.message.getSenderId()); this.senderName = user.getDisplayName(); } if (wireframe.message.isForwarded()) { isForwarded = true; this.forwarderName = wireframe.forwardUser.getDisplayName(); } else { isForwarded = false; } layoutDesiredWidth = desiredWidth; long start = SystemClock.uptimeMillis(); this.spannable = application .getEmojiProcessor() .processEmojiCompatMutable( wireframe.message.getMessage(), EmojiProcessor.CONFIGURATION_BUBBLES); // spannable = new SpannableString(wireframe.message.getMessage()); Logger.d(TAG, "Emoji processed in " + (SystemClock.uptimeMillis() - start) + " ms"); start = SystemClock.uptimeMillis(); Linkify.addLinks( this.spannable, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS | Linkify.EMAIL_ADDRESSES); fixLinks(spannable); Logger.d(TAG, "Added links in " + (SystemClock.uptimeMillis() - start) + " ms"); start = SystemClock.uptimeMillis(); layout = new StaticLayout( spannable, bodyPaint, desiredWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true); Logger.d(TAG, "Built base layout in " + (SystemClock.uptimeMillis() - start) + " ms"); if (layout.getLineCount() < 20) { int layoutTextWidth = 0; for (int i = 0; i < layout.getLineCount(); i++) { layoutTextWidth = (int) Math.max(layout.getLineWidth(i), layoutTextWidth); } if (layoutTextWidth < layout.getWidth() - px(10)) { layout = new StaticLayout( spannable, bodyPaint, layoutTextWidth + px(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true); } } layoutRealWidth = layout.getWidth(); timeWidth = (int) clockOutPaint.measureText(wireframe.date) + px((showState ? 23 : 0) + 6); if (layout.getLineCount() == 1) { boolean isLastRtl = layout.getParagraphDirection(0) == Layout.DIR_RIGHT_TO_LEFT; if (!isLastRtl && desiredWidth - layoutRealWidth > timeWidth) { layoutRealWidth += timeWidth; layoutHeight = layout.getHeight() + px(3); } else if (isLastRtl && desiredWidth - layout.getWidth() > timeWidth) { layoutRealWidth = layout.getWidth() + timeWidth; layoutHeight = layout.getHeight() + px(3); } else { if (isLastRtl) { layoutRealWidth = layout.getWidth(); } layoutHeight = layout.getHeight() + px(17); } } else { boolean isLastRtl = layout.getParagraphDirection(layout.getLineCount() - 1) == Layout.DIR_RIGHT_TO_LEFT; if (!isLastRtl && (desiredWidth - layout.getLineWidth(layout.getLineCount() - 1) > timeWidth)) { layoutRealWidth = (int) Math.max( layoutRealWidth, layout.getLineWidth(layout.getLineCount() - 1) + timeWidth); layoutHeight = layout.getHeight() + px(3); } else if (isLastRtl && (desiredWidth - layout.getWidth() > timeWidth)) { layoutRealWidth = (int) Math.max(layoutRealWidth, layout.getWidth() + timeWidth); layoutHeight = layout.getHeight() + px(3); } else { layoutHeight = layout.getHeight() + px(17); } } if (layoutRealWidth < timeWidth) { layoutRealWidth = timeWidth; } if (isForwarded) { layoutHeight += px(19) * 2; forwardOffset = (int) forwardingPaintBase.measureText("From "); layoutRealWidth = (int) Math.max(layoutRealWidth, forwardingPaintBase.measureText("Forwarded message")); forwarderNameMeasured = TextUtils.ellipsize( forwarderName, senderPaintBase, desiredWidth - forwardOffset, TextUtils.TruncateAt.END) .toString(); layoutRealWidth = (int) Math.max( layoutRealWidth, forwardOffset + senderPaintBase.measureText(forwarderNameMeasured)); } if (isGroup && !isOut && !isForwarded) { layoutHeight += px(19); senderNameMeasured = TextUtils.ellipsize(senderName, senderPaintBase, desiredWidth, TextUtils.TruncateAt.END) .toString(); int width = (int) senderPaintBase.measureText(senderNameMeasured); layoutRealWidth = Math.max(layoutRealWidth, width); } Logger.d(TAG, "Build layout end"); }
static Bitmap[] smartNotify(Context context, Bitmap icon, String header, String body) { Properties props = BitmapCache.getProperties(context, "notification_sticky.xml"); final int textTop = Integer.parseInt(props.getProperty("textTop", "24")); final int textLeft = Integer.parseInt(props.getProperty("textLeft", "3")); final int textWidth = Integer.parseInt(props.getProperty("textWidth", "85")); final int textHeight = Integer.parseInt(props.getProperty("textHeight", "69")); final int iconTop = Integer.parseInt(props.getProperty("iconTop", "0")); final int iconLeft = Integer.parseInt(props.getProperty("iconLeft", "0")); final int headerLeft = Integer.parseInt(props.getProperty("headerLeft", "20")); final int headerBaseline = Integer.parseInt(props.getProperty("headerBaseline", "15")); final int headerColor = props.getProperty("headerColor", "white").equalsIgnoreCase("black") ? Color.BLACK : Color.WHITE; final int textColor = props.getProperty("textColor", "black").equalsIgnoreCase("black") ? Color.BLACK : Color.WHITE; final int arrowUpLeft = Integer.parseInt(props.getProperty("arrowUpLeft", "91")); final int arrowUpTop = Integer.parseInt(props.getProperty("arrowUpTop", "23")); final int arrowDownLeft = Integer.parseInt(props.getProperty("arrowDownLeft", "91")); final int arrowDownTop = Integer.parseInt(props.getProperty("arrowDownTop", "56")); final int closeLeft = Integer.parseInt(props.getProperty("closeLeft", "91")); final int closeTop = Integer.parseInt(props.getProperty("closeTop", "89")); FontInfo font = FontCache.instance(context).Get(); List<Bitmap> bitmaps = new ArrayList<Bitmap>(); Paint paintHead = new Paint(); paintHead.setColor(headerColor); paintHead.setTextSize(FontCache.instance(context).Large.size); paintHead.setTypeface(FontCache.instance(context).Large.face); Paint paint = new Paint(); paint.setColor(textColor); paint.setTextSize(font.size); paint.setTypeface(font.face); Paint whitePaint = new Paint(); whitePaint.setColor(Color.WHITE); TextPaint textPaint = new TextPaint(paint); StaticLayout staticLayout = new StaticLayout( body, textPaint, textWidth, android.text.Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false); int iconHeight = 16; int iconOffset = 0; if (icon != null) { iconHeight = Math.max(16, icon.getHeight()); iconOffset = iconHeight - icon.getHeight(); // align icon to bottom of text } int h = staticLayout.getHeight(); int y = 0; int displayHeight = textHeight + 3; int scroll = textHeight - font.size; boolean more = true; int pages = 0; while (more) { more = false; Bitmap bitmap = Bitmap.createBitmap(96, 96, Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); canvas.drawColor(Color.WHITE); canvas.drawBitmap(Utils.getBitmap(context, "notify_background_sticky.png"), 0, 0, null); canvas.save(); canvas.translate(textLeft, textTop - y); // position the text canvas.clipRect(0, y, textWidth, textHeight + y); staticLayout.draw(canvas); canvas.restore(); // Draw header if (icon != null) canvas.drawBitmap(icon, iconLeft, iconOffset + iconTop, paint); canvas.drawText(header, headerLeft, headerBaseline, paintHead); if (y > 0) canvas.drawBitmap(Utils.getBitmap(context, "arrow_up.bmp"), arrowUpLeft, arrowUpTop, null); if ((h - y) > (displayHeight) && pages < 10) { more = true; pages++; canvas.drawBitmap( Utils.getBitmap(context, "arrow_down.bmp"), arrowDownLeft, arrowDownTop, null); } canvas.drawBitmap(Utils.getBitmap(context, "close.bmp"), closeLeft, closeTop, null); y += scroll; bitmaps.add(bitmap); } Bitmap[] bitmapArray = new Bitmap[bitmaps.size()]; bitmaps.toArray(bitmapArray); return bitmapArray; }
private InternalWidget.WidgetData GenWidget(String widget_id) { InternalWidget.WidgetData widget = new InternalWidget.WidgetData(); widget.priority = meetingTime.equals("None") ? 0 : 1; String iconFile = "idle_calendar.bmp"; if (widget_id.equals(id_0)) { widget.id = id_0; widget.description = desc_0; widget.width = 24; widget.height = 32; } else if (widget_id.equals(id_1)) { widget.id = id_1; widget.description = desc_1; widget.width = 96; widget.height = 32; } else if (widget_id.equals(id_2)) { widget.id = id_2; widget.description = desc_2; widget.width = 16; widget.height = 16; iconFile = "idle_calendar_10.bmp"; } else if (widget_id.equals(id_3)) { widget.id = id_3; widget.description = desc_3; widget.width = 80; widget.height = 16; iconFile = "idle_calendar_10.bmp"; } else if (widget_id.equals(id_4)) { widget.id = id_4; widget.description = desc_4; widget.width = 48; widget.height = 32; iconFile = null; } else if (widget_id.equals(id_5)) { widget.id = id_5; widget.description = desc_5; widget.width = 40; widget.height = 16; iconFile = null; } Bitmap icon = iconFile == null ? null : Utils.getBitmap(context, iconFile); widget.bitmap = Bitmap.createBitmap(widget.width, widget.height, Bitmap.Config.RGB_565); Canvas canvas = new Canvas(widget.bitmap); canvas.drawColor(Color.WHITE); if (widget.height == 16 && icon != null) { if (icon != null) canvas.drawBitmap(icon, widget.width == 16 ? 2 : 0, 0, null); if (meetingTime.equals("None")) canvas.drawText("-", widget.width == 16 ? 8 : 6, 15, paintSmallNumerals); else { // Strip out colon to make it fit; String time = meetingTime.replace(":", ""); if (widget.width == 16) { canvas.drawText(time, 8, 15, paintSmallNumerals); } else { paintSmallNumerals.setTextAlign(Align.LEFT); canvas.drawText(time, 0, 15, paintSmallNumerals); paintSmallNumerals.setTextAlign(Align.CENTER); } } } else if (icon != null) { canvas.drawBitmap(icon, 0, 3, null); if ((Preferences.displayLocationInSmallCalendarWidget) && (!meetingTime.equals("None")) && (meetingLocation != null) && (!meetingLocation.equals("---")) && (widget_id.equals(id_0)) && (meetingLocation.length() > 0) && (meetingLocation.length() <= 3)) { canvas.drawText(meetingLocation, 12, 15, paintSmall); } else { Calendar c = Calendar.getInstance(); if ((Preferences.eventDateInCalendarWidget) && (!meetingTime.equals("None"))) { c.setTimeInMillis(meetingStartTimestamp); } int dayOfMonth = c.get(Calendar.DAY_OF_MONTH); if (dayOfMonth < 10) { canvas.drawText("" + dayOfMonth, 12, 16, paintNumerals); } else { canvas.drawText("" + dayOfMonth / 10, 9, 16, paintNumerals); canvas.drawText("" + dayOfMonth % 10, 15, 16, paintNumerals); } } canvas.drawText(meetingTime, 12, 30, paintSmall); } String text = ""; if (iconFile == null) text = meetingTime; if ((meetingTitle != null)) { if (text.length() > 0) text += " : "; text += meetingTitle; } if ((meetingLocation != null) && (meetingLocation.length() > 0)) text += " - " + meetingLocation; if (widget_id.equals(id_1) || widget_id.equals(id_4)) { paintSmall.setTextAlign(Align.LEFT); int iconSpace = iconFile == null ? 0 : 25; canvas.save(); StaticLayout layout = new StaticLayout( text, paintSmall, widget.width - iconSpace, Layout.Alignment.ALIGN_CENTER, 1.2f, 0, false); int height = layout.getHeight(); int textY = 16 - (height / 2); if (textY < 0) { textY = 0; } canvas.translate(iconSpace, textY); // position the text layout.draw(canvas); canvas.restore(); paintSmall.setTextAlign(Align.CENTER); } else if (widget_id.equals(id_3) || widget_id.equals(id_5)) { paintSmall.setTextAlign(Align.LEFT); int iconSpace = iconFile == null ? 0 : 11; canvas.save(); StaticLayout layout = new StaticLayout( text, paintSmall, widget.width - iconSpace, Layout.Alignment.ALIGN_CENTER, 1.0f, 0, false); int height = layout.getHeight(); int textY = 8 - (height / 2); if (textY < 0) { textY = 0; } canvas.translate(iconSpace, textY); // position the text layout.draw(canvas); canvas.restore(); paintSmall.setTextAlign(Align.CENTER); } return widget; }
private void drawText(Canvas canvas, Bitmap bitmap, int percent, Boolean isShort) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); Boolean isGradient = prefs.getBoolean("gradientKey", true); int size = 0; int smallDummyHeight = 0; while (smallDummyHeight < ((bitmap.getHeight() / 100) * percent)) { TextPaint paintText = new TextPaint(Paint.ANTI_ALIAS_FLAG); size = size + 1; paintText.setTextSize(size); paintText.setStyle(Paint.Style.FILL_AND_STROKE); paintText.setShadowLayer(3f, 3f, 3f, Color.BLACK); Rect smallDummyRect = new Rect(); paintText.getTextBounds(gagTitle, 0, gagTitle.length(), smallDummyRect); smallDummyHeight = smallDummyRect.height(); } int pL = bitmap.getWidth() / 100; int pT = bitmap.getHeight() / 100; if (isShort) { TextPaint paintText = new TextPaint(Paint.ANTI_ALIAS_FLAG); paintText.setColor(Color.WHITE); paintText.setTextSize(size); paintText.setStyle(Paint.Style.FILL_AND_STROKE); paintText.setShadowLayer(3f, 3f, 3f, Color.BLACK); Rect rectText = new Rect(); paintText.getTextBounds(gagTitle, 0, gagTitle.length(), rectText); if (isGradient) { int GRADIENT_HEIGHT = rectText.height(); Paint paint = new Paint(); LinearGradient shader = new LinearGradient( 0, 0, 0, GRADIENT_HEIGHT, Color.BLACK, Color.TRANSPARENT, Shader.TileMode.CLAMP); paint.setShader(shader); canvas.drawRect(0, 0, newBitmap.getWidth(), GRADIENT_HEIGHT, paint); } canvas.drawText(gagTitle, pL, rectText.height() + (3 * pT) / 2, paintText); } else { TextPaint paintText = new TextPaint(Paint.ANTI_ALIAS_FLAG); paintText.setColor(Color.WHITE); paintText.setTextSize(size); paintText.setStyle(Paint.Style.FILL_AND_STROKE); paintText.setShadowLayer(3f, 3f, 3f, Color.BLACK); StaticLayout mTextLayout = new StaticLayout( gagTitle, paintText, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); if (isGradient) { int GRADIENT_HEIGHT = mTextLayout.getHeight(); Paint paint = new Paint(); LinearGradient shader = new LinearGradient( 0, 0, 0, GRADIENT_HEIGHT, Color.BLACK, Color.TRANSPARENT, Shader.TileMode.CLAMP); paint.setShader(shader); canvas.drawRect(0, 0, newBitmap.getWidth(), GRADIENT_HEIGHT, paint); } canvas.save(); canvas.translate(pL, pT); mTextLayout.draw(canvas); canvas.restore(); } }
public List<Integer> getPageOffsets(CharSequence text, boolean includePageNumbers) { if (text == null) { return new ArrayList<Integer>(); } List<Integer> pageOffsets = new ArrayList<Integer>(); TextPaint textPaint = bookView.getInnerView().getPaint(); int boundedWidth = bookView.getInnerView().getWidth(); LOG.debug("Page width: " + boundedWidth); StaticLayout layout = layoutFactory.create(text, textPaint, boundedWidth, bookView.getLineSpacing()); LOG.debug("Layout height: " + layout.getHeight()); layout.draw(new Canvas()); // Subtract the height of the top margin int pageHeight = bookView.getHeight() - bookView.getVerticalMargin(); if (includePageNumbers) { String bottomSpace = "0\n"; StaticLayout numLayout = layoutFactory.create(bottomSpace, textPaint, boundedWidth, bookView.getLineSpacing()); numLayout.draw(new Canvas()); // Subtract the height needed to show page numbers, or the // height of the margin, whichever is more pageHeight = pageHeight - Math.max(numLayout.getHeight(), bookView.getVerticalMargin()); } else { // Just subtract the bottom margin pageHeight = pageHeight - bookView.getVerticalMargin(); } LOG.debug("Got pageHeight " + pageHeight); int totalLines = layout.getLineCount(); int topLineNextPage = -1; int pageStartOffset = 0; while (topLineNextPage < totalLines - 1) { LOG.debug("Processing line " + topLineNextPage + " / " + totalLines); int topLine = layout.getLineForOffset(pageStartOffset); topLineNextPage = layout.getLineForVertical(layout.getLineTop(topLine) + pageHeight); LOG.debug("topLine " + topLine + " / " + topLineNextPage); if (topLineNextPage == topLine) { // If lines are bigger than can fit on a page topLineNextPage = topLine + 1; } int pageEnd = layout.getLineEnd(topLineNextPage - 1); LOG.debug("pageStartOffset=" + pageStartOffset + ", pageEnd=" + pageEnd); if (pageEnd > pageStartOffset) { if (text.subSequence(pageStartOffset, pageEnd).toString().trim().length() > 0) { pageOffsets.add(pageStartOffset); } pageStartOffset = layout.getLineStart(topLineNextPage); } } return pageOffsets; }