From eca8f99b38f02711ff93bd4430ba524b6b97bfae Mon Sep 17 00:00:00 2001 From: Choongeun Hong Date: Tue, 4 Jun 2013 17:25:50 +0900 Subject: [PATCH] Add SetFirstDisplayPositionX & support cursor move to row, culomn Change-Id: I588505bc453c07b9f0e4cdbbc5119d10c7c6e95a Signed-off-by: Choongeun Hong --- src/graphics/inc/FGrp_TextTextObject.h | 26 + src/graphics/text/FGrp_TextTextColumn.cpp | 23 + src/graphics/text/FGrp_TextTextColumn.h | 5 + src/graphics/text/FGrp_TextTextComposite.cpp | 224 +-------- src/graphics/text/FGrp_TextTextComposite.h | 2 +- src/graphics/text/FGrp_TextTextObject.cpp | 711 +++++++++++++++++++++++++-- 6 files changed, 742 insertions(+), 249 deletions(-) diff --git a/src/graphics/inc/FGrp_TextTextObject.h b/src/graphics/inc/FGrp_TextTextObject.h index 6cb39c7..071dad6 100644 --- a/src/graphics/inc/FGrp_TextTextObject.h +++ b/src/graphics/inc/FGrp_TextTextObject.h @@ -100,6 +100,8 @@ public: int GetTextIndexFromPosition(float x, float y, bool cursorMode = true) const; + int GetTextIndexFromPosition(float x, float y, int& row, int& column, bool cursorMode = true) const; + int GetTextIndexFromPositionAtLine(int lineIndex, int x, bool cursorMode = true) const; int GetTextIndexFromPositionAtLine(int lineIndex, float x, bool cursorMode = true) const; @@ -327,6 +329,8 @@ public: result GetTextPositionInfoAt(int textIndex, float& width, float& height, float& absX, float& absY, float& logicalX, float& logicalY) const; + result GetTextPositionInfoAt(int row, int column, float& width, float& height, float& absX, float& absY, float& logicalX, float& logicalY) const; + result GetBlockTextPositionInfoAt(int textIndex, int& width, int& height, int& absX, int& absY, int& logicalX, int& logicalY) const; result GetBlockTextPositionInfoAt(int textIndex, float& width, float& height, float& absX, float& absY, float& logicalX, float& logicalY) const; @@ -357,6 +361,18 @@ public: TextBidiHint GetTextBidiHint(void) const; + result SetFirstDisplayPositionX(int x); + + result SetFirstDisplayPositionX(float x); + + int GetFirstDisplayPositionX(void) const; + + float GetFirstDisplayPositionXF(void) const; + + result ConvertToRowColumn(int textIndex, int& row, int& column) const; + + int ConvertToTextIndex(int row, int column) const; + result SetDisplayBoundsExpandEnabled(bool enable); bool IsDisplayBoundsExpandEnabled(void) const; @@ -376,6 +392,9 @@ private: result GetTextPositionInfoInWrapAt(int textIndex, float& width, float& height, float& absX, float& absY, float& logicalX, float& logicalY) const; + result GetTextPositionInfoInWrapAt(int row, int clomn, float& width, float& height, float& absX, float& absY, + float& logicalX, float& logicalY) const; + result GetBlockTextPositionInfoInWrapAt(int textIndex, int& width, int& height, int& absX, int& absY, int& logicalX, int& logicalY) const; @@ -388,14 +407,21 @@ private: result GetTextPositionInfoInNoneWrapAt(int textIndex, float& width, float& height, float& absX, float& absY, float& logicalX, float& logicalY) const; + result GetTextPositionInfoInNoneWrapAt(int row, int clomn, float& width, float& height, float& absX, float& absY, + float& logicalX, float& logicalY) const; + int GetTextIndexFromPositionInWrap(int x, int y, bool cursorMode = true) const; int GetTextIndexFromPositionInWrap(float x, float y, bool cursorMode = true) const; + int GetTextIndexFromPositionInWrap(float x, float y, int& row, int& column, bool cursorMode = true) const; + int GetTextIndexFromPositionInNoneWrap(int x, int y, bool cursorMode = true) const; int GetTextIndexFromPositionInNoneWrap(float x, float y, bool cursorMode = true) const; + int GetTextIndexFromPositionInNoneWrap(float x, float y, int& row, int& column, bool cursorMode = true) const; + result UpdateChangedInfo(int startTextIndex, int textLength = -1); result NotifyTextAdded(int textIndex, int textLength); diff --git a/src/graphics/text/FGrp_TextTextColumn.cpp b/src/graphics/text/FGrp_TextTextColumn.cpp index c2e2991..dfb7948 100644 --- a/src/graphics/text/FGrp_TextTextColumn.cpp +++ b/src/graphics/text/FGrp_TextTextColumn.cpp @@ -51,6 +51,7 @@ TextColumn::TextColumn(TextComposite* pCompositeText) __displayLineCount = 0; __firstDisplayLineIndex = 0; __firstDisplayPositionY = -1; + __firstDisplayPositionX = -1; __displayHeight = -1; __slidingPosition = 0; __pCompositeText = pCompositeText; @@ -198,6 +199,11 @@ TextColumn::Draw(_CanvasImpl& canvasImpl, FloatRectangle& displayRect, int start __displayHeight -= __firstDisplayPositionY - lineBounds.y; } + if (__firstDisplayPositionX > 0) + { + displayRect.x -= __firstDisplayPositionX; + } + while (pTextLineNode != null && 0 <= displayRect.height) { if (action == TEXT_OBJECT_ACTION_TYPE_ABBREV) @@ -218,6 +224,11 @@ TextColumn::Draw(_CanvasImpl& canvasImpl, FloatRectangle& displayRect, int start { lineAction = TEXT_OBJECT_ACTION_TYPE_ABBREV; } + + if (displayRect.width < lineBounds.width) + { + lineAction = TEXT_OBJECT_ACTION_TYPE_ABBREV; + } } else { @@ -1669,6 +1680,18 @@ TextColumn::GetFirstDisplayPositionYF(void) const } void +TextColumn::SetFirstDisplayPositionX(float x) +{ + __firstDisplayPositionX = x; +} + +float +TextColumn::GetFirstDisplayPositionX(void) const +{ + return __firstDisplayPositionX; +} + +void TextColumn::SetDisplayHeight(int height) { __displayHeight = _CoordinateSystemUtils::ConvertToFloat(height); diff --git a/src/graphics/text/FGrp_TextTextColumn.h b/src/graphics/text/FGrp_TextTextColumn.h index 2606bb3..1b08256 100644 --- a/src/graphics/text/FGrp_TextTextColumn.h +++ b/src/graphics/text/FGrp_TextTextColumn.h @@ -143,6 +143,10 @@ public: float GetFirstDisplayPositionYF(void) const; + void SetFirstDisplayPositionX(float x); + + float GetFirstDisplayPositionX(void) const; + int GetTextLengthAt(int lineIndex) const; int GetFirstTextIndexAt(int lineIndex) const; @@ -242,6 +246,7 @@ private: int __totalLineCount; int __firstDisplayLineIndex; float __firstDisplayPositionY; + float __firstDisplayPositionX; int __displayLineCount; float __displayHeight; Tizen::Graphics::FloatDimension __slidingDimension; diff --git a/src/graphics/text/FGrp_TextTextComposite.cpp b/src/graphics/text/FGrp_TextTextComposite.cpp index d872047..d760cd0 100644 --- a/src/graphics/text/FGrp_TextTextComposite.cpp +++ b/src/graphics/text/FGrp_TextTextComposite.cpp @@ -1872,7 +1872,6 @@ TextComposite::DrawLine(_CanvasImpl& canvasImpl, TextLine* pTextLine, const Floa pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height); adjustedRect = displayRect; - adjustedRect.width = lineBounds.width; adjustedRect.height = lineBounds.height; if (action == TEXT_OBJECT_ACTION_TYPE_ABBREV) @@ -3228,7 +3227,7 @@ TextComposite::NotifyTextChanged(wchar_t* pText, int startTextIndex, int textLen int textIndexFromElementOffset = 0; bool isOptimized = false; - SetWorkWidth(pFont, pText, __workStart, gap); + //SetWorkWidth(pFont, pText, __workStart, gap); if (gap > 0) { @@ -3952,201 +3951,30 @@ TextComposite::ComposeInNoneWrap(FloatRectangle& rect, NoneWrapComposeInfo* pNon { SysTryReturn(NID_GRP, __pCurrentTextColumn, -1, E_INVALID_STATE, "[E_INVALID_STATE] This instance is not constructed yet."); - TextLine* pTextLine = null; + TextLine* pTextLine = new (std::nothrow)TextLine(this); + SysTryReturn(NID_GRP, pTextLine, -1, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory."); + FloatRectangle lineBounds; - FloatDimension textSize; - int lineOffset = 0; - int lineLength = 0; - int endType = TEXT_RETBY_NORMAL; - bool isChanged = false; + FloatDimension lineTextSize; + int lineLength = __length; float baseline = 0; - int textIndex = 0; - - textIndex = (__workStart < 0) ? 0 : __workStart; - textIndex = (textIndex > __length) ? __length : textIndex; - bool forwardSearch = (textIndex == __length) ? false : true; - - if (__pCurrentTextColumn->GetTotalLineCount() > 0) - { - pTextLine = __pCurrentTextColumn->GetTextLine(0); - SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line."); - - lineBounds = pTextLine->GetBoundsF(); - endType = pTextLine->GetEndType(); - - if (lineBounds.width != rect.width) - { - isChanged = true; - } - - lineOffset = pTextLine->GetTextOffset(); - lineLength = pTextLine->GetTextLength(); - - if (lineOffset <= textIndex && textIndex < lineOffset + lineLength) - { - isChanged = true; - } - } - else - { - pTextLine = new (std::nothrow)TextLine(this); - SysTryReturn(NID_GRP, pTextLine, -1, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory."); - - if (forwardSearch) - { - if (pNoneWrapComposeInfo != null) - { - lineOffset = pNoneWrapComposeInfo->prevTextOffset; - } - else - { - lineOffset = 0; - } - } - else - { - lineOffset = __length - 1; - } - - lineLength = 0; - lineBounds.width = rect.width; - lineBounds.x = 0; - lineBounds.y = 0; - lineBounds.height = 0; - __pCurrentTextColumn->AddLineDuringCompose(pTextLine); + GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height); - isChanged = true; - } - - if (isChanged) - { - lineBounds.width = rect.width; - lineBounds.x = 0; - lineBounds.y = 0; - - if (forwardSearch) - { - endType = ForwardAnalyzeWithBaseline(lineOffset, __length - lineOffset, lineBounds.width, __wrap, - lineLength, textSize.width, textSize.height, baseline); - - lineBounds.height = textSize.height; - pTextLine->SetBounds(lineBounds); - pTextLine->SetTextOffset(lineOffset); - pTextLine->SetTextLength(lineLength); - pTextLine->SetRegion(textSize.width, textSize.height); - pTextLine->SetEndType(endType); - pTextLine->SetBaseline(baseline); - GetTextExtentList(pTextLine); - } - else - { - int textCount = 0; - - BackwardAnalyze(lineOffset, lineBounds.width, &textCount, &textSize.width, &textSize.height); - - lineBounds.height = textSize.height; - lineOffset -= (textCount - 1); - lineLength = textCount; - endType = (lineOffset == 0) ? TEXT_RETBY_NORMAL : TEXT_RETBY_LIMITWIDTH; - - pTextLine->SetBounds(lineBounds); - pTextLine->SetTextOffset(lineOffset); - pTextLine->SetTextLength(lineLength); - pTextLine->SetRegion(textSize.width, textSize.height); - pTextLine->SetEndType(endType); - pTextLine->SetBaseline(baseline); - GetTextExtentList(pTextLine); - } - } - - if (__length == 0) - { - pTextLine->SetEndType(TEXT_RETBY_NORMAL); - return 1; - } - - rect.height = lineBounds.height; - - if (textIndex < lineOffset) - { - lineOffset = textIndex; - endType = ForwardAnalyze(lineOffset, __length - lineOffset, lineBounds.width, __wrap, - lineLength, textSize.width, textSize.height); - - lineBounds.height = textSize.height; - } - else if (forwardSearch && textIndex >= lineOffset + lineLength) - { - FloatDimension needDim; - GetRegion(lineOffset + lineLength, textIndex - (lineOffset + lineLength) + 1, needDim.width, needDim.height); - - int index = 0; - float remainingWidth = needDim.width - (lineBounds.width - textSize.width); - - FloatDimension charDim; - textSize.width += needDim.width; - lineLength += textIndex - (lineOffset + lineLength) + 1; - - while (1) - { - GetRegion(lineOffset, 1, charDim.width, charDim.height); - lineOffset++; - index++; - remainingWidth -= charDim.width; - textSize.width -= charDim.width; - - if (remainingWidth <= 0) - { - break; - } - } - - lineLength -= index; - } - else if (endType != TEXT_RETBY_LIMITWIDTH && lineLength != __length) - { - if (lineOffset > 0) - { - FloatDimension lineTextSize; - int textCount = 0; - float remainingWidth = 0; - - pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height); - remainingWidth = lineBounds.width - lineTextSize.width; - BackwardAnalyze(lineOffset - 1, remainingWidth, &textCount, &textSize.width, &textSize.height); - - if (textSize.width > 0) - { - lineOffset -= textCount; - lineLength += textCount; - textSize.width += lineTextSize.width; - lineBounds.height = textSize.height; - endType = TEXT_RETBY_LIMITLENGTH; - } - else - { - return 1; - } - } - else - { - return 1; - } - } - else - { - return 1; - } + lineBounds.width = (rect.width < lineTextSize.width) ? lineTextSize.width :rect.width; + lineBounds.height = lineTextSize.height; + baseline = lineBounds.height / 3.0f; pTextLine->SetBounds(lineBounds); - pTextLine->SetRegion(textSize.width, textSize.height); - pTextLine->SetTextLength(lineLength); - pTextLine->SetTextOffset(lineOffset); - pTextLine->SetEndType(endType); + pTextLine->SetRegion(lineTextSize.width, lineTextSize.height); + pTextLine->SetTextOffset(0); + pTextLine->SetTextLength(lineLength); + pTextLine->SetEndType(TEXT_RETBY_NORMAL); pTextLine->SetBaseline(baseline); GetTextExtentList(pTextLine); + __pCurrentTextColumn->AddLineDuringCompose(pTextLine); + return 1; } @@ -4963,8 +4791,7 @@ TextComposite::ComposeInNoneWrapMiddleEllipsis(FloatRectangle& rect) maxHeight = textSize.height; - ForwardAnalyze(__middleEllipsisTextLengthInHead, __length - __middleEllipsisTextLengthInHead, lineBounds.width - __middleEllipsisWidth - - __middleEllipsisHeadWidth, __wrap, length, textSize.width, textSize.height); + BackwardAnalyze(__length - 1, lineBounds.width - __middleEllipsisWidth - __middleEllipsisHeadWidth, length, textSize.width, textSize.height); __middleEllipsisTextLengthInTail = length; maxHeight = (maxHeight < textSize.height) ? textSize.height : maxHeight; @@ -5032,7 +4859,8 @@ TextComposite::ComposeInNoneWrapHeadEllipsis(FloatRectangle& rect) __pAbbrevTextElement->GetRegion(0, 1, abbrevTextDim.width, abbrevTextDim.height); __headEllipsisWidth = abbrevTextDim.width; - BackwardAnalyze(__length - 1, lineBounds.width - abbrevTextDim.width, &__headEllipsisTextLength, &textSize.width, &textSize.height); + BackwardAnalyze(__length - 1, lineBounds.width - abbrevTextDim.width, __headEllipsisTextLength, textSize.width, textSize.height); + maxHeight = textSize.height; TextLine* pTextLine = new (std::nothrow)TextLine(this); @@ -5110,15 +4938,15 @@ TextComposite::GetValue(int textIndex, TextComponentInfoValueType type, unsigned } bool -TextComposite::BackwardAnalyze(int startTextIndex, float maxWidth, int* actualLength, float* width, float* height) +TextComposite::BackwardAnalyze(int startTextIndex, float maxWidth, int& actualLength, float& width, float& height) { float remainingWidth = 0; int length = 0; FloatDimension textSize; - *actualLength = 0; - *width = 0; - *height = 0; + actualLength = 0; + width = 0; + height = 0; remainingWidth = maxWidth; length = 1; @@ -5129,9 +4957,9 @@ TextComposite::BackwardAnalyze(int startTextIndex, float maxWidth, int* actualLe if (textSize.width <= remainingWidth) { - *actualLength = length; - *width = textSize.width; - *height = textSize.height; + actualLength = length; + width = textSize.width; + height = textSize.height; } startTextIndex--; diff --git a/src/graphics/text/FGrp_TextTextComposite.h b/src/graphics/text/FGrp_TextTextComposite.h index 562f37f..af6f58c 100644 --- a/src/graphics/text/FGrp_TextTextComposite.h +++ b/src/graphics/text/FGrp_TextTextComposite.h @@ -301,7 +301,7 @@ private: int ComposeInPartialMode(FloatRectangle& rect); - bool BackwardAnalyze(int startTextIndex, float maxWidth, int* actualLength, float* width, float* height); + bool BackwardAnalyze(int startTextIndex, float maxWidth, int& actualLength, float& width, float& height); result DrawAbbrevInMiddleEllipsis(_CanvasImpl& canvasImpl, const FloatRectangle& displayRect, const TextObjectAlignment alignment); diff --git a/src/graphics/text/FGrp_TextTextObject.cpp b/src/graphics/text/FGrp_TextTextObject.cpp index df0175c..e7b5961 100644 --- a/src/graphics/text/FGrp_TextTextObject.cpp +++ b/src/graphics/text/FGrp_TextTextObject.cpp @@ -737,6 +737,7 @@ TextObject::Compose(void) __pTextColumn->SetChangeAction(TextColumn::TEXT_CHANGE_UNKONWN, 0, 0); __pTextColumn->SetFirstDisplayLineIndex(0); __pTextColumn->SetFirstDisplayPositionY(0.0f); + __pTextColumn->SetFirstDisplayPositionX(0.0f); } ResetSweepInfo(); @@ -749,10 +750,11 @@ TextObject::Compose(void) TextLine* pTextLine = __pTextColumn->GetTextLine(0); if (pTextLine != null) { + FloatRectangle lineBounds = pTextLine->GetBoundsF(); int lineLength = pTextLine->GetTextLength(); int totalLength = __pCompositeText->GetTextLength(); - if (lineLength < totalLength) + if (lineLength < totalLength || __rect.width < lineBounds.width) { __isActionOn = true; __pTextColumn->SetSlidingPosition(0.0f); @@ -902,6 +904,48 @@ CATCH: } result +TextObject::SetFirstDisplayPositionX(int x) +{ + return SetFirstDisplayPositionX(_CoordinateSystemUtils::ConvertToFloat(x)); +} + +result +TextObject::SetFirstDisplayPositionX(float x) +{ + IF_NOT_CONSTRUCTED(return E_INVALID_STATE); + SysTryReturn(NID_GRP, __wrap == TEXT_OBJECT_WRAP_TYPE_NONE + , E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The argument is invalid."); + + TextLine* pTextLine = __pTextColumn->GetTextLine(0); + SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line."); + + FloatRectangle lineBounds = pTextLine->GetBoundsF(); + + if (x < 0) + { + x = 0; + } + + __pTextColumn->SetFirstDisplayPositionX(x); + + return E_SUCCESS; +} + +int +TextObject::GetFirstDisplayPositionX(void) const +{ + return _CoordinateSystemUtils::ConvertToInteger(GetFirstDisplayPositionXF()); +} + +float +TextObject::GetFirstDisplayPositionXF(void) const +{ + IF_NOT_CONSTRUCTED(return -1); + + return __pTextColumn->GetFirstDisplayPositionX(); +} + +result TextObject::SetFirstDisplayPositionY(int y) { return SetFirstDisplayPositionY(_CoordinateSystemUtils::ConvertToFloat(y)); @@ -1926,6 +1970,27 @@ TextObject::GetTextIndexFromPosition(float x, float y, bool cursorMode) const } int +TextObject::GetTextIndexFromPosition(float x, float y, int& row, int& column, bool cursorMode) const +{ + IF_NOT_CONSTRUCTED(return -1); + + int lineCount = __pTextColumn->GetTotalLineCount(); + if (lineCount <= 0) + { + return -1; + } + + if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE) + { + return GetTextIndexFromPositionInNoneWrap(x, y, row, column, !cursorMode); + } + else + { + return GetTextIndexFromPositionInWrap(x, y, row, column, !cursorMode); + } +} + +int TextObject::GetTextIndexFromPositionAtLine(int lineIndex, int x, bool cursorMode) const { return GetTextIndexFromPositionAtLine(lineIndex, _CoordinateSystemUtils::ConvertToFloat(x), cursorMode); @@ -2402,6 +2467,115 @@ TextObject::GetTextPositionInfoAt(int textIndex, float& width, float& height, fl } result +TextObject::GetTextPositionInfoAt(int row, int column, float& width, float& height, float& absX, float& absY, float& logicalX, float& logicalY) const +{ + IF_NOT_CONSTRUCTED(return E_INVALID_STATE); + + result r = E_SUCCESS; + TextBidiHint bidiHint = _GetTextBidiHint(); + _SetTextBidiHint(__bidiHint); + + int lineCount = __pTextColumn->GetTotalLineCount(); + + if (lineCount < 1) + { + _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont); + SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance."); + + float maxHeight = TextUtility::GetFontMaxHeightF(pFont); + float posX = 0.0f; + float posY = 0.0f; + absX = 0.0f; + absY = 0.0f; + + if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE) + { + switch (__align & TEXT_ALIGNMASK_VERT) + { + case TEXT_OBJECT_ALIGNMENT_TOP: + break; + + case TEXT_OBJECT_ALIGNMENT_MIDDLE: + posY += (__rect.height - maxHeight) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_BOTTOM: + posY += (__rect.height - maxHeight); + break; + } + logicalY = __rect.y + posY; + + switch (__align & TEXT_ALIGNMASK_HORIZ) + { + case TEXT_OBJECT_ALIGNMENT_LEFT: + break; + + case TEXT_OBJECT_ALIGNMENT_CENTER: + posX += __rect.width / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_RIGHT: + posX += __rect.width; + break; + } + logicalX = __rect.x + posX; + } + else + { + float lineHeight = maxHeight + __pCompositeText->GetLineSpaceF(); + TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment(); + switch (alignment & TEXT_ALIGNMASK_VERT) + { + case TEXT_OBJECT_ALIGNMENT_TOP: + // fall through + default: + break; + + case TEXT_OBJECT_ALIGNMENT_MIDDLE: + posY += (lineHeight - maxHeight) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_BOTTOM: + posY += lineHeight - maxHeight; + break; + } + + switch (__align & TEXT_ALIGNMASK_HORIZ) + { + case TEXT_OBJECT_ALIGNMENT_LEFT: + break; + + case TEXT_OBJECT_ALIGNMENT_CENTER: + posX += __rect.width / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_RIGHT: + posX += __rect.width; + break; + } + + logicalX = posX + __rect.x; + logicalY = posY + __rect.y; + } + + width = 0.0f; + height = maxHeight; + absX = posX; + absY = posY; + } + else + { + r = (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE) ? GetTextPositionInfoInNoneWrapAt(row, column, width, height, absX, absY, logicalX, logicalY) + : GetTextPositionInfoInWrapAt(row, column, width, height, absX, absY, logicalX, logicalY); + SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); + } + + _SetTextBidiHint(bidiHint); + + return E_SUCCESS; +} + +result TextObject::GetBlockTextPositionInfoAt(int textIndex, int& width, int& height, int& absX, int& absY, int& logicalX, int& logicalY) const { float widthF = _CoordinateSystemUtils::ConvertToFloat(width); @@ -2675,6 +2849,110 @@ TextObject::GetTextIndexFromPositionInWrap(float x, float y, bool cursorMode) co } int +TextObject::GetTextIndexFromPositionInWrap(float x, float y, int& row, int& column, bool cursorMode) const +{ + TextLine* pTextLine = null; + FloatRectangle lineBounds; + int firstDisplayLineIndex = __pTextColumn->GetFirstDisplayLineIndex(); + float firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF(); + int lineCount = __pTextColumn->GetTotalLineCount(); + int lineIndex = 0; + float totalHeight = __pTextColumn->GetTotalHeightF(); + + TextBidiHint bidiHint = _GetTextBidiHint(); + _SetTextBidiHint(__bidiHint); + + switch (__align & TEXT_ALIGNMASK_VERT) + { + case TEXT_OBJECT_ALIGNMENT_TOP: + break; + + case TEXT_OBJECT_ALIGNMENT_MIDDLE: + y -= (__rect.height - totalHeight) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_BOTTOM: + y -= (__rect.height - totalHeight); + break; + } + + for (lineIndex = firstDisplayLineIndex; lineIndex < lineCount; lineIndex++) + { + pTextLine = __pTextColumn->GetTextLine(lineIndex); + SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line."); + + lineBounds = pTextLine->GetBoundsF(); + + if (lineIndex == firstDisplayLineIndex) + { + if (y < lineBounds.y - firstDisplayPositionY) + { + return -1; + } + } + + if ((lineBounds.y - firstDisplayPositionY <= y) && (y < lineBounds.y + lineBounds.height - firstDisplayPositionY)) + { + break; + } + + if (lineIndex == lineCount - 1) + { + if (cursorMode) + { + return pTextLine->GetTextLength() + pTextLine->GetTextOffset(); + } + else + { + return -1; + } + } + } + + SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line."); + + int lineLength = pTextLine->GetTextLength(); + Dimension lineTextSize; + pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height); + + switch (__align & TEXT_ALIGNMASK_HORIZ) + { + case TEXT_OBJECT_ALIGNMENT_LEFT: + break; + + case TEXT_OBJECT_ALIGNMENT_CENTER: + x -= (lineBounds.width - lineTextSize.width) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_RIGHT: + x -= (lineBounds.width - lineTextSize.width); + break; + } + + if (x < 0.0f) + { + x = 0.0f; + } + + int index = pTextLine->GetTextIndexFromPosition(x); + row = pTextLine->GetIndex(); + column = index - pTextLine->GetTextOffset(); + + int endType = pTextLine->GetEndType(); + if (endType == TEXT_RETBY_LINEFEED && column == lineLength) + { + index -= 1; + column -= 1; + } + + _SetTextBidiHint(bidiHint); + + SetLastResult(E_SUCCESS); + + return index; +} + +int TextObject::GetTextIndexFromPositionInNoneWrap(int x, int y, bool cursorMode) const { return GetTextIndexFromPositionInNoneWrap(_CoordinateSystemUtils::ConvertToFloat(x), _CoordinateSystemUtils::ConvertToFloat(y), cursorMode); @@ -2687,6 +2965,7 @@ TextObject::GetTextIndexFromPositionInNoneWrap(float x, float y, bool cursorMode FloatRectangle lineBounds; int lineOffset = 0; int lineLength = 0; + float firstDisplayPositionX = __pTextColumn->GetFirstDisplayPositionX(); TextLine* pTextLine = null; pTextLine = __pTextColumn->GetTextLine(0); @@ -2700,6 +2979,8 @@ TextObject::GetTextIndexFromPositionInNoneWrap(float x, float y, bool cursorMode lineBounds = pTextLine->GetBoundsF(); pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height); + x += firstDisplayPositionX; + switch (__align & TEXT_ALIGNMASK_HORIZ) { case TEXT_OBJECT_ALIGNMENT_LEFT: @@ -2741,10 +3022,76 @@ TextObject::GetTextIndexFromPositionInNoneWrap(float x, float y, bool cursorMode return index; } -result -TextObject::SetFirstDisplayLineIndexFromTextIndexInWrap(int textIndex) +int +TextObject::GetTextIndexFromPositionInNoneWrap(float x, float y, int& row, int& column, bool cursorMode) const { - result r = E_SUCCESS; + FloatDimension lineTextSize; + FloatRectangle lineBounds; + int lineOffset = 0; + int lineLength = 0; + float firstDisplayPositionX = __pTextColumn->GetFirstDisplayPositionX(); + TextLine* pTextLine = null; + + pTextLine = __pTextColumn->GetTextLine(0); + SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line."); + + TextBidiHint bidiHint = _GetTextBidiHint(); + _SetTextBidiHint(__bidiHint); + + lineOffset = pTextLine->GetTextOffset(); + lineLength = pTextLine->GetTextLength(); + lineBounds = pTextLine->GetBoundsF(); + pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height); + + x += firstDisplayPositionX; + + switch (__align & TEXT_ALIGNMASK_HORIZ) + { + case TEXT_OBJECT_ALIGNMENT_LEFT: + break; + + case TEXT_OBJECT_ALIGNMENT_CENTER: + x -= (lineBounds.width - lineTextSize.width) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_RIGHT: + x -= (lineBounds.width - lineTextSize.width); + break; + } + + switch (__align & TEXT_ALIGNMASK_VERT) + { + case TEXT_OBJECT_ALIGNMENT_TOP: + break; + + case TEXT_OBJECT_ALIGNMENT_MIDDLE: + y -= (__rect.height - lineTextSize.height) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_BOTTOM: + y -= (__rect.height - lineTextSize.height); + break; + } + + if (x < 0.0f) + { + x = 0.0f; + } + + int index = pTextLine->GetTextIndexFromPosition(x); + row = 0; + column = index; + + _SetTextBidiHint(bidiHint); + + SetLastResult(E_SUCCESS); + return index; +} + +result +TextObject::SetFirstDisplayLineIndexFromTextIndexInWrap(int textIndex) +{ + result r = E_SUCCESS; FloatRectangle lineBounds; float firstDisplayPositionY = 0.0f; int currentTextIndex = textIndex; @@ -2929,13 +3276,15 @@ TextObject::SetFirstDisplayLineIndexFromTextIndexInWrap(int textIndex) result TextObject::SetFirstDisplayLineIndexFromTextIndexInNoneWrap(int textIndex) { - result r = E_SUCCESS; - int currentTextIndex = textIndex; int lineOffset = 0; int lineEndIndex = 0; int lineLength = 0; + int count = 0; + float firstDisplayPositionX = __pTextColumn->GetFirstDisplayPositionX(); FloatRectangle lineBounds; FloatDimension lineTextSize; + FloatDimension currentLinetextSize; + FloatDimension prevTextSize; _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont); SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance."); @@ -2946,71 +3295,66 @@ TextObject::SetFirstDisplayLineIndexFromTextIndexInNoneWrap(int textIndex) lineOffset = pTextLine->GetTextOffset(); lineLength = pTextLine->GetTextLength(); lineEndIndex = pTextLine->GetTextOffset() + pTextLine->GetTextLength(); - lineBounds = pTextLine->GetBoundsF(); - pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height); - if (currentTextIndex < pTextLine->GetTextOffset() + 1) - { - lineOffset = currentTextIndex; - pTextLine->SetTextOffset(lineOffset); - lineOffset = pTextLine->GetTextOffset(); - if (lineOffset > 0) - { - lineOffset--; - pTextLine->SetTextOffset(lineOffset); - } + pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height); - __pCompositeText->ForwardAnalyze(lineOffset, __pCompositeText->GetTextLength() - lineOffset, lineBounds.width, - __wrap, lineLength, lineTextSize.width, lineTextSize.height); + __pCompositeText->ForwardAnalyze(lineOffset, textIndex, lineBounds.width, __wrap, count, currentLinetextSize.width, currentLinetextSize.height); + __pCompositeText->ForwardAnalyze(lineOffset, textIndex - 1, lineBounds.width,__wrap, count, prevTextSize.width, prevTextSize.height); - lineBounds.height = (lineBounds.height > lineTextSize.height) ? lineBounds.height : lineTextSize.height; - if (lineBounds.height == 0.0f) - { - lineBounds.height = TextUtility::GetFontMaxHeightF(pFont); - } + if (prevTextSize.width < firstDisplayPositionX) + { + SetFirstDisplayPositionX(prevTextSize.width); pTextLine->SetBounds(lineBounds); pTextLine->SetRegion(lineTextSize.width, lineTextSize.height); pTextLine->SetTextLength(lineLength); __pCompositeText->GetTextExtentList(pTextLine); } - else if (lineEndIndex <= currentTextIndex) + else if (firstDisplayPositionX + __rect.width <= currentLinetextSize.width) // 글자가 display 영역 뒤로 계속 쓸 때 { - float gapWidth = 0.0f; - float gapHeight = 0.0f; float tempWidth = 0.0f; + float tempHeight = 0.0f; int textCount = 0; - r = __pCompositeText->GetRegion(lineEndIndex, currentTextIndex - lineEndIndex, gapWidth, gapHeight); - SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); + __pCompositeText->ForwardAnalyze(0, textIndex, lineBounds.width, __wrap, textCount, tempWidth, tempHeight); + SetFirstDisplayPositionX(tempWidth - __rect.width); - gapWidth -= lineBounds.width - lineTextSize.width; + pTextLine->SetBounds(lineBounds); + pTextLine->SetRegion(lineTextSize.width, lineTextSize.height); + pTextLine->SetTextOffset(0); + pTextLine->SetTextLength(lineLength); + __pCompositeText->GetTextExtentList(pTextLine); + } + else if (lineBounds.width < firstDisplayPositionX + __rect.width && lineLength <= textIndex) // 글 꽉 채운 후 한글자씩 지울 때 + { + float tempWidth = 0.0f; + float tempHeight = 0.0f; + int textCount = 0; - __pCompositeText->ForwardAnalyze(lineOffset, __pCompositeText->GetTextLength() - lineOffset, gapWidth, __wrap, - textCount, tempWidth, gapHeight); + __pCompositeText->ForwardAnalyze(0, textIndex, lineBounds.width, __wrap, textCount, tempWidth, tempHeight); + SetFirstDisplayPositionX(tempWidth - __rect.width); - if (tempWidth < gapWidth) - { - lineOffset += (textCount + 1); - } - else - { - lineOffset += textCount; - } + pTextLine->SetBounds(lineBounds); + pTextLine->SetRegion(lineTextSize.width, lineTextSize.height); + pTextLine->SetTextOffset(0); + pTextLine->SetTextLength(lineLength); + __pCompositeText->GetTextExtentList(pTextLine); + } + else if (lineBounds.width < firstDisplayPositionX + __rect.width) // 글 꽉 채운 후에, 중간에 글자를 지울 때, + { + float tempWidth = 0.0f; + float tempHeight = 0.0f; + int textCount = 0; - __pCompositeText->ForwardAnalyze(lineOffset, __pCompositeText->GetTextLength() - lineOffset, lineBounds.width, - __wrap, lineLength, lineTextSize.width, lineTextSize.height); + float gap = __rect.width - (lineBounds.width - currentLinetextSize.width); - lineBounds.height = (lineBounds.height > lineTextSize.height) ? lineBounds.height: lineTextSize.height; - if (lineBounds.height == 0.0f) - { - lineBounds.height = TextUtility::GetFontMaxHeightF(pFont); - } + __pCompositeText->ForwardAnalyze(0, textIndex, lineBounds.width, __wrap, textCount, tempWidth, tempHeight); + SetFirstDisplayPositionX(tempWidth - gap); pTextLine->SetBounds(lineBounds); pTextLine->SetRegion(lineTextSize.width, lineTextSize.height); - pTextLine->SetTextOffset(lineOffset); + pTextLine->SetTextOffset(0); pTextLine->SetTextLength(lineLength); __pCompositeText->GetTextExtentList(pTextLine); } @@ -3187,6 +3531,122 @@ TextObject::GetTextPositionInfoInWrapAt(int textIndex, float& width, float& heig } result +TextObject::GetTextPositionInfoInWrapAt(int row, int column, float& width, float& height, float& absX, float& absY, + float& logicalX, float& logicalY) const +{ + TextLine* pTextLine = null; + float firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF(); + int lineCount = __pTextColumn->GetTotalLineCount(); + float posX = 0.0f; + float posY = 0.0f; + + _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont); + SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance."); + + pTextLine = __pTextColumn->GetTextLine(row); + SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line."); + + FloatRectangle lineBounds = pTextLine->GetBoundsF(); + int lineOffset = pTextLine->GetTextOffset(); + int lineLength = pTextLine->GetTextLength(); + int textIndex = pTextLine->GetTextOffset() + column; + float lineY = lineBounds.y; + + SysTryReturn(NID_GRP, lineOffset <= textIndex && textIndex <= lineOffset + lineLength + , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (row = %d column = %d)", row, column); + + FloatDimension lineTextSize; + pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height); + + if (lineTextSize.height == 0) + { + lineTextSize.height = TextUtility::GetFontMaxHeightF(pFont); + } + + switch (__align & TEXT_ALIGNMASK_HORIZ) + { + case TEXT_OBJECT_ALIGNMENT_LEFT: + break; + + case TEXT_OBJECT_ALIGNMENT_CENTER: + posX += (lineBounds.width - lineTextSize.width) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_RIGHT: + posX += (lineBounds.width - lineTextSize.width); + break; + } + + switch (__align & TEXT_ALIGNMASK_VERT) + { + case TEXT_OBJECT_ALIGNMENT_TOP: + break; + + case TEXT_OBJECT_ALIGNMENT_MIDDLE: + posY += (__rect.height - __pTextColumn->GetDisplayHeightF()) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_BOTTOM: + posY += (__rect.height - __pTextColumn->GetDisplayHeightF()); + break; + } + + if (posX < 0.0f) + { + posX = 0.0f; + } + + if (posY < 0.0f) + { + posY = 0.0f; + } + + FloatRectangle textExtent = pTextLine->GetTextExtentF(column, 1); + + if (row == lineCount) + { + textExtent.width = 0.0f; + } + + if (textIndex >= 1) + { + Font* pTextFont = __pCompositeText->GetFont(textIndex - 1); + textExtent.height = TextUtility::GetFontMaxHeightF(pTextFont); + } + + if (textExtent.height < 0.0f) + { + textExtent.height = TextUtility::GetFontMaxHeightF(pFont); + } + + TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment(); + switch (alignment & TEXT_ALIGNMASK_VERT) + { + case TEXT_OBJECT_ALIGNMENT_TOP: + // fall through + default: + break; + + case TEXT_OBJECT_ALIGNMENT_MIDDLE: + lineY = lineY + (lineBounds.height - textExtent.height) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_BOTTOM: + lineY = lineY + (lineBounds.height - textExtent.height); + break; + } + + width = textExtent.width; + height = textExtent.height; + absX = posX + textExtent.x; + logicalX = absX + __rect.x; + absY = lineY; + logicalY = absY - firstDisplayPositionY + __rect.y + posY; + + return E_SUCCESS; +} + +result TextObject::GetBlockTextPositionInfoInWrapAt(int textIndex, int& width, int& height, int& absX, int& absY, int& logicalX, int& logicalY) const { @@ -3384,6 +3844,7 @@ TextObject::GetTextPositionInfoInNoneWrapAt(int textIndex, float& width, float& SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line."); int lineLength = pTextLine->GetTextLength(); + float firstDisplayPositionX = __pTextColumn->GetFirstDisplayPositionX(); float posX = 0.0f; float posY = 0.0f; @@ -3461,7 +3922,104 @@ TextObject::GetTextPositionInfoInNoneWrapAt(int textIndex, float& width, float& break; } - absX = posX + textExtent.x; + absX = posX + textExtent.x - firstDisplayPositionX; + logicalX = (absX >= 0.0f) ? absX + __rect.x : absX; + absY = posY; + logicalY = absY + __rect.y; + width = textExtent.width; + height = textExtent.height; + + return E_SUCCESS; +} + +result +TextObject::GetTextPositionInfoInNoneWrapAt(int row, int column, float& width, float& height, float& absX, float& absY, + float& logicalX, float& logicalY) const +{ + TextLine* pTextLine = null; + pTextLine = __pTextColumn->GetTextLine(row); + SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line."); + + int lineLength = pTextLine->GetTextLength(); + float firstDisplayPositionX = __pTextColumn->GetFirstDisplayPositionX(); + float posX = 0.0f; + float posY = 0.0f; + + _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont); + SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance."); + + FloatDimension lineTextSize; + FloatRectangle lineBounds; + lineBounds = pTextLine->GetBoundsF(); + pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height); + + if (lineTextSize.height == 0.0f || pTextLine->GetTextLength() == 0.0f) + { + lineTextSize.height = TextUtility::GetFontMaxHeightF(pFont); + } + + switch (__align & TEXT_ALIGNMASK_HORIZ) + { + case TEXT_OBJECT_ALIGNMENT_LEFT: + break; + + case TEXT_OBJECT_ALIGNMENT_CENTER: + posX += (lineBounds.width - lineTextSize.width) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_RIGHT: + posX += (lineBounds.width - lineTextSize.width); + break; + } + + switch (__align & TEXT_ALIGNMASK_VERT) + { + case TEXT_OBJECT_ALIGNMENT_TOP: + break; + + case TEXT_OBJECT_ALIGNMENT_MIDDLE: + posY += (__rect.height - lineTextSize.height) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_BOTTOM: + posY += (__rect.height - lineTextSize.height); + break; + } + + posX = (posX < 0.0f) ? 0.0f : posX; + posY = (posY < 0.0f) ? 0.0f : posY; + + FloatRectangle textExtent = pTextLine->GetTextExtentF(column - pTextLine->GetTextOffset(), 1); + + if (column >= 1) + { + Font* pTextFont = __pCompositeText->GetFont(column - 1); + textExtent.height = TextUtility::GetFontMaxHeightF(pTextFont); + } + + if (textExtent.height < 0.0f) + { + textExtent.height = TextUtility::GetFontMaxHeightF(pFont); + } + + TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment(); + switch (alignment & TEXT_ALIGNMASK_VERT) + { + case TEXT_OBJECT_ALIGNMENT_TOP: + // fall through + default: + break; + + case TEXT_OBJECT_ALIGNMENT_MIDDLE: + posY = posY + (lineBounds.height - textExtent.height) / 2.0f; + break; + + case TEXT_OBJECT_ALIGNMENT_BOTTOM: + posY = posY + (lineBounds.height - textExtent.height); + break; + } + + absX = posX + textExtent.x - firstDisplayPositionX; logicalX = (absX >= 0.0f) ? absX + __rect.x : absX; absY = posY; logicalY = absY + __rect.y; @@ -4190,6 +4748,59 @@ TextObject::GetTextBidiHint(void) const } result +TextObject::ConvertToRowColumn(int textIndex, int& row, int& column) const +{ + IF_NOT_CONSTRUCTED(return E_INVALID_STATE); + + SysTryReturn(NID_GRP, textIndex >= 0 && textIndex <= GetTextLength(), E_INVALID_ARG, E_INVALID_ARG + , "[E_INVALID_ARG] The argument is invalid. (textIndex = %d)", textIndex); + + TextLine* pTextLine = null; + int lineIndex = 0; + int lineOffset = 0; + int lineLength = 0; + int lineCount = GetTotalLineCount(); + + for (lineIndex = 0; lineIndex < lineCount; lineIndex++) + { + pTextLine = __pTextColumn->GetTextLine(lineIndex); + SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line."); + + lineOffset = pTextLine->GetTextOffset(); + lineLength = pTextLine->GetTextLength(); + + if (lineOffset <= textIndex && textIndex < lineOffset + lineLength) + { + break; + } + } + + column = (lineIndex == lineCount) ? lineLength : textIndex - lineOffset; + row = (lineIndex == lineCount) ? lineIndex - 1 : lineIndex; + + return E_SUCCESS; +} + +int +TextObject::ConvertToTextIndex(int row, int column) const +{ + IF_NOT_CONSTRUCTED(return -1); + + TextLine* pTextLine = __pTextColumn->GetTextLine(row); + SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line."); + + int lineOffset = pTextLine->GetTextOffset(); + int lineLength = pTextLine->GetTextLength(); + + SysTryReturn(NID_GRP, column <= lineLength, -1, E_INVALID_ARG + , "[E_INVALID_ARG] The argument is invalid. (row = %d, column = %d)", row, column); + + SetLastResult(E_SUCCESS); + + return lineOffset + column; +} + +result TextObject::SetDisplayBoundsExpandEnabled(bool enable) { IF_NOT_CONSTRUCTED(return E_INVALID_STATE); -- 2.7.4