      *  @private
      *  TODO This should be mx_internal, but that causes a compiler error.
      */
+    protected function composeRequired(unscaledWidth:Number, 
+                                       unscaledHeight:Number):Boolean
+    {
+        // For textAlign, if the composeWidth isn't the same
+        // as the unscaledWidth, and the text isn't left aligned, we need to 
+        // recompose.
+        //
+        if (isNaN(_composeWidth) || _composeWidth != unscaledWidth)
+        {
+            var direction:String = getStyle("direction");
+            var textAlign:String = getStyle("textAlign");
+
+            var leftAligned:Boolean =
+                textAlign == "left" ||
+                textAlign == "start" && direction == "ltr" ||
+                textAlign == "end" && direction == "rtl";
+
+            if (!leftAligned)
+                return true;
+        }
+        
+        // For verticalAlign, if the composeHeight isn't the same as the
+        // unscaledHeight, and the text isn't top aligned, we need to
+        // recompose (or adjust the y values of all the text lines).
+        if (isNaN(_composeHeight) || _composeHeight != unscaledHeight)
+        {
+            var verticalAlign:String = getStyle("verticalAlign");
+            var topAligned:Boolean = (verticalAlign == "top");
+
+            if (!topAligned)
+                return true;
+        }
+
+        return false;   
+    }
+
+    /**
+     *  @private
+     *  TODO This should be mx_internal, but that causes a compiler error.
+     */
     protected function composeOnHeightChange():Boolean
     {
         if (truncation != 0 && getStyle("lineBreak") == "toFit")

        
        // ToDo: optimize for right-to-left text so compose isn't always done
        // when height or width changes.
        if (mx_internal::invalidateCompose)
        {
            compose = true;
        }

        }
                
        // Register as a weak listener for "change" events from ResourceManager.
        // If TextGraphicElements registered as a strong listener,
        // they wouldn't get garbage collected.
        resourceManager.addEventListener(
            Event.CHANGE, resourceManager_changeHandler, false, 0, true);
