private static Alignment parseTextAlignment(String s) { switch (s) { case "start": case "left": return Alignment.ALIGN_NORMAL; case "center": case "middle": return Alignment.ALIGN_CENTER; case "end": case "right": return Alignment.ALIGN_OPPOSITE; default: Log.w(TAG, "Invalid alignment value: " + s); return null; } }
private Layout makeSingleLayout(int i, BoringLayout.Metrics metrics, int i2, Alignment alignment, boolean z, TextUtils.TruncateAt truncateAt, boolean z2) { BoringLayout.Metrics isBoring; if (metrics == UNKNOWN_BORING) { isBoring = BoringLayout.isBoring(this.mText, this.mPaint, this.mBoring); if (isBoring != null) { this.mBoring = isBoring; } } else { isBoring = metrics; } if (isBoring != null) { if (isBoring.width <= i && (truncateAt == null || isBoring.width <= i2)) { return BoringLayout.make(this.mText, this.mPaint, i, alignment, this.mLineSpacingMult, this.mLineSpacingAdd, isBoring, this.mIncludeFontPadding); } else if (z && isBoring.width <= i) { return BoringLayout.make(this.mText, this.mPaint, i, alignment, this.mLineSpacingMult, this.mLineSpacingAdd, isBoring, this.mIncludeFontPadding, truncateAt, i2); } else if (z) { return StaticLayoutWithMaxLines.create(this.mText, 0, this.mText.length(), this.mPaint, i, alignment, this.mLineSpacingMult, this.mLineSpacingAdd, this.mIncludeFontPadding, truncateAt, i2, this.mMaxLines); } else { return new StaticLayout(this.mText, this.mPaint, i, alignment, this.mLineSpacingMult, this.mLineSpacingAdd, this.mIncludeFontPadding); } } else if (z) { return StaticLayoutWithMaxLines.create(this.mText, 0, this.mText.length(), this.mPaint, i, alignment, this.mLineSpacingMult, this.mLineSpacingAdd, this.mIncludeFontPadding, truncateAt, i2, this.mMaxLines); } else { return new StaticLayout(this.mText, this.mPaint, i, alignment, this.mLineSpacingMult, this.mLineSpacingAdd, this.mIncludeFontPadding); } }
private Cue(CharSequence text, Alignment textAlignment, Bitmap bitmap, float line, @LineType int lineType, @AnchorType int lineAnchor, float position, @AnchorType int positionAnchor, float size, float bitmapHeight, boolean windowColorSet, int windowColor) { this.text = text; this.textAlignment = textAlignment; this.bitmap = bitmap; this.line = line; this.lineType = lineType; this.lineAnchor = lineAnchor; this.position = position; this.positionAnchor = positionAnchor; this.size = size; this.bitmapHeight = bitmapHeight; this.windowColorSet = windowColorSet; this.windowColor = windowColor; }
@SuppressWarnings({"checkstyle:ParameterNumber", "PMD.ExcessiveParameterList"}) // TODO group parameters into classes public NoPlayerCue(CharSequence text, Alignment textAlignment, Bitmap bitmap, float line, int lineType, int lineAnchor, float position, int positionAnchor, float size, float bitmapHeight, boolean windowColorSet, int windowColor) { this.text = text; this.textAlignment = textAlignment; this.bitmap = bitmap; this.line = line; this.lineType = lineType; this.lineAnchor = lineAnchor; this.position = position; this.positionAnchor = positionAnchor; this.size = size; this.bitmapHeight = bitmapHeight; this.windowColorSet = windowColorSet; this.windowColor = windowColor; }
private static void assertCue(WebvttSubtitle subtitle, int eventTimeIndex, long startTimeUs, int endTimeUs, String text, Alignment textAlignment, float line, int lineType, int lineAnchor, float position, int positionAnchor, float size) { assertEquals(startTimeUs, subtitle.getEventTime(eventTimeIndex)); assertEquals(endTimeUs, subtitle.getEventTime(eventTimeIndex + 1)); List<Cue> cues = subtitle.getCues(subtitle.getEventTime(eventTimeIndex)); assertEquals(1, cues.size()); // Assert cue properties Cue cue = cues.get(0); assertEquals(text, cue.text.toString()); assertEquals(textAlignment, cue.textAlignment); assertEquals(line, cue.line); assertEquals(lineType, cue.lineType); assertEquals(lineAnchor, cue.lineAnchor); assertEquals(position, cue.position); assertEquals(positionAnchor, cue.positionAnchor); assertEquals(size, cue.size); }
private void measurePlainText(int widthMeasureSpec, int heightMeasureSpec) { int paddingLeft = this.getPaddingLeft(); int paddingRight = this.getPaddingRight(); int paddingTop = this.getPaddingTop(); int paddingBottom = this.getPaddingBottom(); // max allowed width or height int sizeWidth = MeasureSpec.getSize(widthMeasureSpec) - paddingLeft - paddingRight; int sizeHeight = MeasureSpec.getSize(heightMeasureSpec) - paddingTop - paddingBottom; // mode int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); // calculate text width and height mPaint.setTextSize(mTextSize); mStaticLayout = new StaticLayout(mTextString, mPaint, sizeWidth, Alignment.ALIGN_NORMAL, 1.0f, 0, false); // measured width and height int measuredWidth = modeWidth == MeasureSpec.EXACTLY ? sizeWidth : Math.min(sizeWidth, (int) Math.ceil(Layout.getDesiredWidth(mTextString, mPaint))); int measuredHeight = modeHeight == MeasureSpec.EXACTLY ? sizeHeight : mStaticLayout.getHeight(); setMeasuredDimension(measuredWidth + paddingLeft + paddingRight, measuredHeight + paddingTop + paddingBottom); }
@Override public void applyToSelection(RTEditText editor, Selection selectedParagraphs, Layout.Alignment alignment) { final Spannable str = editor.getText(); mSpans2Process.clear(); for (Paragraph paragraph : editor.getParagraphs()) { // find existing AlignmentSpan and add them to mSpans2Process to be removed List<RTSpan<Layout.Alignment>> existingSpans = getSpans(str, paragraph, SpanCollectMode.SPAN_FLAGS); mSpans2Process.removeSpans(existingSpans, paragraph); // if the paragraph is selected then we sure have an alignment boolean hasExistingSpans = !existingSpans.isEmpty(); Alignment newAlignment = paragraph.isSelected(selectedParagraphs) ? alignment : hasExistingSpans ? existingSpans.get(0).getValue() : null; if (newAlignment != null) { boolean isRTL = Helper.isRTL(str, paragraph.start(), paragraph.end()); AlignmentSpan alignmentSpan = new AlignmentSpan(newAlignment, isRTL); mSpans2Process.addSpan(alignmentSpan, paragraph); } } // add or remove spans mSpans2Process.process(str); }
public void testDecodeWithPositioning() throws IOException, SubtitleDecoderException { WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_POSITIONING_FILE); // Test event count. assertEquals(12, subtitle.getEventTimeCount()); // Test cues. assertCue(subtitle, 0, 0, 1234000, "This is the first subtitle.", Alignment.ALIGN_NORMAL, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.TYPE_UNSET, 0.1f, Cue.ANCHOR_TYPE_START, 0.35f); assertCue(subtitle, 2, 2345000, 3456000, "This is the second subtitle.", Alignment.ALIGN_OPPOSITE, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, 0.35f); assertCue(subtitle, 4, 4000000, 5000000, "This is the third subtitle.", Alignment.ALIGN_CENTER, 0.45f, Cue.LINE_TYPE_FRACTION, Cue.ANCHOR_TYPE_END, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, 0.35f); assertCue(subtitle, 6, 6000000, 7000000, "This is the fourth subtitle.", Alignment.ALIGN_CENTER, -10f, Cue.LINE_TYPE_NUMBER, Cue.TYPE_UNSET, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET); assertCue(subtitle, 8, 7000000, 8000000, "This is the fifth subtitle.", Alignment.ALIGN_OPPOSITE, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.TYPE_UNSET, 0.1f, Cue.ANCHOR_TYPE_END, 0.1f); assertCue(subtitle, 10, 10000000, 11000000, "This is the sixth subtitle.", Alignment.ALIGN_CENTER, 0.45f, Cue.LINE_TYPE_FRACTION, Cue.ANCHOR_TYPE_END, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, 0.35f); }
private static void assertCue(WebvttSubtitle subtitle, int eventTimeIndex, long startTimeUs, int endTimeUs, String text, Alignment textAlignment, float line, int lineType, int lineAnchor, float position, int positionAnchor, float size) { assertEquals(startTimeUs, subtitle.getEventTime(eventTimeIndex)); assertEquals(endTimeUs, subtitle.getEventTime(eventTimeIndex + 1)); List<Cue> cues = subtitle.getCues(subtitle.getEventTime(eventTimeIndex)); assertEquals(1, cues.size()); // Assert cue properties. Cue cue = cues.get(0); assertEquals(text, cue.text.toString()); assertEquals(textAlignment, cue.textAlignment); assertEquals(line, cue.line); assertEquals(lineType, cue.lineType); assertEquals(lineAnchor, cue.lineAnchor); assertEquals(position, cue.position); assertEquals(positionAnchor, cue.positionAnchor); assertEquals(size, cue.size); }
@Override public void draw(Canvas canvas) { canvas.save(); mPaint.setColor(Color.TRANSPARENT); Rect rect = new Rect(0, 0, mDrawableWidth, mDrawableHeight); canvas.drawRect(rect, mPaint); mPaint.setColor(mTextBgColor); RectF rectf = new RectF(mMarginLeft, mMarginTop, mDrawableWidth - mMarginRight, mDrawableHeight - mMarginBottom); canvas.drawRoundRect(rectf, mRoundRectRadiusX, mRoundRectRadiusY, mPaint); canvas.translate(mMarginLeft + mPaddingLeft, mMarginTop + mPaddingTop); canvas.clipRect(0, 0, mContentWidth, mContentHeight); mPaint.setColor(mTextFgColor); StaticLayout layout = new StaticLayout(mContent, mPaint, mContentWidth, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true); layout.draw(canvas); canvas.restore(); }
@Override public int getIntrinsicHeight() { StaticLayout layout = new StaticLayout(mContent, mPaint, mContentWidth, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true); int textHeight = layout.getHeight(); int height = 0; if (textHeight + mPaddingTop + mPaddingBottom + mMarginTop + mMarginBottom > mMaxHeight) { height = mMaxHeight; mContentHeight = height - mPaddingTop - mPaddingBottom - mMarginTop - mMarginBottom; } else { height = textHeight + mPaddingTop + mPaddingBottom + mMarginTop + mMarginBottom; mContentHeight = textHeight; } return height; }
private Layout makeLayout(CharSequence paramCharSequence) { CharSequence localCharSequence; TextPaint localTextPaint; if (this.mSwitchTransformationMethod != null) { localCharSequence = this.mSwitchTransformationMethod.getTransformation(paramCharSequence, this); localTextPaint = this.mTextPaint; if (localCharSequence == null) { break label66; } } label66: for (int i = (int)Math.ceil(Layout.getDesiredWidth(localCharSequence, this.mTextPaint));; i = 0) { return new StaticLayout(localCharSequence, localTextPaint, i, Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true); localCharSequence = paramCharSequence; break; } }
protected final int a(int paramInt1, int paramInt2, int paramInt3, int paramInt4) { int i1 = paramInt2 + this.H.aP; this.h = new StaticLayout(getContext().getString(efj.Jg), efj.B(getContext(), ehr.bc), paramInt4, Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, false); int i2 = i1 + this.h.getHeight() + this.H.aP; this.q = i2; int i3 = View.MeasureSpec.makeMeasureSpec(0, 0); int i4 = View.MeasureSpec.makeMeasureSpec(this.P, 1073741824); int i5 = d(false); if (i5 == 0) {} for (int i6 = i2 + a(paramInt4);; i6 = i2 + i5) { this.j.measure(i4, i3); int i7 = i6 + this.j.getMeasuredHeight(); if (this.r == 0) { this.r = i7; } return this.r; } }
public void testDecodeWithPositioning() throws IOException, SubtitleDecoderException { WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_POSITIONING_FILE); // Test event count. assertEquals(12, subtitle.getEventTimeCount()); // Test cues. assertCue(subtitle, 0, 0, 1234000, "This is the first subtitle.", Alignment.ALIGN_NORMAL, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.TYPE_UNSET, 0.1f, Cue.ANCHOR_TYPE_START, 0.35f); assertCue(subtitle, 2, 2345000, 3456000, "This is the second subtitle.", Alignment.ALIGN_OPPOSITE, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, 0.35f); assertCue(subtitle, 4, 4000000, 5000000, "This is the third subtitle.", Alignment.ALIGN_CENTER, 0.45f, Cue.LINE_TYPE_FRACTION, Cue.ANCHOR_TYPE_END, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, 0.35f); assertCue(subtitle, 6, 6000000, 7000000, "This is the fourth subtitle.", Alignment.ALIGN_CENTER, -11f, Cue.LINE_TYPE_NUMBER, Cue.TYPE_UNSET, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET); assertCue(subtitle, 8, 7000000, 8000000, "This is the fifth subtitle.", Alignment.ALIGN_OPPOSITE, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.TYPE_UNSET, 0.1f, Cue.ANCHOR_TYPE_END, 0.1f); assertCue(subtitle, 10, 10000000, 11000000, "This is the sixth subtitle.", Alignment.ALIGN_CENTER, 0.45f, Cue.LINE_TYPE_FRACTION, Cue.ANCHOR_TYPE_END, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, 0.35f); }
public WindowSelectOppoment() { bg = new Sprite2D(CacheManager.black.texture, new RectF(0, 0, 1024, 512), new RectF(0, 0, 1, 1) ); bg.alpha = 0.8f; btnCancel = new SpriteButton(CacheManager.getTextureById(R.drawable.ui_game), 608, 640, 144, 80); btnCancel.setLocation(160,432); for (int i = 0; i < 3; i++) { SpriteButton btnOppoment = new SpriteButton(CacheManager.getTextureById(R.drawable.ui_game), 432, 640, 176, 208); btnOppoment.setLocation(192 + i * 224, 160); btnOppoments.add(btnOppoment); Sprite2D spFace = CacheManager.getPlayerFaceById(0, 128, 128); spFace.setLocation(217 + i * 224, 182.8f); spFaces.add(spFace); TextField txtName = new TextField("", 128, 32); txtName.setColor(Color.BLACK); txtName.setLocation(216 + i * 224, 314); txtName.setAlign(Alignment.ALIGN_CENTER); txtNames.add(txtName); } }
public WindowOppoments(){ oppmentsBg = new Sprite2D(CacheManager.getTextureById(R.drawable.ui_game),0,80,416,64); oppmentsBg.setLocation(304, 448); for (int i = 0; i < 3; i++) { oppomentsFace[i] = CacheManager.getPlayerFaceById(0, 44, 44); oppomentsFace[i].setLocation(330 + i * 120, 458); oppomentsCash[i] = new TextField("", 128, 32); oppomentsCash[i].setColor(Color.BLACK); oppomentsCash[i].setLocation(310 + i * 120, 488); oppomentsCash[i].setSize(14); oppomentsCash[i].setAlign(Alignment.ALIGN_OPPOSITE); oppomentsName[i] = new TextField("name", 128, 32); oppomentsName[i].setColor(Color.BLACK); oppomentsName[i].setLocation(380 + i * 120, 462); oppomentsName[i].setSize(14); } stopIcon = new Sprite2D [3]; for (int i = 0; i < 3; i++) { stopIcon [i] = new Sprite2D(CacheManager.getTextureById(R.drawable.ui_game), new RectF(0,0,16,16), new RectF(32,0,64,32)); stopIcon [i].alpha = 0; stopIcon [i].setLocation(370 + i*120, 496); } }
public DataSet(){ txtName = new TextField("name", 128 , 64); txtName.setColor(Color.BLACK); txtName.setSize(26); txtCash = new TextField("cash", 128 , 32); txtCash.setAlign(Alignment.ALIGN_OPPOSITE); txtCash.setColor(Color.BLACK); txtJob = new TextField("job", 128 , 32); txtJob.setColor(Color.BLACK); txtETC = new TextField("ETC", 128, 32); txtETC.setAlign(Alignment.ALIGN_OPPOSITE); txtETC.setColor(Color.BLACK); txtAchievement = new TextField("achievement", 128 , 128); txtAchievement.setAlign(Alignment.ALIGN_OPPOSITE); txtAchievement.setColor(Color.BLACK); txtAchievement.setSize(80); txtAchievement.alpha = 0.5f; playerFace = CacheManager.getPlayerFaceById(0, 64, 64); }
public WindowScoreBoard() { bg = new SpriteButton(CacheManager.getTextureById(R.drawable.ui_game_scoreboard),0,0,1024,512); bg.setLocation(0, -512); btnClose = new SpriteButton(CacheManager.black.texture, new RectF(0,0,1024,96), new RectF(0,0,1,1) ); btnClose.setLocation(0, -96); btnDay = new SpriteButton(CacheManager.getTextureById(R.drawable.ui_game),416,64,144,64); btnDay.setLocation(568,0); txtDayCount = new TextField("99", 64, 32); txtDayCount.setAlign(Alignment.ALIGN_CENTER); txtDayCount.setSize(28); txtDayCount.setLocation(600, 0); for(int i=0; i < 4; i++){ DataSet ds = new DataSet(); ds.setLocation(256,96+i*96-512); dataSetsArrayList.add(ds); dataSets[i] = ds; } }
public WindowScoreBoardFinal(){ bg = new Sprite2D(CacheManager.getTextureById(R.drawable.ui_final),0,0,672,448); bg.setLocation(176, 32); playerFace = CacheManager.getPlayerFaceById(0, 112, 112); playerFace.setLocation(456, 232); txtAp = new TextField("0", 128, 64); txtAp.setAlign(Alignment.ALIGN_OPPOSITE); txtAp.setLocation(452, 390); txtAp.setSize(40); txtAp.setColor(Color.BLACK); txtPlayerName = new TextField("xxx", 128, 64); txtPlayerName.setAlign(Alignment.ALIGN_CENTER); txtPlayerName.setLocation(448, 352); txtPlayerName.setSize(24); txtPlayerName.setColor(Color.BLACK); }
private static void drawText(Canvas canvas, int xStart, int yStart, int xWidth, int yHeigth, String textToDisplay, TextPaint paintToUse, float startTextSizeInPixels, float stepSizeForTextSizeSteps) { // Text view line spacing multiplier float mSpacingMult = 1.0f; // Text view additional line spacing float mSpacingAdd = 0.0f; StaticLayout l = null; do { paintToUse.setTextSize(startTextSizeInPixels); startTextSizeInPixels -= stepSizeForTextSizeSteps; l = new StaticLayout(textToDisplay, paintToUse, xWidth, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true); } while (l.getHeight() > yHeigth); int textCenterX = xStart + (xWidth / 2); int textCenterY = (yHeigth - l.getHeight()) / 2; canvas.save(); canvas.translate(textCenterX, textCenterY); l.draw(canvas); canvas.restore(); }
@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; } }
private Spannable addEndTag(SpannableStringBuilder builder) { //Don't add the tag to the last section. Spine spine = bookView.getSpine(); if (spine == null || spine.getPosition() >= spine.size() -1 ) { return builder; } int length = builder.length(); builder.append("\uFFFC"); builder.append("\n"); builder.append( context.getString(R.string.end_of_section)); //If not, consider it an internal nav link. ClickableSpan span = new ClickableSpan() { @Override public void onClick(View widget) { pageDown(); } }; Drawable img = context.getResources().getDrawable(R.drawable.gateway); img.setBounds(0, 0, img.getIntrinsicWidth(), img.getIntrinsicHeight() ); builder.setSpan(new ImageSpan(img), length, length+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); builder.setSpan(span, length, builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); builder.setSpan( (AlignmentSpan) () -> Alignment.ALIGN_CENTER , length, builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return builder; }
public Cue(CharSequence text, Alignment textAlignment, float line, int lineType, int lineAnchor, float position, int positionAnchor, float size) { this.text = text; this.textAlignment = textAlignment; this.line = line; this.lineType = lineType; this.lineAnchor = lineAnchor; this.position = position; this.positionAnchor = positionAnchor; this.size = size; }
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(); }
@Override public void draw(@NonNull Canvas canvas) { Paint paint = new Paint(); paint.setColor(textColor); paint.setStyle(Style.STROKE); int numberOfColumns = tableRow.size(); if (numberOfColumns == 0) { return; } int columnWidth = tableWidth / numberOfColumns; int offset; for (int i = 0; i < numberOfColumns; i++) { offset = i * columnWidth; if (paintBorder) { // The rect is open at the bottom, so there's a single line // between rows. canvas.drawRect(offset, 0, offset + columnWidth, rowHeight, paint); } StaticLayout layout = new StaticLayout(tableRow.get(i), getTextPaint(), (columnWidth - 2 * PADDING), Alignment.ALIGN_NORMAL, 1.5f, 0.5f, true); canvas.translate(offset + PADDING, 0); layout.draw(canvas); canvas.translate(-1 * (offset + PADDING), 0); } }
@Override public void draw(Canvas canvas) { Paint paint = new Paint(); paint.setColor(textColor); paint.setStyle(Style.STROKE); int numberOfColumns = tableRow.size(); if (numberOfColumns == 0) { return; } int columnWidth = tableWidth / numberOfColumns; int offset = 0; for (int i = 0; i < numberOfColumns; i++) { offset = i * columnWidth; if ( paintBorder ) { // The rect is open at the bottom, so there's a single line // between rows. canvas.drawRect(offset, 0, offset + columnWidth, rowHeight, paint); } StaticLayout layout = new StaticLayout(tableRow.get(i), getTextPaint(), (columnWidth - 2 * PADDING), Alignment.ALIGN_NORMAL, 1f, 0f, true); canvas.translate(offset + PADDING, 0); layout.draw(canvas); canvas.translate(-1 * (offset + PADDING), 0); } }