Skip to content

Commit

Permalink
Add support for minEms, minWidth, maxEms, maxWidth in TextLayoutBuilder
Browse files Browse the repository at this point in the history
Summary: Some attributes from `TextView` are still missing in `TextSpec`, specifically `maxEms` attribute was requested from engineers who are doing NewsFeed conversions to Components. `TextSpec` uses `TextLayoutBuilder` to do its layout and this diff adds support for `ems` and related attributes to `TextLayoutBuilder`, specifically `minEms`, `maxEms`, `minWidth`, `maxWidth`.

Reviewed By: sriramramani

Differential Revision: D4544590

fbshipit-source-id: 5f402d844811c5612af447150dc686c164e16f62
  • Loading branch information
muraziz authored and facebook-github-bot committed Feb 13, 2017
1 parent 1e0e4b3 commit 2e351ef
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ public class TextLayoutBuilder {
// Default maxLines.
public static final int DEFAULT_MAX_LINES = Integer.MAX_VALUE;

private static final int EMS = 1;
private static final int PIXELS = 2;

private int mMinWidth = 0;
private int mMinWidthMode = PIXELS;
private int mMaxWidth = Integer.MAX_VALUE;
private int mMaxWidthMode = PIXELS;

// Cache for text layouts.
@VisibleForTesting
static final LruCache<Integer, Layout> sCache = new LruCache<>(100);
Expand Down Expand Up @@ -101,6 +109,10 @@ void createNewPaintIfNeeded() {
}
}

int getLineHeight() {
return Math.round(paint.getFontMetricsInt(null) * spacingMult + spacingAdd);
}

@Override
public int hashCode() {
int hashCode = 1;
Expand Down Expand Up @@ -618,6 +630,88 @@ public TextLayoutBuilder setGlyphWarmer(GlyphWarmer glyphWarmer) {
return this;
}

/**
* Sets the min width expressed in ems (equivalent to setMinEms() in TextView)
*
* @param minEms min width expressed in ems
*/
public TextLayoutBuilder setMinEms(int minEms) {
mMinWidth = minEms;
mMinWidthMode = EMS;
return this;
}

/**
* @return the min width expressed in ems (equivalent to getMinEms() in TextView) or -1
* if min width is set in pixels instead by using {@link #setMinWidth(int)}
*
* @see #setMinEms(int)
*/
public int getMinEms() {
return mMinWidthMode == EMS ? mMinWidth : -1;
}

/**
* Sets the min width expressed in pixels
* @param minWidth
*/
public TextLayoutBuilder setMinWidth(@Px int minWidth) {
mMinWidth = minWidth;
mMinWidthMode = PIXELS;
return this;
}

/**
* @return the min width expressed in pixels or -1 if the min width was set in ems instead
*
* @see #setMinWidth(int)
*/
@Px
public int getMinWidth() {
return mMinWidthMode == PIXELS ? mMinWidth : -1;
}

/**
* Sets the max width expressed in ems (equivalent to setMaxEms() in TextView)
*
* @param maxEms max width expressed in ems
*/
public TextLayoutBuilder setMaxEms(int maxEms) {
mMaxWidth = maxEms;
mMaxWidthMode = EMS;
return this;
}

/**
* @return the max width expressed in ems (equivalent to getMaxEms() in TextView) or -1
* if max width is set in pixels instead by using {@link #setMaxWidth(int)}
*
* @see #setMaxEms(int)
*/
public int getMaxEms() {
return mMaxWidthMode == EMS ? mMaxWidth : -1;
}

/**
* Sets the max width expressed in pixels
* @param maxWidth
*/
public TextLayoutBuilder setMaxWidth(@Px int maxWidth) {
mMaxWidth = maxWidth;
mMaxWidthMode = PIXELS;
return this;
}

/**
* @return the max width expressed in pixels or -1 if the max width was set in ems instead
*
* @see #setMaxWidth(int)
*/
@Px
public int getMaxWidth() {
return mMaxWidthMode == PIXELS ? mMaxWidth : -1;
}

/**
* Builds and returns a {@link Layout}.
*
Expand Down Expand Up @@ -685,6 +779,19 @@ public Layout build() {
throw new IllegalStateException("Unexpected measure mode " + mParams.measureMode);
}

final int lineHeight = mParams.getLineHeight();
if (mMaxWidthMode == EMS) {
width = Math.min(width, mMaxWidth * lineHeight);
} else {
width = Math.min(width, mMaxWidth);
}

if (mMinWidthMode == EMS) {
width = Math.max(width, mMinWidth * lineHeight);
} else {
width = Math.max(width, mMinWidth);
}

Layout layout;
if (metrics != null) {
layout = BoringLayout.make(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,46 @@ public void testMaxLines() {
assertEquals(mLayout.getLineCount(), 2);
}

@Test
public void testMinEms() {
mBuilder
.setText(LONG_TEXT)
.setMinEms(10)
.build();
assertEquals(mBuilder.getMinEms(), 10);
assertEquals(mBuilder.getMinWidth(), -1);
}

@Test
public void testMaxEms() {
mBuilder
.setText(LONG_TEXT)
.setMaxEms(10)
.build();
assertEquals(mBuilder.getMaxEms(), 10);
assertEquals(mBuilder.getMaxWidth(), -1);
}

@Test
public void testMinWidth() {
mBuilder
.setText(LONG_TEXT)
.setMinWidth(100)
.build();
assertEquals(mBuilder.getMinWidth(), 100);
assertEquals(mBuilder.getMinEms(), -1);
}

@Test
public void testMaxWidth() {
mBuilder
.setText(LONG_TEXT)
.setMaxWidth(100)
.build();
assertEquals(mBuilder.getMaxWidth(), 100);
assertEquals(mBuilder.getMaxEms(), -1);
}

@Test
public void testDrawableState() {
int[] drawableState = {0, 1};
Expand Down

0 comments on commit 2e351ef

Please sign in to comment.