Last active
August 29, 2015 14:00
-
-
Save jbruchanov/11376943 to your computer and use it in GitHub Desktop.
TextRenderHelper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); | |
g.setFont(new Font("Arial", Font.PLAIN, 24)); | |
FontMetrics fm = g.getFontMetrics(); | |
TextRenderHelper helper = new TextRenderHelper(fm, "Hello World\nHello World Hello World Hello World Hello World", 300, 60); | |
for (TextRenderHelper.LineRenderContext lrc : helper.prepareForRender(TextRenderHelper.Gravity.CENTER, TextRenderHelper.Gravity.CENTER)) { | |
g.drawString(lrc.text, lrc.x, lrc.y); | |
} | |
private static class TextRenderHelper{ | |
private String mText; | |
public enum Gravity { | |
LEFT_TOP, CENTER, RIGHT_BOTTOM | |
} | |
private final FontMetrics mFontMetrics; | |
private int mMaxWidth; | |
private int mMaxHeight; | |
private final int mLineHeight; | |
public TextRenderHelper(FontMetrics metrics, String text, int maxWidth, int maxHeight) { | |
mFontMetrics = metrics; | |
mLineHeight = mFontMetrics.getHeight();//mFontMetrics.getMaxAscent() + mFontMetrics.getMaxDescent(); | |
mText = text; | |
mMaxWidth = maxWidth; | |
mMaxHeight = maxHeight; | |
} | |
public ArrayList<LineRenderContext> prepareForRender(Gravity horizontal, Gravity vertical) { | |
ArrayList<LineRenderContext> list = createLineContexts(horizontal); | |
countVerticalPositions(list, vertical); | |
return list; | |
} | |
private ArrayList<LineRenderContext> createLineContexts(Gravity horizontal) { | |
ArrayList<LineRenderContext> result = new ArrayList<LineRenderContext>(); | |
int width = mFontMetrics.stringWidth(mText); | |
if (width < mMaxWidth && !mText.contains("\n")) { | |
//single line | |
result.add(new LineRenderContext(getX(horizontal, width), mText)); | |
} else { | |
char[] chars = mText.toCharArray(); | |
String currentLine = String.valueOf(chars[0]); | |
width = mFontMetrics.stringWidth(currentLine); | |
for (int i = 1; i < chars.length; i++) { | |
char c = chars[i]; | |
boolean newLine = '\n' == c; | |
int newWidth = mFontMetrics.stringWidth(currentLine + c); | |
if (!newLine && newWidth < mMaxWidth) {//continue till letter will reach max width | |
currentLine += c; | |
width = newWidth; | |
} else { | |
//add new line | |
result.add(new LineRenderContext(getX(horizontal, width), currentLine)); | |
currentLine = newLine ? "" : String.valueOf(c); | |
width = newWidth - width; | |
} | |
} | |
//rest | |
if (currentLine.trim().length() > 0) { | |
result.add(new LineRenderContext(getX(horizontal, width), currentLine)); | |
} | |
} | |
return result; | |
} | |
private void countVerticalPositions(ArrayList<LineRenderContext> contexts, Gravity vertical) { | |
final int len = contexts.size(); | |
int y = 0; | |
switch (vertical) { | |
case LEFT_TOP: | |
y = mFontMetrics.getMaxAscent(); | |
for (LineRenderContext context1 : contexts) { | |
context1.y = y; | |
y += mLineHeight; | |
} | |
break; | |
case CENTER: | |
y = ((mLineHeight + mMaxHeight) >> 1) - mFontMetrics.getMaxDescent(); | |
final int offset = ((len - 1) * mLineHeight) >> 1; | |
for (LineRenderContext context : contexts) { | |
context.y = y - offset; | |
y += mLineHeight; | |
} | |
break; | |
case RIGHT_BOTTOM: | |
y = mMaxHeight - mFontMetrics.getMaxDescent(); | |
for (int i = len - 1; i >= 0; i--) { | |
contexts.get(i).y = y; | |
y -= mLineHeight; | |
} | |
break; | |
} | |
} | |
public int getX(Gravity horizontal, int lineWidth){ | |
int x = 0; | |
switch (horizontal) { | |
case LEFT_TOP: x = 0; break; | |
case CENTER: x = (mMaxWidth - lineWidth) >> 1; break; | |
case RIGHT_BOTTOM: x = mMaxWidth - lineWidth; break; | |
} | |
return x; | |
} | |
private static class LineRenderContext { | |
public int x; | |
public int y; | |
public String text; | |
public LineRenderContext(int x, String text) { | |
this(x, 0, text); | |
} | |
public LineRenderContext(int x, int y, String text) { | |
this.x = x; | |
this.y = y; | |
this.text = text; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment