package com.bdc.ociney.view.textview;
import android.graphics.Paint;
import android.view.Gravity;
import android.widget.TextView;
/*!
*
* TextJustifyUtils.java
* @author Mathew Kurian
*
* From TextJustify-Android Library v1.0.2
* https://github.com/bluejamesbond/TextJustify-Android
*
* Please report any issues
* https://github.com/bluejamesbond/TextJustify-Android/issues
*
* Date: 12/13/2013 12:29:16 PM
*
*/
public class TextJustifyUtils
{
// Please use run(...) instead
public static void justify(TextView textView)
{
Paint paint = new Paint();
String [] blocks;
float spaceOffset = 0;
float textWrapWidth = 0;
int spacesToSpread;
float wrappedEdgeSpace;
String block;
String [] lineAsWords;
String wrappedLine;
String smb = "";
Object [] wrappedObj;
// Pull widget properties
paint.setColor(textView.getCurrentTextColor());
paint.setTypeface(textView.getTypeface());
paint.setTextSize(textView.getTextSize());
textWrapWidth = textView.getWidth();
spaceOffset = paint.measureText(" ");
blocks = textView.getText().toString().split("((?<=\n)|(?=\n))");
if(textWrapWidth < 20)
{
return;
}
for(int i = 0; i < blocks.length; i++)
{
block = blocks[i];
if(block.length() == 0)
{
continue;
}
else if(block.equals("\n"))
{
smb += block;
continue;
}
block = block.trim();
if(block.length() == 0) continue;
wrappedObj = TextJustifyUtils.createWrappedLine(block, paint, spaceOffset, textWrapWidth);
wrappedLine = ((String) wrappedObj[0]);
wrappedEdgeSpace = (Float) wrappedObj[1];
lineAsWords = wrappedLine.split(" ");
spacesToSpread = (int) (wrappedEdgeSpace != Float.MIN_VALUE ? wrappedEdgeSpace/spaceOffset : 0);
for(String word : lineAsWords)
{
smb += word + " ";
if(--spacesToSpread > 0)
{
smb += " ";
}
}
smb = smb.trim();
if(blocks[i].length() > 0)
{
blocks[i] = blocks[i].substring(wrappedLine.length());
if(blocks[i].length() > 0)
{
smb += "\n";
}
i--;
}
}
textView.setGravity(Gravity.LEFT);
textView.setText(smb);
}
protected static Object [] createWrappedLine(String block, Paint paint, float spaceOffset, float maxWidth)
{
float cacheWidth = maxWidth;
float origMaxWidth = maxWidth;
String line = "";
for(String word : block.split("\\s"))
{
cacheWidth = paint.measureText(word);
maxWidth -= cacheWidth;
if(maxWidth <= 0)
{
return new Object[] { line, maxWidth + cacheWidth + spaceOffset };
}
line += word + " ";
maxWidth -= spaceOffset;
}
if(paint.measureText(block) <= origMaxWidth)
{
return new Object[] { block, Float.MIN_VALUE };
}
return new Object[] { line, maxWidth };
}
final static String SYSTEM_NEWLINE = "\n";
final static float COMPLEXITY = 5.12f; //Reducing this will increase efficiency but will decrease effectiveness
final static Paint p = new Paint();
/* @author Mathew Kurian */
public static void run(final TextView tv, float origWidth) {
String s = tv.getText().toString();
p.setTypeface(tv.getTypeface());
String [] splits = s.split(SYSTEM_NEWLINE);
float width = origWidth - 5;
for(int x = 0; x<splits.length;x++)
if(p.measureText(splits[x])>width){
splits[x] = wrap(splits[x], width, p);
String [] microSplits = splits[x].split(SYSTEM_NEWLINE);
for(int y = 0; y<microSplits.length-1;y++)
microSplits[y] = justify(removeLast(microSplits[y], " "), width, p);
StringBuilder smb_internal = new StringBuilder();
for(int z = 0; z<microSplits.length;z++)
smb_internal.append(microSplits[z]+((z+1<microSplits.length) ? SYSTEM_NEWLINE : ""));
splits[x] = smb_internal.toString();
}
final StringBuilder smb = new StringBuilder();
for(String cleaned : splits)
smb.append(cleaned+SYSTEM_NEWLINE);
tv.setGravity(Gravity.LEFT);
tv.setText(smb);
}
private static String wrap(String s, float width, Paint p){
String [] str = s.split("\\s"); //regex
StringBuilder smb = new StringBuilder(); //save memory
smb.append(SYSTEM_NEWLINE);
for(int x = 0; x<str.length; x++){
float length = p.measureText(str[x]);
String [] pieces = smb.toString().split(SYSTEM_NEWLINE);
try{
if(p.measureText(pieces[pieces.length-1])+length>width)
smb.append(SYSTEM_NEWLINE);
}catch(Exception e){}
smb.append(str[x] + " ");
}
return smb.toString().replaceFirst(SYSTEM_NEWLINE, "");
}
private static String removeLast(String s, String g){
if(s.contains(g)){
int index = s.lastIndexOf(g);
int indexEnd = index + g.length();
if(index == 0) return s.substring(1);
else if(index == s.length()-1) return s.substring(0, index);
else
return s.substring(0, index) + s.substring(indexEnd);
}
return s;
}
private static String justifyOperation(String s, float width, Paint p){
float holder = (float) (COMPLEXITY*Math.random());
while(s.contains(Float.toString(holder)))
holder = (float) (COMPLEXITY*Math.random());
String holder_string = Float.toString(holder);
float lessThan = width;
int timeOut = 100;
int current = 0;
while(p.measureText(s)<lessThan&¤t<timeOut) {
s = s.replaceFirst(" ([^"+holder_string+"])", " "+holder_string+"$1");
lessThan = p.measureText(holder_string)+lessThan-p.measureText(" ");
current++;
}
String cleaned = s.replaceAll(holder_string, " ");
return cleaned;
}
private static String justify(String s, float width, Paint p){
while(p.measureText(s)<width){
s = justifyOperation(s,width, p);
}
return s;
}
}