You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ha...@apache.org on 2017/03/16 13:37:58 UTC

[38/42] flex-asjs git commit: And here’s TLF…

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ITextFlowLine.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ITextFlowLine.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ITextFlowLine.as
new file mode 100644
index 0000000..6fe88e8
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ITextFlowLine.as
@@ -0,0 +1,104 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.compose
+{
+	import org.apache.flex.core.IParentIUIBase;
+	import org.apache.flex.geom.Rectangle;
+	import org.apache.flex.graphics.ICompoundGraphic;
+	import org.apache.flex.text.engine.ITextBlock;
+	import org.apache.flex.text.engine.ITextLine;
+	import org.apache.flex.textLayout.container.IContainerController;
+	import org.apache.flex.textLayout.edit.SelectionFormat;
+	import org.apache.flex.textLayout.elements.IFlowLeafElement;
+	import org.apache.flex.textLayout.elements.IParagraphElement;
+	import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+	
+	public interface ITextFlowLine extends IVerticalJustificationLine
+	{
+		function get composable():Boolean;
+		function initialize(paragraph:IParagraphElement, outerTargetWidth:Number = 0, lineOffset:Number = 0, absoluteStart:int = 0, numChars:int = 0, textLine:ITextLine = null):void;
+		function get heightTW():int;
+		function get outerTargetWidthTW():int;
+		function get ascentTW():int;
+		function get targetWidthTW():int;
+		function get textHeightTW():int;
+		function get lineOffsetTW():int;
+		function get lineExtentTW():int;
+		function get hasGraphicElement():Boolean;
+		function get hasNumberLine():Boolean;
+		function get numberLinePosition():Number;
+		function set numberLinePosition(position:Number):void;
+		function get textHeight():Number ;
+		function get xTW():int;
+		function get yTW():int;
+		function setXYAndHeight(lineX:Number,lineY:Number,lineHeight:Number):void;
+		function get location():int;
+		function get controller():IContainerController;
+		function get columnIndex():int;
+		function setController(cont:IContainerController,colNumber:int):void;
+		function get lineOffset():Number;
+		function get paragraph():IParagraphElement;
+		function get absoluteStart():int;
+		function setAbsoluteStart(val:int):void;
+		function get textLength():int;
+		function setTextLength(val:int):void;
+		function get spaceBefore():Number;
+		function get spaceAfter():Number;
+		function get outerTargetWidth():Number;
+		function set outerTargetWidth(val:Number):void;
+		function get targetWidth():Number;
+		function getBounds():Rectangle;
+		function get validity():String;
+		function get unjustifiedTextWidth():Number;
+		function get lineExtent():Number;
+		function set lineExtent(value:Number):void;
+		function get accumulatedLineExtent():Number;
+		function set accumulatedLineExtent(value:Number):void;
+		function get accumulatedMinimumStart():Number;
+		function set accumulatedMinimumStart(value:Number):void;
+		function get alignment():String;
+		function set alignment(value:String):void;
+		function isDamaged():Boolean;
+		function clearDamage():void;
+		function damage(damageType:String):void;
+		function testLineVisible(wmode:String, x:int, y:int, w:int, h:int):int;
+		function oldTestLineVisible(wmode:String, x:int, y:int, w:int, h:int):Boolean;
+		function cacheLineBounds(wmode:String, bndsx:Number, bndsy:Number, bndsw:Number, bndsh:Number):void;
+		function hasLineBounds():Boolean;
+		function get textLineExists():Boolean;
+		function peekTextLine():ITextLine;
+		function getTextLine(forceValid:Boolean = false):ITextLine;
+		function recreateTextLine(textBlock:ITextBlock, previousLine:ITextLine):ITextLine;
+		function createShape(bp:String, textLine:ITextLine):void;
+		function createAdornments(blockProgression:String,elem:IFlowLeafElement,elemStart:int, textLine:ITextLine, numberLine:ITextLine):void;
+		function getLineLeading(bp:String,elem:IFlowLeafElement,elemStart:int):Number;
+		function getLineTypographicAscent(elem:IFlowLeafElement,elemStart:int,textLine:ITextLine):Number;
+		function getCSSLineBox(bp:String, elem:IFlowLeafElement, elemStart:int, swfContext:ISWFContext, effectiveListMarkerFormat:ITextLayoutFormat=null, numberLine:ITextLine=null):Rectangle;
+		function calculateSelectionBounds(textLine:ITextLine, rectArray:Array, begIdx:int, endIdx:int, blockProgression:String, heightAndAdj:Array):void;
+		function getRomanSelectionHeightAndVerticalAdjustment (prevLine:ITextFlowLine, nextLine:ITextFlowLine):Array;
+		function convertLineRectToContainer(rect:Rectangle, constrainShape:Boolean):void;
+		function hiliteBlockSelection(selObj:ICompoundGraphic, selFormat:SelectionFormat, container:IParentIUIBase, begIdx:int,endIdx:int, prevLine:ITextFlowLine, nextLine:ITextFlowLine):void;
+		function hilitePointSelection(selFormat:SelectionFormat, idx:int, container:IParentIUIBase, prevLine:ITextFlowLine, nextLine:ITextFlowLine):void;
+		function computePointSelectionRectangle(idx:int, container:IParentIUIBase, prevLine:ITextFlowLine, nextLine:ITextFlowLine, constrainSelRect:Boolean):Rectangle;
+		function selectionWillIntersectScrollRect(scrollRect:Rectangle, begIdx:int, endIdx:int, prevLine:ITextFlowLine, nextLine:ITextFlowLine):int;
+
+		function get adornCount():int ;
+
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ITextFlowTableBlock.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ITextFlowTableBlock.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ITextFlowTableBlock.as
new file mode 100644
index 0000000..6ad273a
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ITextFlowTableBlock.as
@@ -0,0 +1,46 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.compose
+{
+	import org.apache.flex.textLayout.elements.CellCoordinates;
+	import org.apache.flex.textLayout.elements.ITableElement;
+	import org.apache.flex.textLayout.elements.TableBlockContainer;
+	import org.apache.flex.textLayout.elements.CellContainer;
+	import org.apache.flex.textLayout.elements.ITableCellElement;
+	import org.apache.flex.textLayout.elements.TableCellElement;
+
+	public interface ITextFlowTableBlock extends ITextFlowLine
+	{
+		function clear():void;
+
+		function getTableCells():Vector.<ITableCellElement>;
+
+		function addCell(container:CellContainer):void;
+
+		function get container():TableBlockContainer
+
+		function get parentTable():ITableElement;
+
+		function updateCompositionShapes():void;
+
+		function set parentTable(parentTable:ITableElement):void;
+
+		function getCellsInRange(startCoords:CellCoordinates, endCoords:CellCoordinates):Vector.<ITableCellElement>;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/IVerticalJustificationLine.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/IVerticalJustificationLine.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/IVerticalJustificationLine.as
new file mode 100644
index 0000000..ee6a315
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/IVerticalJustificationLine.as
@@ -0,0 +1,95 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.compose {
+	import org.apache.flex.textLayout.elements.IParagraphElement;
+	import org.apache.flex.text.engine.ITextLine;
+	
+	/** 
+	 * The IVerticalJustificationLine interface defines the methods and properties required to allow
+	 * the vertical justification of text lines.
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public interface IVerticalJustificationLine
+	{
+		/** 
+		 * The horizontal position of the line relative to its container, expressed as the offset in pixels from the 
+		 * left of the container.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #y
+		 */
+		function get x():Number;
+		
+		/** Set X location for the line.  Used only during vertical justification. @private */
+		function set x(val:Number):void;
+		
+		/** 
+		 * The vertical position of the line relative to its container, expressed as the offset in pixels from the top 
+		 * of the container.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see #x
+		 */
+		function get y():Number;
+		
+		/** Set Y location for the line.  Used only during vertical justification. @private */
+		function set y(val:Number):void;
+		
+		/** 
+		 * @copy org.apache.flex.text.engine.TextLine#ascent
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		function get ascent():Number;
+		
+		/** 
+		 * @copy org.apache.flex.text.engine.TextLine#descent
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		function get descent():Number;
+		
+		/** The height of the line in pixels.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 */
+		function get height():Number;
+		
+
+		// TODO for TextFlowTableBloack
+		function set height(value:Number):void;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/Parcel.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/Parcel.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/Parcel.as
new file mode 100644
index 0000000..51fb80d
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/Parcel.as
@@ -0,0 +1,376 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.compose
+{
+	import org.apache.flex.text.engine.Constants;
+		
+	import org.apache.flex.textLayout.container.IContainerController;
+//	import org.apache.flex.textLayout.debug.assert;
+	import org.apache.flex.textLayout.formats.ClearFloats;
+	import org.apache.flex.textLayout.formats.Direction;
+
+
+
+		
+	/** 
+	 * Helper class for implementations of IParcelList
+	 * 
+	 * @private
+	 */
+	public class Parcel 
+	{
+		public var x:Number;
+		public var y:Number;
+		public var width:Number;
+		public var height:Number;
+		public var logicalWidth:Number;
+
+		private var _controller:IContainerController;
+		private var _columnIndex:int;
+		private var _fitAny:Boolean;
+		private var _composeToPosition:Boolean;
+
+		private var _left:Edge;
+		private var _right:Edge;
+		private var _maxWidth:Number;
+		
+		private const EDGE_CACHE_MAX:int = 6;		// number of edges we cache
+		static private var edgeCache:Vector.<Edge>; // cache to prevent edge allocation/deallocation
+		
+		private var _verticalText:Boolean;
+		
+		/** Constructor. */
+		public function Parcel(verticalText:Boolean, x:Number, y:Number, width:Number, height:Number, controller:IContainerController, columnIndex:int)
+		{
+			initialize(verticalText, x, y, width, height, controller, columnIndex);
+		}
+		
+		public function initialize(verticalText:Boolean, x:Number, y:Number, width:Number, height:Number, controller:IContainerController, columnIndex:int):Parcel
+		{
+			this.x = x;
+			this.y = y;
+			this.width = width;
+			this.height = height;
+			this.logicalWidth = verticalText ? height : width;
+			this._verticalText = verticalText; 
+			
+			_controller   = controller;
+			_columnIndex  =  columnIndex;
+			_fitAny	  = false;
+			_composeToPosition = false;
+			
+			var xmin:Number;
+			if (verticalText)
+			{
+				xmin = y;
+				_maxWidth = height;
+			}
+			else
+			{
+				xmin = x;
+				_maxWidth = width;
+			}
+
+			_left = allocateEdge(xmin);
+			_right = allocateEdge(xmin + _maxWidth);		
+			return this;
+		}
+		
+		
+		/** prevent any leaks. @private */
+		public function releaseAnyReferences():void
+		{
+			_controller = null;
+			deallocateEdge(_left);
+			deallocateEdge(_right);
+		}
+		
+		private function allocateEdge(x:Number):Edge
+		{
+			if (!edgeCache)
+			 edgeCache = new Vector.<Edge>();
+			var edge:Edge = (edgeCache.length > 0) ? edgeCache.pop() : new Edge();
+			edge.initialize(x);
+			return edge;
+		}
+		
+		private function deallocateEdge(edge:Edge):void
+		{
+			if (edgeCache.length < EDGE_CACHE_MAX)
+				edgeCache.push(edge);
+		}
+		
+		public function get bottom():Number	{ return (y + height); }
+		public function get right():Number	{ return (x + width); }
+		
+		public function get controller():IContainerController
+		{ return _controller; }
+
+		/** column number in the container */
+		public function get columnIndex():int
+		{ return _columnIndex; }
+		public function get fitAny():Boolean
+		{ return _fitAny; }
+		public function set fitAny(value:Boolean):void
+		{ _fitAny = value; }
+		public function get composeToPosition():Boolean
+		{ return _composeToPosition; }
+		public function set composeToPosition(value:Boolean):void
+		{ _composeToPosition = value; }
+		/** Do explicit line breaking (no wrapping) */
+
+		private function getLogicalHeight():Number
+		{
+			if (_verticalText)
+			{
+				return _controller.measureWidth ? Constants.MAX_LINE_WIDTH : width;
+			}
+			else
+			{
+				return _controller.measureHeight ? Constants.MAX_LINE_WIDTH : height;
+			}
+		}
+		
+		// Returns the amount to move down to apply clear past any floats
+		public function applyClear(clear:String, depth:Number, direction:String):Number
+		{
+			var leftMargin:Number;
+			var rightMargin:Number;
+			var adjustedDepth:Number = depth;
+			
+			if (clear == ClearFloats.START)
+				clear = (direction == Direction.LTR) ? ClearFloats.LEFT : ClearFloats.RIGHT;
+			else if (clear == ClearFloats.END)
+				clear = (direction == Direction.RTL) ? ClearFloats.LEFT : ClearFloats.RIGHT;
+
+			while (adjustedDepth < Number.MAX_VALUE)
+			{
+				leftMargin = _left.getMaxForSpan(adjustedDepth, adjustedDepth + 1);	// getLeftForSpan
+				if (leftMargin > 0 && (clear == ClearFloats.BOTH || clear == ClearFloats.LEFT))
+				{
+					adjustedDepth = _left.findNextTransition(adjustedDepth);
+					continue;
+				}
+				rightMargin = _right.getMaxForSpan(adjustedDepth, adjustedDepth + 1);	// getRightForSpan
+				if (rightMargin > 0 && (clear == ClearFloats.BOTH || clear == ClearFloats.RIGHT))
+				{
+					adjustedDepth = _right.findNextTransition(adjustedDepth);
+					continue;
+				}
+				
+				return adjustedDepth - depth;
+			} 
+			
+			return (_verticalText ? this.width : this.height);	
+		}
+		
+		public function fitsInHeight(depth:Number, minimumHeight:Number):Boolean
+		{
+			return composeToPosition || depth + minimumHeight <= getLogicalHeight();
+		}
+		
+		// Given a current location, what is the longest longest line of a given height that can be placed there,
+		// that is at least as wide as the minimum width. Return false if there is no possible line in the parcel.
+		// May shift the line down if thee is more space below.
+		public function getLineSlug(slug:Slug, depth:Number, lineHeight:Number, minimumWidth:Number, minimumHeight:Number, leftMargin:Number, rightMargin:Number, textIndent:Number, directionLTR:Boolean, useExplicitLineBreaks:Boolean):Boolean
+		{
+			if (!fitsInHeight(depth, minimumHeight))
+				return false;
+			
+			slug.height = lineHeight;			
+
+			while (depth < Number.MAX_VALUE)
+			{
+				slug.depth = depth;
+
+				slug.leftMargin = _left.getMaxForSpan(slug.depth, slug.depth + lineHeight);	// getLeftForSpan
+				slug.wrapsKnockOut = slug.leftMargin != 0;
+				if (leftMargin > 0)
+					slug.leftMargin = Math.max(leftMargin, slug.leftMargin);
+				else
+					slug.leftMargin += leftMargin;		// negative indent, let it overlap
+				slug.rightMargin = _right.getMaxForSpan(slug.depth, slug.depth + lineHeight);	// getRightForSpan
+				slug.wrapsKnockOut = slug.wrapsKnockOut || (slug.rightMargin != 0);
+				if (rightMargin > 0)
+					slug.rightMargin = Math.max(rightMargin, slug.rightMargin);
+				else
+					slug.rightMargin += rightMargin;		// negative indent, let it overlap
+				if (textIndent)
+				{
+					if (directionLTR)
+						slug.leftMargin += textIndent;
+					else
+						slug.rightMargin += textIndent;
+				}
+
+				if (useExplicitLineBreaks || (_verticalText && _controller.measureHeight) || (!_verticalText && _controller.measureWidth))
+					slug.width = Constants.MAX_LINE_WIDTH;
+				else
+					slug.width = this.logicalWidth - (slug.leftMargin + slug.rightMargin);
+				if (!minimumWidth || slug.width >= minimumWidth)
+					break;
+				depth = findNextTransition(depth);
+			} 
+			
+			return (depth < Number.MAX_VALUE);
+		}
+
+		public function knockOut(knockOutWidth:Number, yMin:Number, yMax:Number, onLeft:Boolean):void
+		{
+			var edge:Edge = onLeft ? _left : _right;
+			edge.addSpan(knockOutWidth, yMin, yMax);	
+		}
+		
+		public function removeKnockOut(knockOutWidth:Number, yMin:Number, yMax:Number, onLeft:Boolean):void
+		{
+			var edge:Edge = onLeft ? _left : _right;
+			edge.removeSpan(knockOutWidth, yMin, yMax);	
+		}
+		
+		/** Returns true if the parcel has no knockouts */
+		public function isRectangular():Boolean
+		{
+			return (_left.numSpans <= 0 && _right.numSpans <= 0);
+		}
+		
+	/*	public function getLeftForSpan(ymin:Number, ymax:Number):Number
+		{
+			return _left.getMaxForSpan(ymin, ymax);
+		}
+		
+		public function getRightForSpan(ymin:Number, ymax:Number):Number
+		{
+			return _right.getMinForSpan(ymin, ymax);
+		} */
+		
+		public function findNextTransition(y:Number):Number
+		{
+			return Math.min(_left.findNextTransition(y), _right.findNextTransition(y));
+		}
+		
+	}
+}
+
+class Span
+{
+	public var x:Number;
+	public var ymin:Number;
+	public var ymax:Number;
+	
+	public function Span(x:Number, ymin:Number, ymax:Number)
+	{
+		this.x = x;
+		this.ymin = ymin;
+		this.ymax = ymax;
+	}
+		
+	public function overlapsInY(ymin:Number, ymax:Number):Boolean
+	{
+		return !(ymax < this.ymin || ymin >= this.ymax);
+	}
+	
+	public function equals(x:Number, ymin:Number, ymax:Number):Boolean
+	{
+		return x == this.x && ymin == this.ymin && ymax == this.ymax;
+	} 
+}
+
+//import org.apache.flex.textLayout.utils.Twips;
+
+class Edge
+{
+	private var _xbase:Number;
+	private var _spanList:Vector.<Span>;
+	
+	public function Edge()
+	{
+		_spanList = new Vector.<Span>();
+	}
+	
+	public function initialize(xbase:Number):void
+	{
+		_xbase = xbase;
+		_spanList.length = 0;
+	}
+	
+	public function get base():Number
+	{
+		return _xbase;
+	}
+	
+	public function addSpan(x:Number, ymin:Number, ymax:Number):void
+	{
+		_spanList.push(new Span(x, ymin, ymax));
+	}
+	
+	public function removeSpan(x:Number, ymin:Number, ymax:Number):void
+	{
+		for (var i:int=0; i < _spanList.length; ++i)
+		{
+			if (_spanList[i].equals(x, ymin, ymax))
+			{
+				_spanList.splice(i,1);
+				return;
+			}
+		}
+
+//		CONFIG::debug { org.apache.flex.textLayout.debug.assert(false, "Deleting a span not in list"); }			
+	} 
+	
+	public function get numSpans():int
+	{
+		return _spanList.length;
+	}
+	
+	public function getMaxForSpan(ymin:Number, ymax:Number):Number
+	{
+		var res:Number = 0;
+		for each (var span:Span in _spanList)
+		{
+			if (span.x > res && span.overlapsInY(ymin, ymax))
+				res = span.x;
+		}
+		return res;
+	}
+	
+	/*public function getMinForSpan(ymin:Number, ymax:Number):Number
+	{
+		var res:Number = _xbase;
+		for each (var span:Span in _spanList)
+		{
+			if (span.x < res && span.overlapsInY(ymin, ymax))
+				res = span.x;
+		}
+		return res;
+	} */
+	
+	public function findNextTransition(y:Number):Number
+	{
+		var res:Number = Number.MAX_VALUE;
+		for each (var s:Span in _spanList)
+		{
+			if (s.ymin > y && s.ymin < res)
+				res = s.ymin;
+			if (s.ymax > y && s.ymax < res)
+				res = s.ymax;
+		}
+		return res;
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ParcelList.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ParcelList.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ParcelList.as
new file mode 100644
index 0000000..9f2cfbb
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/ParcelList.as
@@ -0,0 +1,438 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.compose
+{
+	import org.apache.flex.text.engine.Constants;
+	import org.apache.flex.geom.Rectangle;
+	
+	import org.apache.flex.textLayout.container.ColumnState;
+	import org.apache.flex.textLayout.container.IContainerController;
+	import org.apache.flex.textLayout.container.ScrollPolicy;
+	import org.apache.flex.textLayout.debug.assert;
+	import org.apache.flex.textLayout.elements.TableCellElement;
+	import org.apache.flex.textLayout.formats.BlockProgression;
+	import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+	import org.apache.flex.textLayout.formats.LineBreak;
+
+	
+
+			
+	/** @private
+	 * Used for composing text containers, keeps track of the areas that text in the 
+	 * flow is composed into.
+	 * 
+	 * ParcelList will always have one parcel, which corresponds to the container's
+	 * bounding box. 
+	 */
+	public class ParcelList
+	{
+		protected var _flowComposer:IFlowComposer;
+		
+		/** Current vertical position in the parcel. */
+		protected var _totalDepth:Number;
+		
+		/** whether the current parcel has any content */
+		protected var _hasContent:Boolean;
+		
+		/** The list of parcels that are available for text layout.
+			They are appear in the array in reading order: the first text goes in the
+			first parcel, when it gets filled later text is flowed into the second 
+			parcel, and so on.  */
+		protected var _parcelArray:Array;	/* of Parcel */
+		protected var _numParcels:int;
+		protected var _singleParcel:Parcel;
+		
+		/** Index of the "current" parcel. These next two variables must be kept in sync. */
+		protected var _currentParcelIndex:int;
+		protected var _currentParcel:Parcel;
+		
+		protected var _insideListItemMargin:Number;
+		
+		protected var _leftMargin:Number;
+		protected var _rightMargin:Number; 
+		
+		protected var _explicitLineBreaks:Boolean;
+			
+		/** True if text is vertical (as for some Japanese & Chinese, false otherwise */
+		protected var _verticalText:Boolean;
+		
+//		private static const MAX_HEIGHT:Number = 900000000;		// vertical scroll max - capped to prevent loss of precision - what should it be?
+//		private static const MAX_WIDTH:Number =  900000000;		// horizontal scroll max - capped to prevent loss of precision - what should it be?
+			
+		// a single parcellist that is checked out and checked in
+		static private var _sharedParcelList:ParcelList;
+
+		/** @private */
+		static public function getParcelList():ParcelList
+		{
+			var rslt:ParcelList = _sharedParcelList ? _sharedParcelList : new ParcelList();
+			_sharedParcelList = null;
+			return rslt;
+		}
+		
+		/** @private */
+		static public function releaseParcelList(list:ParcelList):void
+		{
+			if (_sharedParcelList == null)
+			{
+				_sharedParcelList = list as ParcelList;
+				if (_sharedParcelList)
+					_sharedParcelList.releaseAnyReferences();
+			}
+		}
+
+		/** Constructor. */
+		public function ParcelList()
+		{ _numParcels = 0;	}
+		
+		/** prevent any leaks. @private */
+		public function releaseAnyReferences():void
+		{
+			this._flowComposer = null;
+			
+			_numParcels = 0;
+			_parcelArray = null;
+			
+			if (_singleParcel)
+				_singleParcel.releaseAnyReferences();
+		}
+		
+		CONFIG::debug public function getBounds():Array
+		{
+			var boundsArray:Array = [];
+			for (var i:int = 0; i < _numParcels; ++i)
+				boundsArray.push(getParcelAt(i));
+			return boundsArray;
+		}
+		
+		public function getParcelAt(idx:int):Parcel
+		{ return _numParcels <= 1 ? _singleParcel : _parcelArray[idx]; }
+				
+		public function get currentParcelIndex():int
+		{ return _currentParcelIndex; }
+		
+		public function get explicitLineBreaks():Boolean
+		{ 
+			return _explicitLineBreaks;
+		}
+		
+		private function get measureLogicalWidth():Boolean
+		{
+			if (_explicitLineBreaks)
+				return true;
+			if (!_currentParcel)
+				return false;
+			var controller:IContainerController = _currentParcel.controller;
+			return _verticalText ? controller.measureHeight : controller.measureWidth;
+		}
+
+		private function get measureLogicalHeight():Boolean
+		{
+			if (!_currentParcel)
+				return false;
+			var controller:IContainerController = _currentParcel.controller;
+			return _verticalText ? controller.measureWidth : controller.measureHeight;
+		}
+		
+		public function get totalDepth():Number
+		{
+			return _totalDepth;
+		}
+		
+		public function addTotalDepth(value:Number):Number
+		{
+			_totalDepth += value;	
+		//	trace("addTotalDepth", value, "newDepth", totalDepth);
+			return _totalDepth;
+		}
+		
+		protected function reset():void
+		{
+			// Composition starts with an initial invalid parcel. It will start by calling next(), which will 
+			// advance to the first parcel.
+			_totalDepth = 0;
+			_hasContent = false;
+
+			_currentParcelIndex = -1;
+			_currentParcel = null;
+			
+			_leftMargin = 0;
+			_rightMargin = 0;
+			_insideListItemMargin = 0;
+		}
+		
+		public function addParcel(column:Rectangle, controller:IContainerController, columnIndex:int):Parcel
+		{
+			var newParcel:Parcel = _numParcels == 0 && _singleParcel 
+				? _singleParcel.initialize(_verticalText, column.x,column.y,column.width,column.height,controller,columnIndex) 
+				: new Parcel(_verticalText, column.x, column.y, column.width, column.height, controller, columnIndex);
+			if (_numParcels == 0)
+				_singleParcel = newParcel;
+			else if (_numParcels == 1)
+				_parcelArray = [  _singleParcel, newParcel ];
+			else
+				_parcelArray.push(newParcel);
+			_numParcels++;
+			return newParcel;
+		}
+		
+		// Return numbers of parcels in this parcel list
+		public function numParcels():int
+		{
+			return this._numParcels;
+		}
+		
+		// Pop up top most parcel
+		public function popParcel():Parcel
+		{
+			_numParcels -- ;
+			return _parcelArray.pop();
+		}
+		
+		public function addTableCell2ColumnState(controller:IContainerController, cell:TableCellElement):void
+		{
+			var columnState:ColumnState = controller.columnState;
+			if (columnState)
+				columnState.pushTableCell(cell);
+		}
+		protected function addOneControllerToParcelList(controllerToInitialize:IContainerController):void
+		{
+			// Initialize new parcels for columns
+			var columnState:ColumnState = controllerToInitialize.columnState;
+			columnState.clearCellList();
+			for (var columnIndex:int = 0; columnIndex < columnState.columnCount; columnIndex++)
+			{
+				var column:Rectangle = columnState.getColumnAt(columnIndex);
+				if (!column.isEmpty())
+					addParcel(column, controllerToInitialize, columnIndex);
+			}
+		}
+		
+		public function beginCompose(composer:IFlowComposer, controllerStartIndex:int, controllerEndIndex:int, composeToPosition:Boolean):void
+		{
+			_flowComposer = composer;
+			
+			var rootFormat:ITextLayoutFormat = composer.rootElement.computedFormat;
+			_explicitLineBreaks = rootFormat.lineBreak == LineBreak.EXPLICIT;
+			_verticalText   = (rootFormat.blockProgression == BlockProgression.RL);
+			
+			if (composer.numControllers != 0)
+			{
+				// if controllerEndIndex is not specified then assume we are composing to position and add all controllers
+				if (controllerEndIndex < 0)
+					controllerEndIndex = composer.numControllers-1;
+				else
+					controllerEndIndex = Math.min(controllerEndIndex,composer.numControllers-1);
+				var idx:int = controllerStartIndex;
+				do
+				{
+					addOneControllerToParcelList(IContainerController(composer.getControllerAt(idx)));
+				} while (idx++ != controllerEndIndex);
+				// adjust the last container for scrolling
+				if (controllerEndIndex == composer.numControllers-1)
+					adjustForScroll(composer.getControllerAt(composer.numControllers-1), composeToPosition);
+			}
+			reset();
+		}
+		
+		/** Adjust the size of the parcel corresponding to the last column of the containter, in 
+		 * order to account for scrolling.
+		 */
+		private function adjustForScroll(containerToInitialize:IContainerController, composeToPosition:Boolean):void
+		{			
+			// Expand the last parcel if scrolling could be enabled. Expand to twice what would fit in available space. 
+			// We will start composing from the top, so if we've scrolled down there will be more to compose.
+			// We turn on fitAny, so that lines will be included in the container even if only a tiny portion of the line
+			// fits. This makes lines that are only partially scrolling in appear. We turn on composeToPosition if we're
+			// forcing composition to go through a given position -- this will make all lines fit, and composition will
+			// continue until it is past the supplied position.
+			var p:Parcel;
+			if (_verticalText)
+			{
+				if (containerToInitialize.horizontalScrollPolicy != ScrollPolicy.OFF)
+				{
+					p = getParcelAt(_numParcels-1);
+					if (p)
+					{
+						var horizontalPaddingAmount:Number = containerToInitialize.getTotalPaddingRight() + containerToInitialize.getTotalPaddingLeft();
+						var right:Number = p.right;
+						p.x = containerToInitialize.horizontalScrollPosition - p.width - horizontalPaddingAmount;
+						p.width = right - p.x;
+						p.fitAny = true;
+						p.composeToPosition = composeToPosition;
+					}
+				}
+			}
+			else
+			{
+				if (containerToInitialize.verticalScrollPolicy != ScrollPolicy.OFF)
+				{
+					p = getParcelAt(_numParcels-1);
+					if (p)
+					{
+						var verticalPaddingAmount:Number = containerToInitialize.getTotalPaddingBottom() + containerToInitialize.getTotalPaddingTop();
+						p.height = (containerToInitialize.verticalScrollPosition + p.height + verticalPaddingAmount) - p.y;
+						p.fitAny = true;
+						p.composeToPosition = composeToPosition;
+					}
+				}
+			}
+		}
+
+		public function get leftMargin():Number
+		{
+			return _leftMargin;
+		}
+		
+		public function pushLeftMargin(leftMargin:Number):void
+		{
+			_leftMargin += leftMargin;	
+		}
+		
+		public function popLeftMargin(leftMargin:Number):void
+		{
+			_leftMargin -= leftMargin;	
+		}
+					
+		public function get rightMargin():Number
+		{
+			return _rightMargin;
+		}
+		
+		public function pushRightMargin(rightMargin:Number):void
+		{
+			_rightMargin += rightMargin;	
+		}
+		
+		public function popRightMargin(rightMargin:Number):void
+		{
+			_rightMargin -= rightMargin;	
+		}
+		
+		public function pushInsideListItemMargin(margin:Number):void
+		{ _insideListItemMargin += margin; }
+		public function popInsideListItemMargin(margin:Number):void
+		{ _insideListItemMargin -= margin; }	
+		public function get insideListItemMargin():Number
+		{ return _insideListItemMargin; }
+		
+		public		function getComposeXCoord(o:Rectangle):Number
+		{ 
+			// trace("LPL: getComposeXCoord");
+			return _verticalText ? o.right : o.left;
+		}
+		public		function getComposeYCoord(o:Rectangle):Number
+		{ 
+			// trace("LPL: getComposeYCoord");
+			return o.top;
+		}
+
+		public function getComposeWidth(o:Rectangle):Number
+		{ 
+			// trace("LPL: getComposeWidth");
+			if (measureLogicalWidth)
+				return Constants.MAX_LINE_WIDTH;
+			return _verticalText ? o.height : o.width; 
+		}
+
+		public function getComposeHeight(o:Rectangle):Number
+		{ 
+			// trace("LPL: getComposeHeight");
+			if (measureLogicalHeight)
+				return Constants.MAX_LINE_WIDTH;
+			return _verticalText ? o.width : o.height; 
+		}		
+
+		/** Returns true if the current parcel is the last.
+		*/
+		public function atLast():Boolean
+		{
+			return _numParcels == 0 || _currentParcelIndex == _numParcels -1;
+		}
+		
+		public function atEnd():Boolean
+		{
+			return _numParcels == 0 || _currentParcelIndex >= _numParcels;
+		}
+		
+		public function gotoParcel(index:int, depth:Number = 0):Boolean
+		{
+			if ( index < 0 || index >= _numParcels )
+				return false;
+			
+			_currentParcel = this.getParcelAt(index);
+			if ( _currentParcel == null )
+				return false;
+			_currentParcelIndex = index;
+			
+			_totalDepth = depth;
+			
+			return true;
+		}
+		
+		public function next():Boolean
+		{
+			CONFIG::debug { assert(_currentParcelIndex >= -1 && _currentParcelIndex < _numParcels, "invalid _currentParcelIndex in ParcelList"); }			
+			var nextParcelIsValid:Boolean = (_currentParcelIndex + 1) < _numParcels;
+
+			_currentParcelIndex += 1;
+			_totalDepth = 0;
+
+			if (nextParcelIsValid)
+			{
+				_currentParcel = getParcelAt(_currentParcelIndex);
+			}
+			else
+				_currentParcel = null;
+	
+			return nextParcelIsValid;
+		}
+		
+		public function get currentParcel():Parcel
+		{ return _currentParcel; }
+
+		/**Return the slug rectangle for a line that goes at the current vertical location,
+		 * and could extend down for at least height pixels. Note that this function
+		 * can change the current parcel, and the location within the parcel.
+		 * @param slugRect result rectangle where line was fit
+		 * @param height	amount of contiguous vertical space that must be available
+		 * @param minWidth	amount of contiguous horizontal space that must be available 
+		 * @return true if a line slug was fit horizontal space actually available
+		 */
+		public function getLineSlug(slug:Slug, height:Number, minWidth:Number, textIndent:Number, directionLTR:Boolean):Boolean
+		{
+			if (currentParcel.getLineSlug(slug, _totalDepth, height, minWidth, currentParcel.fitAny ? 1 : int(height), _leftMargin, _rightMargin, textIndent+_insideListItemMargin, directionLTR,  _explicitLineBreaks))
+			{
+				if (totalDepth != slug.depth)
+					_totalDepth = slug.depth;
+				return true;
+			}
+			return false;
+		}
+	
+		// Attempts to fit a float of the specified width and height in the current parcel. Float is considered to fit if it
+		// is alone on the line but exceeds the parcel width and fits within the logical height.
+		// Returns success or failure.
+		public function fitFloat(slug:Slug, totalDepth:Number, width:Number, height:Number):Boolean
+		{
+			return currentParcel.getLineSlug(slug, totalDepth, height, width, currentParcel.fitAny ? 1 : int(height), _leftMargin, _rightMargin, 0, true, _explicitLineBreaks);
+		}
+				
+	}	//end class
+} //end package

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/SWFContext.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/SWFContext.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/SWFContext.as
new file mode 100644
index 0000000..f3e2e8d
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/SWFContext.as
@@ -0,0 +1,85 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.compose {
+	import org.apache.flex.textLayout.compose.ISWFContext;
+
+	public class SWFContext implements ISWFContext {
+		public function callInContext(fn : Function, thisArg : Object, argArray : Array, returns : Boolean = true) : * {
+		}
+		public static function get globalSWFContext():ISWFContext
+		{ 
+			return GlobalSWFContext.globalSWFContext; 
+		}
+	}
+}
+import org.apache.flex.textLayout.compose.ISWFContext;
+import org.apache.flex.textLayout.debug.Debugging;
+class GlobalSWFContext implements ISWFContext
+{
+	public function GlobalSWFContext()
+	{ }
+
+	static public const globalSWFContext:GlobalSWFContext = new GlobalSWFContext();
+	
+	public function callInContext(fn:Function, thisArg:Object, argsArray:Array, returns:Boolean=true):*
+	{
+		CONFIG::debug
+		{
+			var rslt:*;
+			try
+			{
+				if (returns)
+					rslt = fn.apply(thisArg, argsArray);
+
+				else
+					fn.apply(thisArg, argsArray);
+					
+				if (thisArg)
+				{
+					var traceArgs:Array;
+					// later make this table driven
+					if (thisArg.hasOwnProperty("createTextLine") && fn == thisArg["createTextLine"])
+					{
+						traceArgs = [rslt,thisArg,"createTextLine"];
+						traceArgs.push.apply(traceArgs, argsArray);
+						Debugging.traceFTECall.apply(null,traceArgs);
+					}
+					else if (thisArg.hasOwnProperty("recreateTextLine") && fn == thisArg["recreateTextLine"])
+					{
+						traceArgs = [rslt,thisArg,"recreateTextLine"];
+						traceArgs.push.apply(traceArgs, argsArray);
+						Debugging.traceFTECall.apply(null,traceArgs);
+					}
+				}
+			}
+			catch(e:Error)
+			{
+				// trace(e);
+				throw(e);
+			}
+			return rslt;
+		}
+		CONFIG::release
+		{
+			if (returns)
+				return fn.apply(thisArg, argsArray);
+			fn.apply(thisArg, argsArray);
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/SimpleCompose.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/SimpleCompose.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/SimpleCompose.as
new file mode 100644
index 0000000..013532c
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/SimpleCompose.as
@@ -0,0 +1,442 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.compose
+{
+	import org.apache.flex.textLayout.compose.utils.NumberlineUtil;
+	import org.apache.flex.textLayout.compose.utils.TextLineUtil;
+	import org.apache.flex.text.engine.Constants;
+	import org.apache.flex.text.engine.ITextLine;
+	import org.apache.flex.textLayout.container.IContainerController;
+	import org.apache.flex.textLayout.debug.Debugging;
+	import org.apache.flex.textLayout.debug.assert;
+	import org.apache.flex.textLayout.elements.IFlowGroupElement;
+	import org.apache.flex.textLayout.elements.IFlowLeafElement;
+	import org.apache.flex.textLayout.elements.IParagraphElement;
+	import org.apache.flex.textLayout.elements.ITextFlow;
+	import org.apache.flex.textLayout.formats.BlockProgression;
+	import org.apache.flex.textLayout.formats.Direction;
+	import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+	import org.apache.flex.textLayout.formats.VerticalAlign;
+
+	
+
+
+	// [ExcludeClass]
+	/** Keeps track of internal state during composition. 
+	 * 
+	 * This is the simpler version, used when there are no floats, no wraps, no columns.
+	 * @private
+	 */
+	public class SimpleCompose extends BaseCompose implements ISimpleCompose	{
+		// reusable scratch TextFlowLine
+		protected var workingLine:ITextFlowLine = new TextFlowLine(null, null);
+		
+		// resulting TextLines
+		private var _lines:Array;
+		
+		// scratch aligns for VJ
+		private var _vjLines:Array;
+		
+		// for figuring out when to do VJ
+		private var vjBeginLineIndex:int = 0;
+		private var vjDisableThisParcel:Boolean = false;
+		private var vjType:String;
+		
+		// accumulator for absolute start computation to support truncation 
+		private var _totalLength:Number;
+		
+		/** Constructor. */
+		public function  SimpleCompose()
+		{	
+			super();
+			_lines = new Array();
+			_vjLines = new Array();
+		}
+		
+		/** @private */
+		protected override function createParcelList():ParcelList
+		{
+			return ParcelList.getParcelList();
+		}
+		/** @private */
+		protected override function releaseParcelList(list:ParcelList):void
+		{
+			ParcelList.releaseParcelList(list);
+		}	
+
+		protected override function  initializeForComposer(composer:IFlowComposer, composeToPosition:int, controllerStartIndex:int, controllerEndIndex:int):void
+		{
+			// Always compose from the start of the flow
+			_startController = composer.getControllerAt(0);
+			_startComposePosition = 0;
+			super.initializeForComposer(composer, composeToPosition, 0, controllerEndIndex);
+			
+			// vj support
+			_vjLines.splice(0);
+			vjBeginLineIndex = 0;
+			vjDisableThisParcel = false;
+			vjType =_startController.computedFormat.verticalAlign;
+		}
+
+		/** @private */
+		public override function composeTextFlow(textFlow:ITextFlow, composeToPosition:int, controllerEndIndex:int):int
+		{
+			_flowComposer = textFlow.flowComposer as IFlowComposer;
+			_curLine = workingLine;
+			CONFIG::debug { assert (_curLine != null, "_curLine is null"); }
+			// empty out lines array
+			_lines.splice(0);
+			// accumulator initialization
+			_totalLength = 0;
+			
+			return super.composeTextFlow(textFlow, composeToPosition, controllerEndIndex);
+		}
+		
+ 		override protected function doVerticalAlignment(canVerticalAlign:Boolean,nextParcel:Parcel):void
+ 		{
+			var vjParcel:Parcel = parcelList.currentParcel;
+
+			if (canVerticalAlign && vjType != VerticalAlign.TOP && vjBeginLineIndex != _lines.length &&  !vjDisableThisParcel)
+			{
+				var controller:IContainerController = _curParcel.controller;
+				var beginFloatIndex:int = 0;
+				var endFloatIndex:int = 0;
+				if (controller.numFloats > 0)
+				{
+					beginFloatIndex = controller.findFloatIndexAtOrAfter(_curParcelStart);
+					endFloatIndex = controller.findFloatIndexAfter(_curElementStart + _curElementOffset);
+				}
+				applyVerticalAlignmentToColumn(vjParcel.controller,vjType,_vjLines,0,_vjLines.length, beginFloatIndex, endFloatIndex);
+			}
+
+			_vjLines.splice(0);
+			vjBeginLineIndex = _lines.length;
+			vjDisableThisParcel = false;
+			if (nextParcel)
+				vjType = nextParcel.controller.computedFormat.verticalAlign;
+ 		}
+ 		
+		// all lines are visible in the factory
+		override protected function isLineVisible(textLine:ITextLine):Boolean
+		{ return textLine != null; }
+		
+		/** Called when we are finished composing a line. Handler for derived classes to override default behavior.  */
+		override protected function endLine(textLine:ITextLine):void
+		{
+			super.endLine(textLine);
+			
+			_curLine.createShape(_blockProgression, textLine);
+			
+			if (textFlow.backgroundManager)
+				textFlow.backgroundManager.finalizeLine(_curLine);
+				
+			textLine.userData = _totalLength; 		// store absolute start position in the userData field
+			_totalLength += textLine.rawTextLength; // update length accumulator
+			_lines.push(textLine);
+			if (vjType != VerticalAlign.TOP)
+				_vjLines.push(new VJHelper(textLine,_curLine.height));
+				
+			commitLastLineState(_curLine);	
+		}
+
+		public function get textFlow():ITextFlow
+		{ return _textFlow; }
+		
+		private var _resetLineHandler:Function;
+		
+		/** Callback to the client to reset a line when its being rebroken */
+		public function get resetLineHandler():Function
+		{ return _resetLineHandler; }
+		public function set resetLineHandler(val:Function):void
+		{ _resetLineHandler = val; }
+		
+		/** @private */
+		protected override function resetLine(textLine:ITextLine):void
+		{
+			super.resetLine(textLine);
+			if (_resetLineHandler != null)
+				_resetLineHandler(textLine);
+		}
+		
+		/** @private */
+		protected override function composeNextLine():ITextLine
+		{
+			CONFIG::debug { assert(!_previousLine || _previousLine.validity == "valid","Bad prevline: "+Debugging.getIdentity(_previousLine)); }
+			
+			var numberLine:ITextLine;
+			// create numberLine if in a listElement
+			if (_listItemElement && _listItemElement.getAbsoluteStart() == _curElementStart+_curElementOffset)
+			{
+				var isRTL:Boolean = _curParaElement.computedFormat.direction == Direction.RTL;
+				numberLine = NumberlineUtil.createNumberLine(_listItemElement, _curParaElement, _flowComposer.swfContext, isRTL ? _parcelList.rightMargin : _parcelList.leftMargin);				
+				pushInsideListItemMargins(numberLine);
+			}
+			
+			// space to palce a line?			
+			if (!_parcelList.getLineSlug(_lineSlug, 0, 0, _textIndent, _curParaFormat.direction == Direction.LTR))
+				return null;
+			
+			var textLine:ITextLine;
+			
+			for (;;) 
+			{
+				for (;;)
+				{	
+					// generate new line
+					CONFIG::debug { assert(!_parcelList.atEnd(), "failing to stop"); }
+					CONFIG::debug { assert(_curElement is IFlowLeafElement, "element must be leaf before calling composeLine"); }
+					
+					textLine = createTextLine(_lineSlug.width, !_lineSlug.wrapsKnockOut /* don't allow emergency breaks next to floats or padded elements */);
+					if (textLine)
+						break;
+
+					// force advance within the parcel to the next wider slug, or (if there are no more) to the next parcel
+					var newDepth:Number = _curParcel.findNextTransition(_lineSlug.depth);
+					if (newDepth < Number.MAX_VALUE)
+					{
+						_parcelList.addTotalDepth(newDepth - _lineSlug.depth);
+						_parcelList.getLineSlug(_lineSlug, 0, 1, _textIndent, _curParaFormat.direction == Direction.LTR);
+					}
+					else
+					{
+						advanceToNextParcel();
+						if (!_parcelList.atEnd())
+							if (_parcelList.getLineSlug(_lineSlug, 0, 1, _textIndent, _curParaFormat.direction == Direction.LTR))
+								continue;
+						popInsideListItemMargins(numberLine);
+						return null;
+					}
+				}
+
+				
+				// updates _lineSlug
+				if (fitLineToParcel(textLine, true, numberLine))	// TODO!!!!!!
+					break;		// we have a good line
+				if (resetLineHandler != null)
+					resetLineHandler(textLine);
+				if (_parcelList.atEnd())		// keep going
+				{
+					popInsideListItemMargins(numberLine);
+					return null;
+				}
+			}
+			
+			popInsideListItemMargins(numberLine);
+
+			CONFIG::debug { assert(textLine != null, "textLine != null"); }		
+			return textLine;
+		}
+        
+        /** @private */
+        public function swapLines(lines:Array):Array
+        {
+        	var current:Array = _lines;
+        	_lines = lines;
+        	return current;
+        }
+
+		/** Final adjustment on the content bounds. */
+ 		override protected function finalParcelAdjustment(controller:IContainerController):void
+ 		{
+			CONFIG::debug { assert(controller.absoluteStart == 0,"SimpleCompose: multiple controllers not supported"); }
+
+			var minX:Number = Constants.MAX_LINE_WIDTH;
+ 			var minY:Number = Constants.MAX_LINE_WIDTH;
+ 			var maxX:Number = -Constants.MAX_LINE_WIDTH;
+			
+			var verticalText:Boolean = _blockProgression == BlockProgression.RL;
+			
+			if (!isNaN(_parcelLogicalTop))
+			{
+				if (verticalText)
+					maxX = _parcelLogicalTop;
+				else
+					minY = _parcelLogicalTop;
+			}
+			
+			if (!_measuring)
+			{
+				if (verticalText)
+					minY = _accumulatedMinimumStart;
+				else
+					minX = _accumulatedMinimumStart;			
+			}
+			else
+			{
+	 			var textLine:ITextLine;
+	 			var startPos:int = 0;
+				
+				var firstLineAdjust:Number;
+				var effectiveIndent:Number;
+				var edgeAdjust:Number;
+				var curPara:IParagraphElement;
+				var curParaFormat:ITextLayoutFormat;
+				var paddingVerticalAdjust:Number = 0;		// logical vertical adjustment due to padding on paragraph & divs
+				var paddingHorizontalAdjust:Number = 0;		// logical horizontal adjustment due to padding on paragraph & divs
+				var previousParagraph:IParagraphElement = null;
+	
+				for each (textLine in _lines)
+				{
+					var leaf:IFlowLeafElement = controller.textFlow.findLeaf(startPos);
+					var para:IParagraphElement = leaf.getParagraph();
+					if (para != previousParagraph)
+					{
+						// Recalculate padding values for the new paragraph
+						paddingVerticalAdjust = 0;
+						paddingHorizontalAdjust = 0;
+						var fge:IFlowGroupElement = para;
+						while (fge && fge.parent)
+						{
+							if (verticalText)
+							{
+								paddingVerticalAdjust += (fge.getEffectivePaddingRight() + fge.getEffectiveBorderRightWidth() + fge.getEffectiveMarginRight());
+								paddingHorizontalAdjust += (fge.getEffectivePaddingTop() + fge.getEffectiveBorderTopWidth() + fge.getEffectiveMarginTop());
+							}
+							else
+							{
+								paddingVerticalAdjust += (fge.getEffectivePaddingTop() + fge.getEffectiveBorderTopWidth() + fge.getEffectiveMarginTop());
+								paddingHorizontalAdjust += (fge.getEffectivePaddingLeft() + fge.getEffectiveBorderLeftWidth() + fge.getEffectiveMarginLeft());
+							}
+							fge = fge.parent;
+						}
+						previousParagraph = para;
+					}
+	
+	            	// Check the logical vertical dimension first
+	            	// If the lines have children, they may be inlines. The origin of the ITextLine is the baseline, 
+	            	// which does not include the ascent of the inlines or the text. So we have to factor that in.
+					// var verticalAdjust:Number = verticalText ? textLine.descent : textLine.ascent;
+					var inlineAscent:Number = 0;
+					if (textLine.numElements > 0)		// adjustjust logical vertical coord to take into account inlines
+					{
+						var leafStart:int = leaf.getAbsoluteStart();
+						inlineAscent = TextLineUtil.getTextLineTypographicAscent(textLine, leaf, leafStart, startPos + textLine.rawTextLength);
+					}
+	
+					// Figure out the logical horizontal adjustment
+					CONFIG::debug { assert(curPara != para, "found it"); }
+					if (curPara != para)
+					{
+						curParaFormat = para.computedFormat;
+						if (curParaFormat.direction == Direction.LTR)
+						{
+							firstLineAdjust = Math.max(curParaFormat.textIndent, 0);
+							effectiveIndent = curParaFormat.paragraphStartIndent;
+						}
+						else
+						{
+							firstLineAdjust = 0;
+							effectiveIndent = curParaFormat.paragraphEndIndent;
+						}
+					}
+					effectiveIndent += paddingHorizontalAdjust;
+					
+					edgeAdjust = textLine.textBlockBeginIndex == 0 ? effectiveIndent + firstLineAdjust : effectiveIndent;
+					edgeAdjust = verticalText ? textLine.y - edgeAdjust : textLine.x - edgeAdjust;
+					
+					var numberLine:ITextLine = TextLineUtil.findNumberLine(textLine);
+					
+					if (numberLine)
+					{
+						var numberLineStart:Number = verticalText ? numberLine.y+textLine.y : numberLine.x+textLine.x;
+						edgeAdjust = Math.min(edgeAdjust,numberLineStart);
+					}
+					
+					if (verticalText)
+					{
+						minY = Math.min(edgeAdjust, minY);
+			            maxX = Math.max(textLine.x + Math.max(inlineAscent,textLine.ascent) + paddingVerticalAdjust, maxX);
+					}
+					else
+					{
+						minX = Math.min(edgeAdjust, minX);
+						if (inlineAscent < textLine.ascent)
+							inlineAscent = textLine.ascent;
+			           	minY = Math.min(textLine.y - (inlineAscent + paddingVerticalAdjust), minY);
+			  		}
+			  		startPos += textLine.rawTextLength;
+   				}
+			}
+			
+            // Don't make adjustments for tiny fractional values.
+            /*if (minX != _parcelLeft && Math.abs(minX-_parcelLeft) >= 1)
+         		_parcelLeft = minX;
+            if (maxX != _parcelRight && Math.abs(maxX-_parcelRight) >= 1)
+         		_parcelRight = maxX;
+         	if (minY != _parcelTop && Math.abs(minY-_parcelTop) >= 1)
+           		_parcelTop = minY;*/
+			if (minX != Constants.MAX_LINE_WIDTH && Math.abs(minX-_parcelLeft) >= 1)
+				_parcelLeft = minX;
+			if (maxX != -Constants.MAX_LINE_WIDTH && Math.abs(maxX-_parcelRight) >= 1)
+				_parcelRight = maxX;
+			if (minY != Constants.MAX_LINE_WIDTH && Math.abs(minY-_parcelTop) >= 1)
+				_parcelTop = minY;
+
+ 		}		
+		
+		public override function releaseAnyReferences():void
+		{
+			super.releaseAnyReferences();
+			workingLine.initialize(null,0,0,0,0,null);
+			resetLineHandler = null;
+			// parcelList.releaseAnyReferences();
+		}
+
+		public function get lines():Array
+		{
+			return _lines;
+		}
+	}
+}
+import org.apache.flex.text.engine.ITextLine;
+import org.apache.flex.textLayout.compose.IVerticalJustificationLine;
+
+class VJHelper implements IVerticalJustificationLine
+{
+	private var _line:ITextLine;
+	private var _height:Number;
+
+	public function VJHelper(line:ITextLine,h:Number)
+	{
+		_line = line;
+		_height = h;
+	}
+	public function get x():Number
+	{ return _line.x; }
+	public function set x(val:Number):void
+	{ _line.x = val; }
+		
+	public function get y():Number
+	{ return _line.y; }
+	public function set y(val:Number):void
+	{ _line.y = val; }
+		
+	public function get ascent():Number
+	{ return _line.ascent; }
+	public function get descent():Number
+	{ return _line.descent; }
+	public function get height():Number
+	{
+		return _height;
+	}
+
+	public function set height(value:Number):void
+	{
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/Slug.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/Slug.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/Slug.as
new file mode 100644
index 0000000..7fd0788
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/compose/Slug.as
@@ -0,0 +1,32 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.compose
+{
+	/** A Slug is geomtrical line information, generated by a Parcel. It has data required for composition. */
+	// [ExcludeClass]
+	public class Slug
+	{
+		public var leftMargin:Number;
+		public var rightMargin:Number;
+		public var width:Number;	// logical width
+		public var depth:Number;
+		public var height:Number;	// logical height
+		public var wrapsKnockOut:Boolean;	// true if the slug is narrow because it encountered a knockout (e.g., for a float)
+	}
+}