         // as we may have messed up the text lines.
         invalidateDisplayList();
         
-        // Put on next pixel boundary for crisp edges.
-        bounds.width = Math.ceil(bounds.width);        
-        bounds.height = Math.ceil(bounds.height);
+        // Put on next pixel boundary for crisp edges.  If text is aligned,
+        // x and/or y may not be 0.        
+        var newMeasuredHeight:Number = Math.ceil(bounds.bottom);
 
         // If the measured height is not affected, then constrained
         // width measurement is not neccessary.
-        if (!isNaN(_widthConstraint) && measuredHeight == bounds.height)
+        if (!isNaN(_widthConstraint) && measuredHeight == newMeasuredHeight)
             return;
             
         // Call super.measure() here insted of in the beginning of the method,

    /**
     *  @private
     */
    private function composeOnWidthChange(unscaledWidth:Number):Boolean
    {
        // If toFit, then the composeWidth must equal the unscaledWidth
        // so that the text flows properly. 

     *  @private
     */
    private function composeForAlignStyles(unscaledWidth:Number, 
                                           unscaledHeight:Number,
                                           contentWidth:Number,
                                           contentHeight: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.
        //
        var width:Number = isNaN(_composeWidth) ? 
                           contentWidth : _composeWidth;
        if (unscaledWidth != width)
        {
            var direction:String = getStyle("direction");
            var textAlign:String = getStyle("textAlign");
