logicalModel->mFontDescriptionRuns,
logicalModel->mEmbeddedItems,
logicalModel->mAnchors,
- logicalModel->mUnderlinedCharacterRuns);
+ logicalModel->mUnderlinedCharacterRuns,
+ logicalModel->mBackgroundColorRuns);
Length textSize = 0u;
const uint8_t* utf8 = NULL;
/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Vector<EmbeddedItem> items;
Vector<Anchor> anchors;
Vector<UnderlinedCharacterRun> underlinedCharacterRuns;
- MarkupProcessData markupProcessData( colorRuns, fontRuns, items, anchors, underlinedCharacterRuns );
+ Vector<ColorRun> backgroundColorRuns;
+ MarkupProcessData markupProcessData( colorRuns, fontRuns, items, anchors, underlinedCharacterRuns, backgroundColorRuns );
ProcessMarkupString( data.xHTMLEntityString, markupProcessData );
for( Vector<EmbeddedItem>::Iterator it = items.Begin(),
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
DALI_TEST_EQUALS( countAtlas, 1, TEST_LOCATION );
END_TEST;
+}
+
+int UtcDaliTextEditorBackgroundTag(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliTextEditorBackgroundTag\n");
+
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK( editor );
+
+ editor.SetProperty( TextEditor ::Property::ENABLE_MARKUP, true );
+ editor.SetProperty( TextEditor::Property::TEXT, "H<background color='red'>e</background> Worl<background color='yellow'>d</background>" );
+ application.GetScene().Add( editor );
+ application.SendNotification();
+ application.Render();
+
+ Toolkit::Internal::TextEditor& editorImpl = GetImpl( editor );
+ const ColorIndex* const backgroundColorIndicesBuffer = editorImpl.getController()->GetTextModel()->GetBackgroundColorIndices();
+
+ DALI_TEST_CHECK( backgroundColorIndicesBuffer );
+
+ //default color
+ DALI_TEST_EQUALS( backgroundColorIndicesBuffer[0], 0u, TEST_LOCATION);
+
+ //red color
+ DALI_TEST_EQUALS( backgroundColorIndicesBuffer[1], 1u, TEST_LOCATION);
+
+ //yellow color
+ DALI_TEST_EQUALS( backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
+
+ END_TEST;
}
\ No newline at end of file
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
END_TEST;
+}
+
+int UtcDaliTextFieldBackgroundTag(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliTextFieldBackgroundTag\n");
+
+ TextField field = TextField::New();
+ DALI_TEST_CHECK( field );
+
+ field.SetProperty( TextField ::Property::ENABLE_MARKUP, true );
+ field.SetProperty( TextField::Property::TEXT, "H<background color='red'>e</background> Worl<background color='yellow'>d</background>" );
+ application.GetScene().Add( field );
+ application.SendNotification();
+ application.Render();
+
+ Toolkit::Internal::TextField& fieldImpl = GetImpl( field );
+ const ColorIndex* const backgroundColorIndicesBuffer = fieldImpl.getController()->GetTextModel()->GetBackgroundColorIndices();
+
+ DALI_TEST_CHECK( backgroundColorIndicesBuffer );
+
+ //default color
+ DALI_TEST_EQUALS( backgroundColorIndicesBuffer[0], 0u, TEST_LOCATION);
+
+ //red color
+ DALI_TEST_EQUALS( backgroundColorIndicesBuffer[1], 1u, TEST_LOCATION);
+
+ //yellow color
+ DALI_TEST_EQUALS( backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
+
+ END_TEST;
}
\ No newline at end of file
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
END_TEST;
+}
+
+int UtcDaliTextLabelBackgroundTag(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliTextLabelBackgroundTag\n");
+
+ TextLabel label = TextLabel::New();
+ DALI_TEST_CHECK( label );
+
+ label.SetProperty( TextLabel ::Property::ENABLE_MARKUP, true );
+ label.SetProperty( TextLabel::Property::TEXT, "H<background color='red'>e</background> Worl<background color='yellow'>d</background>" );
+ application.GetScene().Add( label );
+ application.SendNotification();
+ application.Render();
+
+ Toolkit::Internal::TextLabel& labelImpl = GetImpl( label );
+ const ColorIndex* const backgroundColorIndicesBuffer = labelImpl.getController()->GetTextModel()->GetBackgroundColorIndices();
+
+ DALI_TEST_CHECK( backgroundColorIndicesBuffer );
+
+ //default color
+ DALI_TEST_EQUALS( backgroundColorIndicesBuffer[0], 0u, TEST_LOCATION);
+
+ //red color
+ DALI_TEST_EQUALS( backgroundColorIndicesBuffer[1], 1u, TEST_LOCATION);
+
+ //yellow color
+ DALI_TEST_EQUALS( backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
+
+ END_TEST;
}
\ No newline at end of file
fontDescriptionRuns,
textModel->mLogicalModel->mEmbeddedItems,
textModel->mLogicalModel->mAnchors,
- textModel->mLogicalModel->mUnderlinedCharacterRuns);
+ textModel->mLogicalModel->mUnderlinedCharacterRuns,
+ textModel->mLogicalModel->mBackgroundColorRuns);
if(textParameters.markupEnabled)
{
if(renderableActor != mRenderableActor)
{
+ UnparentAndReset(mBackgroundActor);
UnparentAndReset(mRenderableActor);
mRenderableActor = renderableActor;
+
+ if(mRenderableActor)
+ {
+ mBackgroundActor = mController->CreateBackgroundActor();
+ }
}
}
if(mRenderableActor)
{
+ const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
+
+ float renderableActorPositionX, renderableActorPositionY;
+
+ if(mStencil)
+ {
+ renderableActorPositionX = scrollOffset.x + mAlignmentOffset;
+ renderableActorPositionY = scrollOffset.y;
+ }
+ else
+ {
+ Extents padding;
+ padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
+
+ // Support Right-To-Left of padding
+ Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
+ if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
+ {
+ std::swap(padding.start, padding.end);
+ }
+
+ renderableActorPositionX = scrollOffset.x + mAlignmentOffset + padding.start;
+ renderableActorPositionY = scrollOffset.y + padding.top;
+ }
+
+ mRenderableActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY));
// Make sure the actors are parented correctly with/without clipping
Actor self = mStencil ? mStencil : Self();
+ Actor highlightActor;
+
for(std::vector<Actor>::iterator it = mClippingDecorationActors.begin(),
endIt = mClippingDecorationActors.end();
it != endIt;
{
self.Add(*it);
it->LowerToBottom();
+
+ if(it->GetProperty<std::string>(Dali::Actor::Property::NAME) == "HighlightActor")
+ {
+ highlightActor = *it;
+ }
}
mClippingDecorationActors.clear();
self.Add(mRenderableActor);
+ if(mBackgroundActor)
+ {
+ if(mDecorator && mDecorator->IsHighlightVisible())
+ {
+ self.Add(mBackgroundActor);
+ mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY)); // In text field's coords.
+ mBackgroundActor.LowerBelow(highlightActor);
+ }
+ else
+ {
+ mRenderableActor.Add(mBackgroundActor);
+ mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); // In renderable actor's coords.
+ mBackgroundActor.LowerToBottom();
+ }
+ }
+
ApplyScrollPosition();
}
UpdateScrollBar();
return states;
}
-bool TextEditor::AccessibleImpl::InsertText(size_t startPosition,
+bool TextEditor::AccessibleImpl::InsertText(size_t startPosition,
std::string text)
{
auto slf = Toolkit::TextEditor::DownCast(Self());
Actor mRenderableActor;
Actor mActiveLayer;
+ Actor mBackgroundActor;
CallbackBase* mIdleCallback;
float mAlignmentOffset;
${toolkit_src_dir}/text/markup-processor-embedded-item.cpp
${toolkit_src_dir}/text/markup-processor-anchor.cpp
${toolkit_src_dir}/text/markup-processor-font.cpp
+ ${toolkit_src_dir}/text/markup-processor-background.cpp
${toolkit_src_dir}/text/markup-processor-helper-functions.cpp
${toolkit_src_dir}/text/multi-language-support.cpp
${toolkit_src_dir}/text/hidden-text.cpp
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/text/markup-processor-background.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <memory.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace
+{
+const std::string XHTML_COLOR_ATTRIBUTE("color");
+} // namespace
+
+void ProcessBackground(const Tag& tag, ColorRun& colorRun)
+{
+ for(auto&& attribute : tag.attributes)
+ {
+ if(TokenComparison(XHTML_COLOR_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ ColorStringToVector4(attribute.valueBuffer, attribute.valueLength, colorRun.color);
+ }
+ }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_BACKGROUND_H
+#define DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_BACKGROUND_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+struct Tag;
+struct ColorRun;
+
+/**
+ * @brief Retrieves the @e background from the @p tag.
+ *
+ * @param[in] tag The background tag and its attributes.
+ * @param[in,out] colorRun The color run to be filled.
+ */
+void ProcessBackground(const Tag& tag, ColorRun& colorRun);
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_BACKGROUND_H
\ No newline at end of file
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/character-set-conversion.h>
#include <dali-toolkit/internal/text/markup-processor-anchor.h>
+#include <dali-toolkit/internal/text/markup-processor-background.h>
#include <dali-toolkit/internal/text/markup-processor-color.h>
#include <dali-toolkit/internal/text/markup-processor-embedded-item.h>
#include <dali-toolkit/internal/text/markup-processor-font.h>
const std::string XHTML_OUTLINE_TAG("outline");
const std::string XHTML_ITEM_TAG("item");
const std::string XHTML_ANCHOR_TAG("a");
+const std::string XHTML_BACKGROUND_TAG("background");
const char LESS_THAN = '<';
const char GREATER_THAN = '>';
* @param[in] fontRunIndex The font run index
* @param[in] colorRunIndex The color run index
* @param[in] underlinedCharacterRunIndex The underlined character run index
+ * @param[in] backgroundRunIndex The background run index
*/
-void ResizeModelVectors(MarkupProcessData& markupProcessData, const StyleStack::RunIndex fontRunIndex, const StyleStack::RunIndex colorRunIndex, const StyleStack::RunIndex underlinedCharacterRunIndex)
+void ResizeModelVectors(MarkupProcessData& markupProcessData, const StyleStack::RunIndex fontRunIndex, const StyleStack::RunIndex colorRunIndex, const StyleStack::RunIndex underlinedCharacterRunIndex, const StyleStack::RunIndex backgroundRunIndex)
{
markupProcessData.fontRuns.Resize(fontRunIndex);
markupProcessData.colorRuns.Resize(colorRunIndex);
markupProcessData.underlinedCharacterRuns.Resize(underlinedCharacterRunIndex);
+ markupProcessData.backgroundColorRuns.Resize(backgroundRunIndex);
#ifdef DEBUG_ENABLED
for(unsigned int i = 0; i < colorRunIndex; ++i)
StyleStack styleStack;
// Points the next free position in the vector of runs.
- StyleStack::RunIndex colorRunIndex = 0u;
- StyleStack::RunIndex fontRunIndex = 0u;
- StyleStack::RunIndex underlinedCharacterRunIndex = 0u;
+ StyleStack::RunIndex colorRunIndex = 0u;
+ StyleStack::RunIndex fontRunIndex = 0u;
+ StyleStack::RunIndex underlinedCharacterRunIndex = 0u;
+ StyleStack::RunIndex backgroundRunIndex = 0u;
// check tag reference
- int colorTagReference = 0u;
- int fontTagReference = 0u;
- int iTagReference = 0u;
- int bTagReference = 0u;
- int uTagReference = 0u;
+ int colorTagReference = 0u;
+ int fontTagReference = 0u;
+ int iTagReference = 0u;
+ int bTagReference = 0u;
+ int uTagReference = 0u;
+ int backgroundTagReference = 0u;
// Give an initial default value to the model's vectors.
markupProcessData.colorRuns.Reserve(DEFAULT_VECTOR_SIZE);
markupProcessData.fontRuns.Reserve(DEFAULT_VECTOR_SIZE);
markupProcessData.underlinedCharacterRuns.Reserve(DEFAULT_VECTOR_SIZE);
+ markupProcessData.backgroundColorRuns.Reserve(DEFAULT_VECTOR_SIZE);
// Get the mark-up string buffer.
const char* markupStringBuffer = markupString.c_str();
else if(TokenComparison(XHTML_U_TAG, tag.buffer, tag.length))
{
ProcessTagForRun<UnderlinedCharacterRun>(
- markupProcessData.underlinedCharacterRuns, styleStack, tag, characterIndex, underlinedCharacterRunIndex, uTagReference, [](const Tag& tag, UnderlinedCharacterRun& run) { });
- } // <u></u>
+ markupProcessData.underlinedCharacterRuns, styleStack, tag, characterIndex, underlinedCharacterRunIndex, uTagReference, [](const Tag& tag, UnderlinedCharacterRun& run) {});
+ } // <u></u>
else if(TokenComparison(XHTML_B_TAG, tag.buffer, tag.length))
{
ProcessTagForRun<FontDescriptionRun>(
{
ProcessItemTag(markupProcessData, tag, characterIndex);
}
+ else if(TokenComparison(XHTML_BACKGROUND_TAG, tag.buffer, tag.length))
+ {
+ ProcessTagForRun<ColorRun>(
+ markupProcessData.backgroundColorRuns, styleStack, tag, characterIndex, backgroundRunIndex, backgroundTagReference, [](const Tag& tag, ColorRun& run) { ProcessBackground(tag, run); });
+ }
} // end if( IsTag() )
else if(markupStringBuffer < markupStringEndBuffer)
{
}
// Resize the model's vectors.
- ResizeModelVectors(markupProcessData, fontRunIndex, colorRunIndex, underlinedCharacterRunIndex);
+ ResizeModelVectors(markupProcessData, fontRunIndex, colorRunIndex, underlinedCharacterRunIndex, backgroundRunIndex);
}
} // namespace Text
*/
struct MarkupProcessData
{
- MarkupProcessData(Vector<ColorRun>& colorRuns,
- Vector<FontDescriptionRun>& fontRuns,
- Vector<EmbeddedItem>& items,
- Vector<Anchor>& anchors,
- Vector<UnderlinedCharacterRun>& underlinedCharacterRuns)
+ MarkupProcessData(Vector<ColorRun>& colorRuns,
+ Vector<FontDescriptionRun>& fontRuns,
+ Vector<EmbeddedItem>& items,
+ Vector<Anchor>& anchors,
+ Vector<UnderlinedCharacterRun>& underlinedCharacterRuns,
+ Vector<ColorRun>& backgroundColorRuns)
: colorRuns(colorRuns),
fontRuns(fontRuns),
items(items),
anchors(anchors),
underlinedCharacterRuns(underlinedCharacterRuns),
+ backgroundColorRuns(backgroundColorRuns),
markupProcessedText()
{
}
Vector<EmbeddedItem>& items; ///< The embedded items.
Vector<Anchor>& anchors; ///< The anchors.
Vector<UnderlinedCharacterRun>& underlinedCharacterRuns; ///< The underlined character runs.
+ Vector<ColorRun>& backgroundColorRuns; ///< The background color runs.
std::string markupProcessedText; ///< The mark-up string.
};
}
}
+Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuffer& buffer, const unsigned int bufferWidth, const unsigned int bufferHeight, bool ignoreHorizontalAlignment, int horizontalOffset, int verticalOffset)
+{
+ // Retrieve lines, glyphs, positions and colors from the view model.
+ const Length modelNumberOfLines = model->GetNumberOfLines();
+ const LineRun* const modelLinesBuffer = model->GetLines();
+ const Length numberOfGlyphs = model->GetNumberOfGlyphs();
+ const GlyphInfo* const glyphsBuffer = model->GetGlyphs();
+ const Vector2* const positionBuffer = model->GetLayout();
+ const Vector4* const backgroundColorsBuffer = model->GetBackgroundColors();
+ const ColorIndex* const backgroundColorIndicesBuffer = model->GetBackgroundColorIndices();
+
+ // Create and initialize the pixel buffer.
+ GlyphData glyphData;
+ glyphData.verticalOffset = verticalOffset;
+ glyphData.width = bufferWidth;
+ glyphData.height = bufferHeight;
+ glyphData.bitmapBuffer = buffer;
+ glyphData.horizontalOffset = 0;
+
+ ColorIndex prevBackgroundColorIndex = 0;
+ ColorIndex backgroundColorIndex = 0;
+
+ // Traverses the lines of the text.
+ for(LineIndex lineIndex = 0u; lineIndex < modelNumberOfLines; ++lineIndex)
+ {
+ const LineRun& line = *(modelLinesBuffer + lineIndex);
+
+ // Sets the horizontal offset of the line.
+ glyphData.horizontalOffset = ignoreHorizontalAlignment ? 0 : static_cast<int>(line.alignmentOffset);
+ glyphData.horizontalOffset += horizontalOffset;
+
+ // Increases the vertical offset with the line's ascender.
+ glyphData.verticalOffset += static_cast<int>(line.ascender);
+
+ // Include line spacing after first line
+ if(lineIndex > 0u)
+ {
+ glyphData.verticalOffset += static_cast<int>(line.lineSpacing);
+ }
+
+ float left = bufferWidth;
+ float right = 0.0f;
+ float baseline = 0.0f;
+
+ // Traverses the glyphs of the line.
+ const GlyphIndex endGlyphIndex = std::min(numberOfGlyphs, line.glyphRun.glyphIndex + line.glyphRun.numberOfGlyphs);
+ for(GlyphIndex glyphIndex = line.glyphRun.glyphIndex; glyphIndex < endGlyphIndex; ++glyphIndex)
+ {
+ // Retrieve the glyph's info.
+ const GlyphInfo* const glyphInfo = glyphsBuffer + glyphIndex;
+
+ if((glyphInfo->width < Math::MACHINE_EPSILON_1000) ||
+ (glyphInfo->height < Math::MACHINE_EPSILON_1000))
+ {
+ // Nothing to do if default background color, the glyph's width or height is zero.
+ continue;
+ }
+
+ backgroundColorIndex = (nullptr == backgroundColorsBuffer) ? 0u : *(backgroundColorIndicesBuffer + glyphIndex);
+
+ if((backgroundColorIndex != prevBackgroundColorIndex) &&
+ (prevBackgroundColorIndex != 0u))
+ {
+ const Vector4& backgroundColor = *(backgroundColorsBuffer + prevBackgroundColorIndex - 1u);
+ DrawBackgroundColor(backgroundColor, bufferWidth, bufferHeight, glyphData, baseline, line, left, right);
+ }
+
+ if(backgroundColorIndex == 0u)
+ {
+ prevBackgroundColorIndex = backgroundColorIndex;
+ //if background color is the default do nothing
+ continue;
+ }
+
+ // Retrieves the glyph's position.
+ const Vector2* const position = positionBuffer + glyphIndex;
+
+ if(baseline < position->y + glyphInfo->yBearing)
+ {
+ baseline = position->y + glyphInfo->yBearing;
+ }
+
+ // Calculate the positions of leftmost and rightmost glyphs in the current line
+ if((position->x < left) || (backgroundColorIndex != prevBackgroundColorIndex))
+ {
+ left = position->x - glyphInfo->xBearing;
+ }
+
+ if(position->x + glyphInfo->width > right)
+ {
+ right = position->x - glyphInfo->xBearing + glyphInfo->advance;
+ }
+
+ prevBackgroundColorIndex = backgroundColorIndex;
+ }
+
+ //draw last background at line end if not default
+ if(backgroundColorIndex != 0u)
+ {
+ const Vector4& backgroundColor = *(backgroundColorsBuffer + backgroundColorIndex - 1u);
+ DrawBackgroundColor(backgroundColor, bufferWidth, bufferHeight, glyphData, baseline, line, left, right);
+ }
+
+ // Increases the vertical offset with the line's descender.
+ glyphData.verticalOffset += static_cast<int>(-line.descender);
+ }
+
+ return glyphData.bitmapBuffer;
+}
+
} // namespace
TypesetterPtr Typesetter::New(const ModelInterface* const model)
}
// Generate the background if enabled
- const bool backgroundEnabled = mModel->IsBackgroundEnabled();
- if(backgroundEnabled)
+ const bool backgroundEnabled = mModel->IsBackgroundEnabled();
+ const bool backgroundMarkupSet = mModel->IsMarkupBackgroundColorSet();
+ if(backgroundEnabled || backgroundMarkupSet)
{
- Devel::PixelBuffer backgroundImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_BACKGROUND, ignoreHorizontalAlignment, pixelFormat, penX, penY, 0u, numberOfGlyphs - 1);
+ Devel::PixelBuffer backgroundImageBuffer;
+
+ if(backgroundEnabled)
+ {
+ backgroundImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_BACKGROUND, ignoreHorizontalAlignment, pixelFormat, penX, penY, 0u, numberOfGlyphs - 1);
+ }
+ else
+ {
+ backgroundImageBuffer = Devel::PixelBuffer::New(bufferWidth, bufferHeight, pixelFormat);
+ }
+
+ if(backgroundMarkupSet)
+ {
+ DrawGlyphsBackground(mModel, backgroundImageBuffer, bufferWidth, bufferHeight, ignoreHorizontalAlignment, penX, penY);
+ }
// Combine the two buffers
imageBuffer = CombineImageBuffer(imageBuffer, backgroundImageBuffer, bufferWidth, bufferHeight);
return mModel->GetBackgroundColorIndices();
}
+bool const ViewModel::IsMarkupBackgroundColorSet() const
+{
+ return mModel->IsMarkupBackgroundColorSet();
+}
+
const Vector4& ViewModel::GetDefaultColor() const
{
return mModel->GetDefaultColor();
const ColorIndex* const GetBackgroundColorIndices() const override;
/**
+ * @copydoc ModelInterface::IsMarkupBackgroundColorSet()
+ */
+ bool const IsMarkupBackgroundColorSet() const override;
+
+ /**
* @copydoc ModelInterface::GetDefaultColor()
*/
const Vector4& GetDefaultColor() const override;
mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
mModel->mVisualModel->CreateCharacterToGlyphTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
- updated = true;
+ updated = true;
}
const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs;
}
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
logicalModel->mFontDescriptionRuns,
logicalModel->mEmbeddedItems,
logicalModel->mAnchors,
- logicalModel->mUnderlinedCharacterRuns);
+ logicalModel->mUnderlinedCharacterRuns,
+ logicalModel->mBackgroundColorRuns);
Length textSize = 0u;
const uint8_t* utf8 = NULL;
virtual const ColorIndex* const GetBackgroundColorIndices() const = 0;
/**
+ * @brief checks if there is background colors set using markup.
+ *
+ * @return boolean if there is background colors set using markup .
+ */
+ virtual bool const IsMarkupBackgroundColorSet() const = 0;
+
+ /**
* @brief Retrieves the text's default color.
*
* @return The default color.
return mVisualModel->mBackgroundColorIndices.Begin();
}
+bool const Model::IsMarkupBackgroundColorSet() const
+{
+ return (mVisualModel->mBackgroundColorIndices.Count() > 0);
+}
+
const Vector4& Model::GetDefaultColor() const
{
return mVisualModel->mTextColor;
const ColorIndex* const GetBackgroundColorIndices() const override;
/**
+ * @copydoc ModelInterface::IsMarkupBackgroundColorSet()
+ */
+ bool const IsMarkupBackgroundColorSet() const override;
+
+ /**
* @copydoc ModelInterface::GetDefaultColor()
*/
const Vector4& GetDefaultColor() const override;
virtual const ColorIndex* const GetBackgroundColorIndices() const = 0;
/**
+ * @brief checks if there is background colors set using markup.
+ *
+ * @return boolean if there is background colors set using markup .
+ */
+ virtual bool const IsMarkupBackgroundColorSet() const = 0;
+
+ /**
* @brief Retrieves the text color
*
* @return The text color
return nullptr;
}
+bool const View::IsMarkupBackgroundColorSet() const
+{
+ if(mImpl->mVisualModel)
+ {
+ return (mImpl->mVisualModel->mBackgroundColorIndices.Count() > 0);
+ }
+
+ return false;
+}
+
const Vector4& View::GetTextColor() const
{
if(mImpl->mVisualModel)
const ColorIndex* const GetBackgroundColorIndices() const override;
/**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::IsMarkupBackgroundColorSet()
+ */
+ bool const IsMarkupBackgroundColorSet() const;
+
+ /**
* @copydoc Dali::Toolkit::Text::ViewInterface::GetTextColor()
*/
const Vector4& GetTextColor() const override;