package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.geom.Point; import flash.geom.Rectangle; import flash.text.engine.*; import flash.ui.Mouse; import flash.ui.MouseCursor; [SWF(width="400", height="125")] public class FTEDemo7 extends Sprite { private var beginIndex:int = -1; private var endIndex:int = -1; private var lines:Array = []; public function FTEDemo7() { var elements:Vector. = new Vector.(); elements.push( createTextElement('He ', 20), createTextElement('who loves ', 16), createTextElement('practice ', 26), createTextElement('without ', 16), createTextElement('theory ', 26), createTextElement('is like the ', 16), createTextElement('sailor ', 20), createTextElement('who boards his ship without a ', 16), createTextElement('rudder ', 26), createTextElement('and ', 16), createTextElement('compass ', 26), createTextElement('and ', 16), createTextElement('never knows where he may cast.', 24), createTextElement('\n - Leonardo da Vinci', 22) ); var i:int = 0; var block:TextBlock = new TextBlock(new GroupElement(elements)); var line:TextLine = block.createTextLine(null, 400); var _y:Number = 0; while(line) { lines.push(addChild(line)); _y += line.height; line.y = _y; line.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); line.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); line.addEventListener(MouseEvent.ROLL_OVER, onRoll); line.addEventListener(MouseEvent.ROLL_OUT, onRoll); line = block.createTextLine(line, 400); } } private function createTextElement(text:String, size:int):TextElement { return new TextElement(text, new ElementFormat( new FontDescription("Times", FontWeight.NORMAL, FontPosture.NORMAL, FontLookup.EMBEDDED_CFF), size) ); } private function onMouseDown(event:MouseEvent):void { stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); graphics.clear(); var line:TextLine = TextLine(event.target); beginIndex = line.textBlockBeginIndex + line.getAtomIndexAtPoint(event.stageX, event.stageY); } private function onMouseMove(event:MouseEvent):void { if(!event.buttonDown) return; var line:TextLine = TextLine(event.target); endIndex = line.textBlockBeginIndex + line.getAtomIndexAtPoint(event.stageX, event.stageY); drawBackground(beginIndex, endIndex); } private function onMouseUp(event:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); var objs:Array = getObjectsUnderPoint(new Point(event.stageX, event.stageY)); var obj:Object; var found:Boolean = false; while(objs.length) { if(objs.pop() is TextLine) { found = true; break; } } Mouse.cursor = found ? MouseCursor.IBEAM : MouseCursor.ARROW; } private function drawBackground(begin:int, end:int):void { graphics.clear(); if(begin > end) { var begin2:int = begin; begin = end; end = begin2; } var line:TextLine; for(var i:int = 0; i < lines.length; i++) { line = lines[i]; if(line.textBlockBeginIndex <= begin && (line.textBlockBeginIndex + line.rawTextLength) >= begin) break; } var startLine:TextLine = line; for(i = 0; i < lines.length; i++) { line = lines[i]; if(line.textBlockBeginIndex <= end && (line.textBlockBeginIndex + line.rawTextLength) >= end) break; } var endLine:TextLine = line; line = startLine; var bounds:Rectangle; // Don't ever do this! // I'm only doing this because I don't want errors // and I didn't have time to vet this math 100%. try { while(true) { if(line == null) break; if(line == startLine) { if(startLine == endLine) bounds = line.getAtomBounds(Math.min(Math.max(begin - line.textBlockBeginIndex, 0), line.rawTextLength - 1)).union(line.getAtomBounds(Math.min(Math.max(end - line.textBlockBeginIndex, 0), line.rawTextLength - 1))); else bounds = line.getAtomBounds(Math.min(Math.max(begin - line.textBlockBeginIndex, 0), line.rawTextLength - 1)).union(line.getAtomBounds(line.rawTextLength - 1)); bounds.x += line.x; bounds.y += line.y; } else if(line == endLine) { bounds = line.getAtomBounds(Math.min(Math.max(end - line.textBlockBeginIndex, 0), line.rawTextLength - 1)).union(line.getAtomBounds(0)); bounds.x += line.x; bounds.y += line.y; } else bounds = line.getBounds(line.parent); graphics.beginFill(0x003399, 0.25); graphics.drawRect(bounds.x, bounds.y, bounds.width, bounds.height); if(line == endLine) break; line = line.nextLine; } } catch(e:Error) { // Do noooothing } } private function onRoll(event:MouseEvent):void { Mouse.cursor = (event.type == MouseEvent.ROLL_OVER || event.buttonDown) ? MouseCursor.IBEAM : MouseCursor.ARROW; } [Embed(source="assets/Times New Roman.ttf", embedAsCFF="true", fontFamily="Times")] private var times:Class; } }