Merge "It may be outside the range of type int. Change to uint64_t." into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller-relayouter.cpp
index 6f4763e..527bb99 100644 (file)
@@ -67,6 +67,8 @@ Size Controller::Relayouter::CalculateLayoutSizeOnRequiredControllerSize(Control
                                                                         SHAPE_TEXT |
                                                                         GET_GLYPH_METRICS);
 
+  const OperationsMask sizeOperations = static_cast<OperationsMask>(LAYOUT | ALIGN | REORDER);
+
   // Set the update info to relayout the whole text.
   TextUpdateInfo& textUpdateInfo = impl.mTextUpdateInfo;
   if((0 == textUpdateInfo.mNumberOfCharactersToAdd) &&
@@ -78,55 +80,71 @@ Size Controller::Relayouter::CalculateLayoutSizeOnRequiredControllerSize(Control
   textUpdateInfo.mParagraphCharacterIndex     = 0u;
   textUpdateInfo.mRequestedNumberOfCharacters = model->mLogicalModel->mText.Count();
 
-  // This is to keep Index to the first character to be updated.
-  // Then restore it after calling Clear method.
-  auto updateInfoCharIndexBackup = textUpdateInfo.mCharacterIndex;
-
   // Get a reference to the pending operations member
   OperationsMask& operationsPending = impl.mOperationsPending;
 
-  // Layout the text for the new width.
-  // Apply the pending operations, requested operations and the only once operations.
-  // Then remove onlyOnceOperations
-  operationsPending = static_cast<OperationsMask>(operationsPending | requestedOperationsMask | onlyOnceOperations);
-
-  // Make sure the model is up-to-date before layouting
-  impl.UpdateModel(static_cast<OperationsMask>(operationsPending & ~UPDATE_LAYOUT_SIZE));
-
   // Store the actual control's size to restore later.
   const Size actualControlSize = visualModel->mControlSize;
 
-  DoRelayout(impl,
-             requestedControllerSize,
-             static_cast<OperationsMask>(operationsPending & ~UPDATE_LAYOUT_SIZE),
-             calculatedLayoutSize);
+  // Whether the text control is editable
+  const bool isEditable = NULL != impl.mEventData;
 
-  // Clear the update info. This info will be set the next time the text is updated.
-  textUpdateInfo.Clear();
+  if(!isEditable)
+  {
+    impl.UpdateModel(onlyOnceOperations);
 
-  //TODO: Refactor "DoRelayout" and extract common code of size calculation without modifying attributes of mVisualModel,
-  //TODO: then calculate GlyphPositions. Lines, Size, Layout for Natural-Size
-  //TODO: and utilize the values in OperationsPending and TextUpdateInfo without changing the original one.
-  //TODO: Also it will improve performance because there is no need todo FullRelyout on the next need for layouting.
+    // Layout the text for the new width.
+    operationsPending = static_cast<OperationsMask>(operationsPending | requestedOperationsMask);
 
-  // FullRelayoutNeeded should be true because DoRelayout is MAX_FLOAT, MAX_FLOAT.
-  // By this no need to take backup and restore it.
-  textUpdateInfo.mFullRelayoutNeeded = true;
+    DoRelayout(impl,
+               requestedControllerSize,
+               static_cast<OperationsMask>(onlyOnceOperations | requestedOperationsMask),
+               calculatedLayoutSize);
 
-  // Restore mCharacterIndex. Because "Clear" set it to the maximum integer.
-  // The "CalculateTextUpdateIndices" does not work proprely because the mCharacterIndex will be greater than mPreviousNumberOfCharacters.
-  // Which apply an assumption to update only the last  paragraph. That could cause many of out of index crashes.
-  textUpdateInfo.mCharacterIndex = updateInfoCharIndexBackup;
+    textUpdateInfo.Clear();
+    textUpdateInfo.mClearAll = true;
 
-  // Do not do again the only once operations.
-  operationsPending = static_cast<OperationsMask>(operationsPending & ~onlyOnceOperations);
+    // Do not do again the only once operations.
+    operationsPending = static_cast<OperationsMask>(operationsPending & ~onlyOnceOperations);
+  }
+  else
+  {
+    // This is to keep Index to the first character to be updated.
+    // Then restore it after calling Clear method.
+    auto updateInfoCharIndexBackup = textUpdateInfo.mCharacterIndex;
 
-  // Do the size related operations again.
+    // Layout the text for the new width.
+    // Apply the pending operations, requested operations and the only once operations.
+    // Then remove onlyOnceOperations
+    operationsPending = static_cast<OperationsMask>(operationsPending | requestedOperationsMask | onlyOnceOperations);
+
+    // Make sure the model is up-to-date before layouting
+    impl.UpdateModel(static_cast<OperationsMask>(operationsPending & ~UPDATE_LAYOUT_SIZE));
+
+    DoRelayout(impl,
+               requestedControllerSize,
+               static_cast<OperationsMask>(operationsPending & ~UPDATE_LAYOUT_SIZE),
+               calculatedLayoutSize);
+
+    // Clear the update info. This info will be set the next time the text is updated.
+    textUpdateInfo.Clear();
+
+    //TODO: Refactor "DoRelayout" and extract common code of size calculation without modifying attributes of mVisualModel,
+    //TODO: then calculate GlyphPositions. Lines, Size, Layout for Natural-Size
+    //TODO: and utilize the values in OperationsPending and TextUpdateInfo without changing the original one.
+    //TODO: Also it will improve performance because there is no need todo FullRelyout on the next need for layouting.
+
+    // FullRelayoutNeeded should be true because DoRelayout is MAX_FLOAT, MAX_FLOAT.
+    // By this no need to take backup and restore it.
+    textUpdateInfo.mFullRelayoutNeeded = true;
 
-  const OperationsMask sizeOperations = static_cast<OperationsMask>(LAYOUT |
-                                                                    ALIGN |
-                                                                    REORDER);
+    // Restore mCharacterIndex. Because "Clear" set it to the maximum integer.
+    // The "CalculateTextUpdateIndices" does not work proprely because the mCharacterIndex will be greater than mPreviousNumberOfCharacters.
+    // Which apply an assumption to update only the last  paragraph. That could cause many of out of index crashes.
+    textUpdateInfo.mCharacterIndex = updateInfoCharIndexBackup;
+  }
 
+  // Do the size related operations again.
   operationsPending = static_cast<OperationsMask>(operationsPending | sizeOperations);
 
   // Restore the actual control's size.
@@ -447,7 +465,19 @@ Controller::UpdateTextType Controller::Relayouter::Relayout(Controller& controll
   if(!isEditable || !controller.IsMultiLineEnabled())
   {
     // After doing the text layout, the vertical offset to place the actor in the desired position can be calculated.
-    CalculateVerticalOffset(controller, size);
+    CalculateVerticalOffset(impl, size);
+  }
+  else // TextEditor
+  {
+    // If layoutSize is bigger than size, vertical align has no meaning.
+    if(layoutSize.y < size.y)
+    {
+      CalculateVerticalOffset(impl, size);
+      if(impl.mEventData)
+      {
+        impl.mEventData->mScrollAfterDelete = false;
+      }
+    }
   }
 
   if(isEditable)
@@ -592,12 +622,15 @@ bool Controller::Relayouter::DoRelayout(Controller::Impl& impl, const Size& size
     }
 
     // Update the visual model.
-    bool isAutoScrollEnabled = impl.mIsAutoScrollEnabled;
+    bool isAutoScrollEnabled            = impl.mIsAutoScrollEnabled;
+    bool isAutoScrollMaxTextureExceeded = impl.mIsAutoScrollMaxTextureExceeded;
+
     Size newLayoutSize;
     viewUpdated               = impl.mLayoutEngine.LayoutText(layoutParameters,
                                                 newLayoutSize,
                                                 elideTextEnabled,
                                                 isAutoScrollEnabled,
+                                                isAutoScrollMaxTextureExceeded,
                                                 ellipsisPosition);
     impl.mIsAutoScrollEnabled = isAutoScrollEnabled;
 
@@ -769,16 +802,15 @@ void Controller::Relayouter::DoRelayoutHorizontalAlignment(Controller::Impl&
   }
 }
 
-void Controller::Relayouter::CalculateVerticalOffset(Controller& controller, const Size& controlSize)
+void Controller::Relayouter::CalculateVerticalOffset(Controller::Impl& impl, const Size& controlSize)
 {
-  Controller::Impl& impl                  = *controller.mImpl;
-  ModelPtr&         model                 = impl.mModel;
-  VisualModelPtr&   visualModel           = model->mVisualModel;
-  Size              layoutSize            = model->mVisualModel->GetLayoutSize();
-  Size              oldLayoutSize         = layoutSize;
-  float             offsetY               = 0.f;
-  bool              needRecalc            = false;
-  float             defaultFontLineHeight = impl.GetDefaultFontLineHeight();
+  ModelPtr&       model                 = impl.mModel;
+  VisualModelPtr& visualModel           = model->mVisualModel;
+  Size            layoutSize            = model->mVisualModel->GetLayoutSize();
+  Size            oldLayoutSize         = layoutSize;
+  float           offsetY               = 0.f;
+  bool            needRecalc            = false;
+  float           defaultFontLineHeight = impl.GetDefaultFontLineHeight();
 
   if(fabsf(layoutSize.height) < Math::MACHINE_EPSILON_1000)
   {