package com.partlyhuman.display
{
import flash.geom.*;
import flash.display.*;
import flash.text.*;
/**
* Wraps left-justified text around any DisplayObject to produce a right rag.
* See more information on http://www.partlyhuman.com/blog/roger/dynamic-text-wrapping-in-actionscript-3
*
* Work licensed under Creative Commons Attribution 3.0 United States License.
*
*
* @author Roger Braunstein
*/
public class WrapTextUtility
{
private static const KILL_LIMIT:int = 100;
private static const GUTTER:int = 2;
private static const NEWLINE:String = "\r";
private static const WHITESPACE:RegExp = /[\s\-\_]/;
public function WrapTextUtility()
{
}
public static function convertToText(tf:TextField):void
{
tf.condenseWhite = false;
tf.text = tf.text.replace(/
/ig, NEWLINE);
}
public static function wrapText(tf:TextField, edge:DisplayObject, paddingPx:int = 6, transparentBackground:Boolean = false, debugSurface:Graphics = null):void
{
if (debugSurface) debugSurface.clear();
if (!tf.hitTestObject(edge)) return;
var edgeOffset:Point = edge.localToGlobal(new Point()).subtract(tf.localToGlobal(new Point()));
var lineY:Number = GUTTER;
var bitmapSlice:BitmapData = new BitmapData(edge.width, edge.height, true, 0x00000000);
var i:int = 0;
do
{
try
{
var lineMetrics:TextLineMetrics = tf.getLineMetrics(i);
} catch (err:RangeError) {
break;
}
var lineBaseline:Number = lineY + lineMetrics.ascent;
bitmapSlice.fillRect(bitmapSlice.rect, 0x00000000);
var clipRect:Rectangle = new Rectangle(0, lineY - edgeOffset.y, edge.width, lineMetrics.ascent + lineMetrics.descent);
lineY += lineMetrics.height;
if (clipRect.width <= 0 || clipRect.height <= 0) continue;
if (clipRect.y >= edge.height || clipRect.y + clipRect.height <= 0) continue;
if (debugSurface)
{
debugSurface.lineStyle(1, 0x808080);
debugSurface.drawRect(edge.x + clipRect.x, edge.y + clipRect.y, clipRect.width, clipRect.height);
}
bitmapSlice.draw(edge, null, null, null, clipRect);
var colorRect:Rectangle = bitmapSlice.getColorBoundsRect((transparentBackground? 0xFF000000 : 0xFFFFFFFF), 0x00000000, false);
if (colorRect == null || colorRect.width <= 0 || colorRect.height <= 0) continue;
if (debugSurface)
{
debugSurface.lineStyle(1, 0x00FF00);
debugSurface.drawRect(edge.x + colorRect.x, edge.y + colorRect.y, colorRect.width, colorRect.height);
debugSurface.lineStyle(1, 0xFF0000);
debugSurface.moveTo(tf.x, tf.y + lineBaseline);
debugSurface.lineTo(tf.x + colorRect.x + edgeOffset.x - paddingPx, tf.y + lineBaseline);
}
var wrapChar:int = tf.getCharIndexAtPoint(colorRect.x + edgeOffset.x - paddingPx, lineBaseline);
var firstCharInLine:int = tf.getLineOffset(i);
var allText:String = tf.text;
if (wrapChar <= 0) continue;
while (allText.charAt(wrapChar).match(WHITESPACE) == null && wrapChar > firstCharInLine)
{
--wrapChar;
}
if (wrapChar <= firstCharInLine)
{
tf.text = allText.slice(0, firstCharInLine) + NEWLINE + allText.slice(firstCharInLine);
} else {
tf.text = allText.slice(0, wrapChar) + NEWLINE + allText.slice(wrapChar + 1);
}
} while (++i < KILL_LIMIT);
bitmapSlice.dispose();
}
}
}