X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller-impl.cpp;h=279f23bf1fa88c8ba74caf467a79ccbc7edfef00;hp=8140c84a0b7545f82d15c525cd0ea6ad11209a52;hb=646440beeb663fc5efcccadeba73dd46016ed1b3;hpb=ac501f02feab8e2fb7e613f936d3d5a511603001 diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 8140c84..279f23b 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -29,11 +29,14 @@ #include #include #include +#include #include #include #include #include #include +#include +#include #include #include @@ -57,6 +60,14 @@ struct BackgroundMesh Vector mIndices; ///< container of indices }; +// The relative luminance of a color is defined as (L = 0.2126 * R + 0.7152 * G + 0.0722 * B) +// based on W3C Recommendations (https://www.w3.org/TR/WCAG20/) +const float BRIGHTNESS_THRESHOLD = 0.179f; +const float CONSTANT_R = 0.2126f; +const float CONSTANT_G = 0.7152f; +const float CONSTANT_B = 0.0722f; +const Dali::Vector4 BLACK(0.f, 0.f, 0.f, 1.f); +const Dali::Vector4 WHITE(1.f, 1.f, 1.f, 1.f); const Dali::Vector4 LIGHT_BLUE(0.75f, 0.96f, 1.f, 1.f); const Dali::Vector4 BACKGROUND_SUB4(0.58f, 0.87f, 0.96f, 1.f); const Dali::Vector4 BACKGROUND_SUB5(0.83f, 0.94f, 0.98f, 1.f); @@ -661,6 +672,39 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) requestedNumberOfCharacters, lineBreakInfo); + if(mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) || + mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::MIXED)) + { + CharacterIndex end = startIndex + requestedNumberOfCharacters; + LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin(); + + for(CharacterIndex index = startIndex; index < end; index++) + { + CharacterIndex wordEnd = index; + while((*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_ALLOW_BREAK) && (*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_MUST_BREAK)) + { + wordEnd++; + } + + if((wordEnd + 1) == end) // add last char + { + wordEnd++; + } + + Vector hyphens = GetWordHyphens(utf32Characters.Begin() + index, wordEnd - index, nullptr); + + for(CharacterIndex i = 0; i < (wordEnd - index); i++) + { + if(hyphens[i]) + { + *(lineBreakInfoBuffer + index + i) = TextAbstraction::LINE_HYPHENATION_BREAK; + } + } + + index = wordEnd; + } + } + // Create the paragraph info. mModel->mLogicalModel->CreateParagraphInfo(startIndex, requestedNumberOfCharacters); @@ -697,13 +741,16 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) TextAbstraction::FontDescription defaultFontDescription; TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale; + //Get the number of points per one unit of point-size + uint32_t numberOfPointsPerOneUnitOfPointSize = mFontClient.GetNumberOfPointsPerOneUnitOfPointSize(); + if(IsShowingPlaceholderText() && mEventData && (nullptr != mEventData->mPlaceholderFont)) { // If the placeholder font is set specifically, only placeholder font is changed. defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription; if(mEventData->mPlaceholderFont->sizeDefined) { - defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * mFontSizeScale * 64u; + defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * mFontSizeScale * numberOfPointsPerOneUnitOfPointSize; } } else if(nullptr != mFontDefaults) @@ -713,11 +760,11 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) if(mTextFitEnabled) { - defaultPointSize = mFontDefaults->mFitPointSize * 64u; + defaultPointSize = mFontDefaults->mFitPointSize * numberOfPointsPerOneUnitOfPointSize; } else { - defaultPointSize = mFontDefaults->mDefaultPointSize * mFontSizeScale * 64u; + defaultPointSize = mFontDefaults->mDefaultPointSize * mFontSizeScale * numberOfPointsPerOneUnitOfPointSize; } } @@ -750,7 +797,7 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) startIndex, requestedNumberOfCharacters, bidirectionalInfo, - mModel->mMatchSystemLanguageDirection, + (mModel->mMatchLayoutDirection != DevelText::MatchLayoutDirection::CONTENTS), mLayoutDirection); if(0u != bidirectionalInfo.Count()) @@ -808,7 +855,7 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters); mModel->mVisualModel->CreateCharacterToGlyphTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters); - updated = true; + updated = true; } const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs; @@ -876,15 +923,36 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) backgroundColorRun.color = textColor; mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun); - Vector4 backgroundColor = mModel->mVisualModel->GetBackgroundColor(); + Vector4 backgroundColor = mModel->mVisualModel->GetBackgroundColor(); + if(backgroundColor.a == 0) // There is no text background color. + { + // Try use the control's background color. + if(nullptr != mEditableControlInterface) + { + mEditableControlInterface->GetControlBackgroundColor(backgroundColor); + if(backgroundColor.a == 0) // There is no control background color. + { + // Determines black or white color according to text color. + // Based on W3C Recommendations (https://www.w3.org/TR/WCAG20/) + float L = CONSTANT_R * textColor.r + CONSTANT_G * textColor.g + CONSTANT_B * textColor.b; + backgroundColor = L > BRIGHTNESS_THRESHOLD ? BLACK : WHITE; + } + } + } + Vector colorRuns; colorRuns.Resize(1u); ColorRun& colorRun = *(colorRuns.Begin()); colorRun.color = backgroundColor; colorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit; colorRun.characterRun.numberOfCharacters = numberOfIndices; - mModel->mLogicalModel->mColorRuns.PushBack(colorRun); + + //Mark-up processor case + if(mModel->mVisualModel->IsMarkupProcessorEnabled()) + { + CopyUnderlinedFromLogicalToVisualModels(false); + } break; } case Dali::InputMethodContext::PreeditStyle::HIGHLIGHT: @@ -894,6 +962,12 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices; backgroundColorRun.color = LIGHT_BLUE; mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun); + + //Mark-up processor case + if(mModel->mVisualModel->IsMarkupProcessorEnabled()) + { + CopyUnderlinedFromLogicalToVisualModels(false); + } break; } case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_1: @@ -1017,9 +1091,9 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) } if((NO_OPERATION != (SHAPE_TEXT & operations)) && - ! ((nullptr != mEventData) && - mEventData->mPreEditFlag && - (0u != mModel->mVisualModel->mCharactersToGlyph.Count()))) + !((nullptr != mEventData) && + mEventData->mPreEditFlag && + (0u != mModel->mVisualModel->mCharactersToGlyph.Count()))) { //Mark-up processor case if(mModel->mVisualModel->IsMarkupProcessorEnabled()) @@ -1030,7 +1104,6 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) updated = true; } - // The estimated number of lines. Used to avoid reallocations when layouting. mTextUpdateInfo.mEstimatedNumberOfLines = std::max(mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count()); @@ -1664,7 +1737,7 @@ void Controller::Impl::GetCursorPosition(CharacterIndex logical, cursorInfo.primaryCursorHeight = cursorInfo.lineHeight; bool isRTL = false; - if(mModel->mMatchSystemLanguageDirection) + if(mModel->mMatchLayoutDirection != DevelText::MatchLayoutDirection::CONTENTS) { isRTL = mLayoutDirection == LayoutDirection::RIGHT_TO_LEFT; } @@ -1979,8 +2052,7 @@ void Controller::Impl::RequestRelayout() Actor Controller::Impl::CreateBackgroundActor() { - // NOTE: Currently we only support background color for one line left-to-right text, - // so the following calculation is based on one line left-to-right text only! + // NOTE: Currently we only support background color for left-to-right text. Actor actor; @@ -2021,8 +2093,12 @@ Actor Controller::Impl::CreateBackgroundActor() const ColorIndex* const backgroundColorIndicesBuffer = mView.GetBackgroundColorIndices(); const Vector4& defaultBackgroundColor = mModel->mVisualModel->IsBackgroundEnabled() ? mModel->mVisualModel->GetBackgroundColor() : Color::TRANSPARENT; - Vector4 quad; - uint32_t numberOfQuads = 0u; + Vector4 quad; + uint32_t numberOfQuads = 0u; + Length yLineOffset = 0; + Length prevLineIndex = 0; + LineIndex lineIndex; + Length numberOfLines; for(uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i) { @@ -2030,8 +2106,18 @@ Actor Controller::Impl::CreateBackgroundActor() // Get the background color of the character. // The color index zero is reserved for the default background color (i.e. Color::TRANSPARENT) - const ColorIndex backgroundColorIndex = (nullptr == backgroundColorsBuffer) ? 0u : *(backgroundColorIndicesBuffer + i); - const Vector4& backgroundColor = (0u == backgroundColorIndex) ? defaultBackgroundColor : *(backgroundColorsBuffer + backgroundColorIndex - 1u); + const bool isMarkupBackground = mView.IsMarkupBackgroundColorSet(); + const ColorIndex backgroundColorIndex = isMarkupBackground ? *(backgroundColorIndicesBuffer + i) : 0u; + const bool isDefaultBackgroundColor = (0u == backgroundColorIndex); + const Vector4& backgroundColor = isDefaultBackgroundColor ? defaultBackgroundColor : *(backgroundColorsBuffer + backgroundColorIndex - 1u); + + mModel->mVisualModel->GetNumberOfLines(i, 1, lineIndex, numberOfLines); + Length lineHeight = lineRun[lineIndex].ascender + -(lineRun[lineIndex].descender) + lineRun[lineIndex].lineSpacing; + + if(lineIndex != prevLineIndex) + { + yLineOffset += lineHeight; + } // Only create quads for glyphs with a background color if(backgroundColor != Color::TRANSPARENT) @@ -2041,30 +2127,30 @@ Actor Controller::Impl::CreateBackgroundActor() if(i == 0u && glyphSize == 1u) // Only one glyph in the whole text { quad.x = position.x; - quad.y = 0.0f; + quad.y = yLineOffset; quad.z = quad.x + std::max(glyph.advance, glyph.xBearing + glyph.width); - quad.w = textSize.height; + quad.w = lineHeight; } - else if(i == 0u) // The first glyph in the whole text + else if((lineIndex != prevLineIndex) || (i == 0u)) // The first glyph in the line { quad.x = position.x; - quad.y = 0.0f; + quad.y = yLineOffset; quad.z = quad.x - glyph.xBearing + glyph.advance; - quad.w = textSize.height; + quad.w = quad.y + lineHeight; } else if(i == glyphSize - 1u) // The last glyph in the whole text { quad.x = position.x - glyph.xBearing; - quad.y = 0.0f; + quad.y = yLineOffset; quad.z = quad.x + std::max(glyph.advance, glyph.xBearing + glyph.width); - quad.w = textSize.height; + quad.w = quad.y + lineHeight; } else // The glyph in the middle of the text { quad.x = position.x - glyph.xBearing; - quad.y = 0.0f; + quad.y = yLineOffset; quad.z = quad.x + glyph.advance; - quad.w = textSize.height; + quad.w = quad.y + lineHeight; } BackgroundVertex vertex; @@ -2103,6 +2189,11 @@ Actor Controller::Impl::CreateBackgroundActor() numberOfQuads++; } + + if(lineIndex != prevLineIndex) + { + prevLineIndex = lineIndex; + } } // Only create the background actor if there are glyphs with background color @@ -2143,28 +2234,28 @@ Actor Controller::Impl::CreateBackgroundActor() void Controller::Impl::CopyUnderlinedFromLogicalToVisualModels(bool shouldClearPreUnderlineRuns) { - //Underlined character runs for markup-processor - const Vector& underlinedCharacterRuns = mModel->mLogicalModel->mUnderlinedCharacterRuns; - const Vector& charactersToGlyph = mModel->mVisualModel->mCharactersToGlyph; - const Vector& glyphsPerCharacter = mModel->mVisualModel->mGlyphsPerCharacter; + //Underlined character runs for markup-processor + const Vector& underlinedCharacterRuns = mModel->mLogicalModel->mUnderlinedCharacterRuns; + const Vector& charactersToGlyph = mModel->mVisualModel->mCharactersToGlyph; + const Vector& glyphsPerCharacter = mModel->mVisualModel->mGlyphsPerCharacter; - if(shouldClearPreUnderlineRuns) - { - mModel->mVisualModel->mUnderlineRuns.Clear(); - } + if(shouldClearPreUnderlineRuns) + { + mModel->mVisualModel->mUnderlineRuns.Clear(); + } - for(Vector::ConstIterator it = underlinedCharacterRuns.Begin(), endIt = underlinedCharacterRuns.End(); it != endIt; ++it) + for(Vector::ConstIterator it = underlinedCharacterRuns.Begin(), endIt = underlinedCharacterRuns.End(); it != endIt; ++it) + { + CharacterIndex characterIndex = it->characterRun.characterIndex; + Length numberOfCharacters = it->characterRun.numberOfCharacters; + for(Length index = 0u; index < numberOfCharacters; index++) { - CharacterIndex characterIndex = it->characterRun.characterIndex; - Length numberOfCharacters = it->characterRun.numberOfCharacters; - for(Length index=0u; indexmVisualModel->mUnderlineRuns.PushBack(underlineGlyphRun); - } + GlyphRun underlineGlyphRun; + underlineGlyphRun.glyphIndex = charactersToGlyph[characterIndex + index]; + underlineGlyphRun.numberOfGlyphs = glyphsPerCharacter[characterIndex + index]; + mModel->mVisualModel->mUnderlineRuns.PushBack(underlineGlyphRun); } + } } } // namespace Text