#include <dali-toolkit/internal/text/shaper.h>
#include <dali-toolkit/internal/text/text-control-interface.h>
#include <dali-toolkit/internal/text/text-controller-impl-event-handler.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
+#include <dali-toolkit/internal/text/text-enumerations-impl.h>
#include <dali-toolkit/internal/text/text-run-container.h>
#include <dali-toolkit/internal/text/text-selection-handle-controller.h>
-#include <dali-toolkit/internal/text/text-enumerations-impl.h>
-
using namespace Dali;
namespace
Vector<unsigned short> 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);
mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
mModel->mVisualModel->CreateCharacterToGlyphTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
- updated = true;
+ updated = true;
}
const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs;
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<ColorRun> 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:
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:
}
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())
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());
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;
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)
{
const ColorIndex backgroundColorIndex = (nullptr == backgroundColorsBuffer) ? 0u : *(backgroundColorIndicesBuffer + i);
const Vector4& backgroundColor = (0u == backgroundColorIndex) ? 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)
{
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;
numberOfQuads++;
}
+
+ if(lineIndex != prevLineIndex)
+ {
+ prevLineIndex = lineIndex;
+ }
}
// Only create the background actor if there are glyphs with background color
void Controller::Impl::CopyUnderlinedFromLogicalToVisualModels(bool shouldClearPreUnderlineRuns)
{
- //Underlined character runs for markup-processor
- const Vector<UnderlinedCharacterRun>& underlinedCharacterRuns = mModel->mLogicalModel->mUnderlinedCharacterRuns;
- const Vector<GlyphIndex>& charactersToGlyph = mModel->mVisualModel->mCharactersToGlyph;
- const Vector<Length>& glyphsPerCharacter = mModel->mVisualModel->mGlyphsPerCharacter;
+ //Underlined character runs for markup-processor
+ const Vector<UnderlinedCharacterRun>& underlinedCharacterRuns = mModel->mLogicalModel->mUnderlinedCharacterRuns;
+ const Vector<GlyphIndex>& charactersToGlyph = mModel->mVisualModel->mCharactersToGlyph;
+ const Vector<Length>& glyphsPerCharacter = mModel->mVisualModel->mGlyphsPerCharacter;
- if(shouldClearPreUnderlineRuns)
- {
- mModel->mVisualModel->mUnderlineRuns.Clear();
- }
+ if(shouldClearPreUnderlineRuns)
+ {
+ mModel->mVisualModel->mUnderlineRuns.Clear();
+ }
- for(Vector<UnderlinedCharacterRun>::ConstIterator it = underlinedCharacterRuns.Begin(), endIt = underlinedCharacterRuns.End(); it != endIt; ++it)
+ for(Vector<UnderlinedCharacterRun>::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; index<numberOfCharacters; index++)
- {
- GlyphRun underlineGlyphRun;
- underlineGlyphRun.glyphIndex = charactersToGlyph[characterIndex + index];
- underlineGlyphRun.numberOfGlyphs = glyphsPerCharacter[characterIndex + index];
- mModel->mVisualModel->mUnderlineRuns.PushBack(underlineGlyphRun);
- }
+ GlyphRun underlineGlyphRun;
+ underlineGlyphRun.glyphIndex = charactersToGlyph[characterIndex + index];
+ underlineGlyphRun.numberOfGlyphs = glyphsPerCharacter[characterIndex + index];
+ mModel->mVisualModel->mUnderlineRuns.PushBack(underlineGlyphRun);
}
+ }
}
} // namespace Text