-
- const bool getScripts = NO_OPERATION != (GET_SCRIPTS & operations);
- const bool validateFonts = NO_OPERATION != (VALIDATE_FONTS & operations);
-
- Vector<ScriptRun>& scripts = mModel->mLogicalModel->mScriptRuns;
- Vector<FontRun>& validFonts = mModel->mLogicalModel->mFontRuns;
-
- if(getScripts || validateFonts)
- {
- // Validates the fonts assigned by the application or assigns default ones.
- // It makes sure all the characters are going to be rendered by the correct font.
- MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
-
- if(getScripts)
- {
- // Retrieves the scripts used in the text.
- multilanguageSupport.SetScripts(utf32Characters,
- startIndex,
- requestedNumberOfCharacters,
- scripts);
- }
-
- if(validateFonts)
- {
- // Validate the fonts set through the mark-up string.
- Vector<FontDescriptionRun>& fontDescriptionRuns = mModel->mLogicalModel->mFontDescriptionRuns;
-
- // Get the default font's description.
- 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 * numberOfPointsPerOneUnitOfPointSize;
- }
- }
- else if(nullptr != mFontDefaults)
- {
- // Set the normal font and the placeholder font.
- defaultFontDescription = mFontDefaults->mFontDescription;
-
- if(mTextFitEnabled)
- {
- defaultPointSize = mFontDefaults->mFitPointSize * numberOfPointsPerOneUnitOfPointSize;
- }
- else
- {
- defaultPointSize = mFontDefaults->mDefaultPointSize * mFontSizeScale * numberOfPointsPerOneUnitOfPointSize;
- }
- }
-
- // Validates the fonts. If there is a character with no assigned font it sets a default one.
- // After this call, fonts are validated.
- multilanguageSupport.ValidateFonts(utf32Characters,
- scripts,
- fontDescriptionRuns,
- defaultFontDescription,
- defaultPointSize,
- startIndex,
- requestedNumberOfCharacters,
- validFonts);
- }
- updated = true;
- }
-
- Vector<Character> mirroredUtf32Characters;
- bool textMirrored = false;
- const Length numberOfParagraphs = mModel->mLogicalModel->mParagraphInfo.Count();
- if(NO_OPERATION != (BIDI_INFO & operations))
- {
- Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = mModel->mLogicalModel->mBidirectionalParagraphInfo;
- bidirectionalInfo.Reserve(numberOfParagraphs);
-
- // Calculates the bidirectional info for the whole paragraph if it contains right to left scripts.
- SetBidirectionalInfo(utf32Characters,
- scripts,
- lineBreakInfo,
- startIndex,
- requestedNumberOfCharacters,
- bidirectionalInfo,
- mModel->mMatchSystemLanguageDirection,
- mLayoutDirection);
-
- if(0u != bidirectionalInfo.Count())
- {
- // Only set the character directions if there is right to left characters.
- Vector<CharacterDirection>& directions = mModel->mLogicalModel->mCharacterDirections;
- GetCharactersDirection(bidirectionalInfo,
- numberOfCharacters,
- startIndex,
- requestedNumberOfCharacters,
- directions);
-
- // This paragraph has right to left text. Some characters may need to be mirrored.
- // TODO: consider if the mirrored string can be stored as well.
-
- textMirrored = GetMirroredText(utf32Characters,
- directions,
- bidirectionalInfo,
- startIndex,
- requestedNumberOfCharacters,
- mirroredUtf32Characters);
- }
- else
- {
- // There is no right to left characters. Clear the directions vector.
- mModel->mLogicalModel->mCharacterDirections.Clear();
- }
- updated = true;
- }
-
- Vector<GlyphInfo>& glyphs = mModel->mVisualModel->mGlyphs;
- Vector<CharacterIndex>& glyphsToCharactersMap = mModel->mVisualModel->mGlyphsToCharacters;
- Vector<Length>& charactersPerGlyph = mModel->mVisualModel->mCharactersPerGlyph;
- Vector<GlyphIndex> newParagraphGlyphs;
- newParagraphGlyphs.Reserve(numberOfParagraphs);
-
- const Length currentNumberOfGlyphs = glyphs.Count();
- if(NO_OPERATION != (SHAPE_TEXT & operations))
- {
- const Vector<Character>& textToShape = textMirrored ? mirroredUtf32Characters : utf32Characters;
- // Shapes the text.
- ShapeText(textToShape,
- lineBreakInfo,
- scripts,
- validFonts,
- startIndex,
- mTextUpdateInfo.mStartGlyphIndex,
- requestedNumberOfCharacters,
- glyphs,
- glyphsToCharactersMap,
- charactersPerGlyph,
- newParagraphGlyphs);
-
- // Create the 'number of glyphs' per character and the glyph to character conversion tables.
- mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
- mModel->mVisualModel->CreateCharacterToGlyphTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
-
- updated = true;
- }
-
- const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs;
-
- if(NO_OPERATION != (GET_GLYPH_METRICS & operations))
- {
- GlyphInfo* glyphsBuffer = glyphs.Begin();
- mMetrics->GetGlyphMetrics(glyphsBuffer + mTextUpdateInfo.mStartGlyphIndex, numberOfGlyphs);
-
- // Update the width and advance of all new paragraph characters.
- for(Vector<GlyphIndex>::ConstIterator it = newParagraphGlyphs.Begin(), endIt = newParagraphGlyphs.End(); it != endIt; ++it)
- {
- const GlyphIndex index = *it;
- GlyphInfo& glyph = *(glyphsBuffer + index);
-
- glyph.xBearing = 0.f;
- glyph.width = 0.f;
- glyph.advance = 0.f;
- }
- updated = true;
- }
-
- if((nullptr != mEventData) &&
- mEventData->mPreEditFlag &&
- (0u != mModel->mVisualModel->mCharactersToGlyph.Count()))
- {
- Dali::InputMethodContext::PreEditAttributeDataContainer attrs;
- mEventData->mInputMethodContext.GetPreeditStyle(attrs);
- Dali::InputMethodContext::PreeditStyle type = Dali::InputMethodContext::PreeditStyle::NONE;
-
- // Check the type of preedit and run it.
- for(Dali::InputMethodContext::PreEditAttributeDataContainer::Iterator it = attrs.Begin(), endIt = attrs.End(); it != endIt; it++)
- {
- Dali::InputMethodContext::PreeditAttributeData attrData = *it;
- DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::UpdateModel PreeditStyle type : %d start %d end %d \n", attrData.preeditType, attrData.startIndex, attrData.endIndex);
- type = attrData.preeditType;
-
- // Check the number of commit characters for the start position.
- unsigned int numberOfCommit = mEventData->mPrimaryCursorPosition - mEventData->mPreEditLength;
- Length numberOfIndices = attrData.endIndex - attrData.startIndex;
-
- switch(type)
- {
- case Dali::InputMethodContext::PreeditStyle::UNDERLINE:
- {
- // Add the underline for the pre-edit text.
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::REVERSE:
- {
- Vector4 textColor = mModel->mVisualModel->GetTextColor();
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = textColor;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
- 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:
- {
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- 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:
- {
- // CUSTOM_PLATFORM_STYLE_1 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB4;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_2:
- {
- // CUSTOM_PLATFORM_STYLE_2 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB5;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_3:
- {
- // CUSTOM_PLATFORM_STYLE_3 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB6;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_4:
- {
- // CUSTOM_PLATFORM_STYLE_4 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB7;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::NONE:
- default:
- {
- break;
- }
- }
- }
- attrs.Clear();
- updated = true;
- }
-
- if(NO_OPERATION != (COLOR & operations))
- {
- // Set the color runs in glyphs.
- SetColorSegmentationInfo(mModel->mLogicalModel->mColorRuns,
- mModel->mVisualModel->mCharactersToGlyph,
- mModel->mVisualModel->mGlyphsPerCharacter,
- startIndex,
- mTextUpdateInfo.mStartGlyphIndex,
- requestedNumberOfCharacters,
- mModel->mVisualModel->mColors,
- mModel->mVisualModel->mColorIndices);
-
- // Set the background color runs in glyphs.
- SetColorSegmentationInfo(mModel->mLogicalModel->mBackgroundColorRuns,
- mModel->mVisualModel->mCharactersToGlyph,
- mModel->mVisualModel->mGlyphsPerCharacter,
- startIndex,
- mTextUpdateInfo.mStartGlyphIndex,
- requestedNumberOfCharacters,
- mModel->mVisualModel->mBackgroundColors,
- mModel->mVisualModel->mBackgroundColorIndices);
-
- updated = true;
- }
-
- if((NO_OPERATION != (SHAPE_TEXT & operations)) &&
- !((nullptr != mEventData) &&
- mEventData->mPreEditFlag &&
- (0u != mModel->mVisualModel->mCharactersToGlyph.Count())))
- {
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(true);
- }
-
- 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());
-
- // Set the previous number of characters for the next time the text is updated.
- mTextUpdateInfo.mPreviousNumberOfCharacters = numberOfCharacters;
-
- return updated;
-}
-
-void Controller::Impl::RetrieveDefaultInputStyle(InputStyle& inputStyle)
-{
- // Sets the default text's color.
- inputStyle.textColor = mTextColor;
- inputStyle.isDefaultColor = true;
-
- inputStyle.familyName.clear();
- inputStyle.weight = TextAbstraction::FontWeight::NORMAL;
- inputStyle.width = TextAbstraction::FontWidth::NORMAL;
- inputStyle.slant = TextAbstraction::FontSlant::NORMAL;
- inputStyle.size = 0.f;
-
- inputStyle.lineSpacing = 0.f;
-
- inputStyle.underlineProperties.clear();
- inputStyle.shadowProperties.clear();
- inputStyle.embossProperties.clear();
- inputStyle.outlineProperties.clear();
-
- inputStyle.isFamilyDefined = false;
- inputStyle.isWeightDefined = false;
- inputStyle.isWidthDefined = false;
- inputStyle.isSlantDefined = false;
- inputStyle.isSizeDefined = false;
-
- inputStyle.isLineSpacingDefined = false;
-
- inputStyle.isUnderlineDefined = false;
- inputStyle.isShadowDefined = false;
- inputStyle.isEmbossDefined = false;
- inputStyle.isOutlineDefined = false;
-
- // Sets the default font's family name, weight, width, slant and size.
- if(mFontDefaults)
- {
- if(mFontDefaults->familyDefined)
- {
- inputStyle.familyName = mFontDefaults->mFontDescription.family;
- inputStyle.isFamilyDefined = true;
- }
-
- if(mFontDefaults->weightDefined)
- {
- inputStyle.weight = mFontDefaults->mFontDescription.weight;
- inputStyle.isWeightDefined = true;
- }
-
- if(mFontDefaults->widthDefined)
- {
- inputStyle.width = mFontDefaults->mFontDescription.width;
- inputStyle.isWidthDefined = true;
- }
-
- if(mFontDefaults->slantDefined)
- {
- inputStyle.slant = mFontDefaults->mFontDescription.slant;
- inputStyle.isSlantDefined = true;
- }
-
- if(mFontDefaults->sizeDefined)
- {
- inputStyle.size = mFontDefaults->mDefaultPointSize;
- inputStyle.isSizeDefined = true;
- }
- }
-}
-
-float Controller::Impl::GetDefaultFontLineHeight()
-{
- FontId defaultFontId = 0u;
- if(nullptr == mFontDefaults)
- {
- TextAbstraction::FontDescription fontDescription;
- defaultFontId = mFontClient.GetFontId(fontDescription, TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale);
- }
- else
- {
- defaultFontId = mFontDefaults->GetFontId(mFontClient, mFontDefaults->mDefaultPointSize * mFontSizeScale);
- }
-
- Text::FontMetrics fontMetrics;
- mMetrics->GetFontMetrics(defaultFontId, fontMetrics);
-
- return (fontMetrics.ascender - fontMetrics.descender);