diff --git a/src/orca/braille.py b/src/orca/braille.py
index f069504..9815a1a 100644
--- a/src/orca/braille.py
+++ b/src/orca/braille.py
@@ -188,6 +188,15 @@ _lines = []
 #
 _regionWithFocus = None
 
+# The last text information painted.  This has the following fields:
+#
+# lastTextObj = the last accessible
+# lastCaretOffset = the last caret offset of the last text displayed
+# lastLineOffset = the last line offset of the last text displayed
+# lastCursorCell = the last cell on the braille display for the caret
+#
+_lastTextInfo = (None, 0, 0, 0)
+
 # The viewport is a rectangular region of size _displaySize whose upper left
 # corner is defined by the point (x, line number).  As such, the viewport is
 # identified solely by its upper left point.
@@ -1056,6 +1065,124 @@ def setFocus(region, panToFocus=True, getLinkMask=True):
 
     viewport[0] = max(0, offset)
 
+def _realignViewport(string, focusOffset, cursorOffset):
+    """Realigns the braille display to account for braille alignment
+    preferences.  By the time this method is called, if there is a
+    cursor cell to be displayed, it should already be somewhere in
+    the viewport.  All we're going to do is adjust the viewport a
+    little to align the viewport edge according to the
+    settings.brailleAlignmentStyle.
+
+    Arguments:
+    - string: the entire string to be presented
+    - focusOffset: where in string the focused region begins
+    - cursorOffset: where in the string the cursor should be
+
+    Returns: the viewport[0] value is potentially modified.
+    """
+
+    # pylint complains we don't set viewport, which in fact we do if
+    # 'jump' ends up being set.
+    #
+    # pylint: disable-msg=W0602
+    #
+    global viewport
+
+    jump = 0
+
+    # If there's no cursor to show or we're doing
+    # ALIGN_BRAILLE_BY_EDGE, the viewport should already be where it
+    # belongs.  Otherwise, we may need to do some adjusting of the
+    # viewport.
+    #
+    if (cursorOffset < 0) \
+       or (settings.brailleAlignmentStyle == settings.ALIGN_BRAILLE_BY_EDGE):
+        pass
+    else:
+        # The left and right margin values are absolute values in the
+        # string and represent where in the string the margins of the
+        # current viewport lie.  Note these are margins and not the
+        # actual edges of the viewport.
+        #
+        leftMargin = viewport[0] + settings.brailleAlignmentMargin
+        rightMargin = (viewport[0] + _displaySize[0]) \
+                      - settings.brailleAlignmentMargin
+
+        # This represents how far left in the string we want to search
+        # and also how far left we'll realign the viewport. Setting it
+        # to focusOffset means we won't move the viewport further left
+        # than the beginning of the current region with focus.
+        #
+        leftMostEdge = max(0, focusOffset)
+
+        # If we align by margin, we just want to keep the cursor at or
+        # in between the margins.  The only time we go outside the
+        # margins are when we are at the ends of the string.
+        #
+        if settings.brailleAlignmentStyle == settings.ALIGN_BRAILLE_BY_MARGIN:
+            if cursorOffset < leftMargin:
+                jump = cursorOffset - leftMargin
+            elif cursorOffset > rightMargin:
+                jump = cursorOffset - rightMargin
+        elif settings.brailleAlignmentStyle == settings.ALIGN_BRAILLE_BY_WORD:
+            # When we align by word, we want to try to show complete
+            # words at the edges of the braille display.  When we're
+            # near the left edge, we'll try to start a word at the
+            # left edge.  When we're near the right edge, we'll try to
+            # end a word at the right edge.
+            #
+            if cursorOffset < leftMargin:
+                # Find the index of the character that is the first
+                # letter of the word prior to left edge of the
+                # viewport.
+                #
+                inWord = False
+                leftWordEdge = viewport[0] - 1
+                while leftWordEdge >= leftMostEdge:
+                    if not string[leftWordEdge] in ' \t\n\r\v\f':
+                        inWord = True
+                    elif inWord:
+                        leftWordEdge += 1
+                        break
+                    leftWordEdge -= 1
+                leftWordEdge = max(leftMostEdge, leftWordEdge)
+                jump = leftWordEdge - viewport[0]
+            elif cursorOffset > rightMargin:
+                # Find the index of the character that is the last
+                # letter of the word after the right edge of the
+                # viewport.
+                #
+                inWord = False
+                rightWordEdge = viewport[0] + _displaySize[0]
+                while rightWordEdge < len(string):
+                    if not string[rightWordEdge] in ' \t\n\r\v\f':
+                        inWord = True
+                    elif inWord:
+                        break
+                    rightWordEdge += 1
+                rightWordEdge = min(len(string), rightWordEdge)
+                jump = max(0, rightWordEdge - (viewport[0] + _displaySize[0]))
+
+            # We use the brailleMaximumJump to help us handle really
+            # long words.  The (jump/abs(jump)) stuff is a quick and
+            # dirty way to retain the sign (i.e., +1 or -1).
+            #
+            if abs(jump) > settings.brailleMaximumJump:
+                jump = settings.brailleMaximumJump * (jump/abs(jump))
+
+    if jump:
+        # Set the viewport's left edge based upon the jump, making
+        # sure we don't go any farther left than the leftMostEdge.
+        #
+        viewport[0] = max(leftMostEdge, viewport[0] + jump)
+
+        # Now, make sure we don't scroll too far to the right.  That
+        # is, avoid showing blank spaces to the right if there is more
+        # of the string that can be shown.
+        #
+        viewport[0] = min(viewport[0],
+                          max(leftMostEdge, len(string) - _displaySize[0]))
+
 def refresh(panToCursor=True,
             targetCursorCell=0,
             getLinkMask=True,
@@ -1087,6 +1214,21 @@ def refresh(panToCursor=True,
     global beginningIsShowing
     global cursorCell
     global _monitor
+    global _lastTextInfo
+
+    # Check out what we were displaying the last time - it might be
+    # the same text object we are displaying now.
+    #
+    (lastTextObj, lastCaretOffset, lastLineOffset, lastCursorCell) = \
+        _lastTextInfo
+    if _regionWithFocus and isinstance(_regionWithFocus, Text):
+        currentTextObj = _regionWithFocus.accessible
+        currentCaretOffset = _regionWithFocus.caretOffset
+        currentLineOffset = _regionWithFocus.lineOffset
+    else:
+        currentTextObj = None
+        currentCaretOffset = 0
+        currentLineOffset = 0
 
     if stopFlash:
         killFlash(restoreSaved=False)
@@ -1102,6 +1244,7 @@ def refresh(panToCursor=True,
                               "BrlTTY seems to have disappeared:")
                 debug.printException(debug.LEVEL_WARNING)
                 shutdown()
+        _lastTextInfo = (None, 0, 0, 0)
         return
 
     # Now determine the location of the cursor.  First, we'll figure
@@ -1112,6 +1255,26 @@ def refresh(panToCursor=True,
     if targetCursorCell < 0:
         targetCursorCell = _displaySize[0] + targetCursorCell + 1
 
+    # If there is no target cursor cell, then try to set one.  We
+    # currently only do this for text objects, and we do so by looking
+    # at the last position of the caret offset and cursor cell.  The
+    # primary goal here is to keep the cursor movement on the display
+    # somewhat predictable.
+    #
+    if (targetCursorCell == 0) \
+       and currentTextObj and (currentTextObj == lastTextObj) \
+       and (currentLineOffset == lastLineOffset):
+        if lastCaretOffset == currentCaretOffset:
+            targetCursorCell = lastCursorCell
+        elif lastCaretOffset < currentCaretOffset:
+            targetCursorCell = min(_displaySize[0],
+                                   lastCursorCell \
+                                   + (currentCaretOffset - lastCaretOffset))
+        elif lastCaretOffset > currentCaretOffset:
+            targetCursorCell = max(1,
+                                   lastCursorCell \
+                                   - (lastCaretOffset - currentCaretOffset))
+
     # Now, we figure out the 0-based offset for where the cursor
     # actually is in the string.
     #
@@ -1136,6 +1299,12 @@ def refresh(panToCursor=True,
         elif cursorOffset >= (viewport[0] + _displaySize[0]):
             viewport[0] = max(0, cursorOffset - _displaySize[0] + 1)
 
+    # The cursorOffset should be somewhere in the viewport right now.
+    # Let's try to realign the viewport so that the cursor shows up
+    # according to the settings.brailleAlignmentStyle setting.
+    #
+    _realignViewport(string, focusOffset, cursorOffset)
+
     startPos = viewport[0]
     endPos = startPos + _displaySize[0]
 
@@ -1216,6 +1385,16 @@ def refresh(panToCursor=True,
     beginningIsShowing = startPos == 0
     endIsShowing = endPos >= len(string)
 
+    # Remember the text information we were presenting (if any)
+    #
+    if _regionWithFocus and isinstance(_regionWithFocus, Text):
+        _lastTextInfo = (_regionWithFocus.accessible,
+                         _regionWithFocus.caretOffset,
+                         _regionWithFocus.lineOffset,
+                         cursorCell)
+    else:
+        _lastTextInfo = (None, 0, 0, 0)
+
 def _flashCallback():
     global _lines
     global _regionWithFocus
diff --git a/src/orca/braille_generator.py b/src/orca/braille_generator.py
index 6a1e2e0..8f721a2 100644
--- a/src/orca/braille_generator.py
+++ b/src/orca/braille_generator.py
@@ -297,7 +297,8 @@ class BrailleGenerator(generator.Generator):
             text = obj.queryText()
         except NotImplementedError:
             text = None
-        if text and self._script.isTextArea(obj):
+        if text and (self._script.isTextArea(obj) \
+                     or (obj.getRole() in [pyatspi.ROLE_LABEL])):
             [lineString, startOffset, endOffset] = text.getTextAtOffset(
                 text.caretOffset,
                 pyatspi.TEXT_BOUNDARY_LINE_START)
diff --git a/src/orca/orca_prefs.py b/src/orca/orca_prefs.py
index 6d34df9..67d42e3 100644
--- a/src/orca/orca_prefs.py
+++ b/src/orca/orca_prefs.py
@@ -313,6 +313,17 @@ class OrcaPrefs:
         else:
             return "orca.settings.BRAILLE_ROLENAME_STYLE_LONG"
 
+    def _getBrailleAlignmentStyleString(self, brailleAlignmentStyle):
+        """Returns a string that represents the brailleAlignmentStyle
+         passed in."""
+
+        if brailleAlignmentStyle == settings.ALIGN_BRAILLE_BY_WORD:
+            return "orca.settings.ALIGN_BRAILLE_BY_WORD"
+        if brailleAlignmentStyle == settings.ALIGN_BRAILLE_BY_MARGIN:
+            return "orca.settings.ALIGN_BRAILLE_BY_MARGIN"
+        else:
+            return "orca.settings.ALIGN_BRAILLE_BY_EDGE"
+
     def _getVerbalizePunctuationStyleString(self, punctuationStyle):
         """Returns a string that represents the punctuation style passed in."""
 
@@ -702,6 +713,8 @@ class OrcaPrefs:
                 value = self._getBrailleSelectionIndicatorString(prefsDict[key])
             elif key == "brailleLinkIndicator":
                 value = self._getBrailleLinkIndicatorString(prefsDict[key])
+            elif key == "brailleAlignmentStyle":
+                value = self._getBrailleAlignmentStyleString(prefsDict[key])
             elif key == "verbalizePunctuationStyle":
                 value = self._getVerbalizePunctuationStyleString(prefsDict[key])
             elif key == "sayAllStyle":
diff --git a/src/orca/settings.py b/src/orca/settings.py
index a8e352f..ce186ff 100644
--- a/src/orca/settings.py
+++ b/src/orca/settings.py
@@ -119,6 +119,7 @@ userCustomizableSettings = [
     "brailleRolenameStyle",
     "brailleSelectorIndicator",
     "brailleLinkIndicator",
+    "brailleAlignmentStyle",
     "enableBrailleMonitor",
     "enableMagnifier",
     "enableMagLiveUpdating",
@@ -272,6 +273,19 @@ BRAILLE_LINK_8    = 0x80 # 10000000
 BRAILLE_LINK_BOTH = 0xc0 # 11000000
 brailleLinkIndicator = BRAILLE_LINK_BOTH
 
+# Braille alignment styles.  These say how to align text on the
+# edges of the braille display.  The brailleAlignmentMargin value
+# says how close to the edge of the braille the display the cursor
+# cell can get.  The brailleMaximumJump says how far we can jump
+# the display when aligning by word.
+#
+ALIGN_BRAILLE_BY_EDGE   = 0
+ALIGN_BRAILLE_BY_MARGIN = 1
+ALIGN_BRAILLE_BY_WORD   = 2
+brailleAlignmentMargin  = 3
+brailleMaximumJump      = 8
+brailleAlignmentStyle   = ALIGN_BRAILLE_BY_EDGE
+
 # Speech punctuation levels (see verbalizePunctuationStyle).
 #
 PUNCTUATION_STYLE_NONE = 3
