-Actor Controller::Impl::CreateBackgroundActor()
-{
- // NOTE: Currently we only support background color for left-to-right text.
-
- Actor actor;
-
- Length numberOfGlyphs = mView.GetNumberOfGlyphs();
- if(numberOfGlyphs > 0u)
- {
- Vector<GlyphInfo> glyphs;
- glyphs.Resize(numberOfGlyphs);
-
- Vector<Vector2> positions;
- positions.Resize(numberOfGlyphs);
-
- // Get the line where the glyphs are laid-out.
- const LineRun* lineRun = mModel->mVisualModel->mLines.Begin();
- float alignmentOffset = lineRun->alignmentOffset;
- numberOfGlyphs = mView.GetGlyphs(glyphs.Begin(),
- positions.Begin(),
- alignmentOffset,
- 0u,
- numberOfGlyphs);
-
- glyphs.Resize(numberOfGlyphs);
- positions.Resize(numberOfGlyphs);
-
- const GlyphInfo* const glyphsBuffer = glyphs.Begin();
- const Vector2* const positionsBuffer = positions.Begin();
-
- BackgroundMesh mesh;
- mesh.mVertices.Reserve(4u * glyphs.Size());
- mesh.mIndices.Reserve(6u * glyphs.Size());
-
- const Vector2 textSize = mView.GetLayoutSize();
-
- const float offsetX = alignmentOffset + textSize.width * 0.5f;
- const float offsetY = textSize.height * 0.5f;
-
- const Vector4* const backgroundColorsBuffer = mView.GetBackgroundColors();
- const ColorIndex* const backgroundColorIndicesBuffer = mView.GetBackgroundColorIndices();
- const Vector4& defaultBackgroundColor = mModel->mVisualModel->IsBackgroundEnabled() ? mModel->mVisualModel->GetBackgroundColor() : Color::TRANSPARENT;
-
- 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 GlyphInfo& glyph = *(glyphsBuffer + i);
-
- // Get the background color of the character.
- // The color index zero is reserved for the default background color (i.e. Color::TRANSPARENT)
- 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)
- {
- const Vector2 position = *(positionsBuffer + i);
-
- if(i == 0u && glyphSize == 1u) // Only one glyph in the whole text
- {
- quad.x = position.x;
- quad.y = yLineOffset;
- quad.z = quad.x + std::max(glyph.advance, glyph.xBearing + glyph.width);
- quad.w = lineHeight;
- }
- else if((lineIndex != prevLineIndex) || (i == 0u)) // The first glyph in the line
- {
- quad.x = position.x;
- quad.y = yLineOffset;
- quad.z = quad.x - glyph.xBearing + glyph.advance;
- 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 = yLineOffset;
- quad.z = quad.x + std::max(glyph.advance, glyph.xBearing + glyph.width);
- quad.w = quad.y + lineHeight;
- }
- else // The glyph in the middle of the text
- {
- quad.x = position.x - glyph.xBearing;
- quad.y = yLineOffset;
- quad.z = quad.x + glyph.advance;
- quad.w = quad.y + lineHeight;
- }
-
- BackgroundVertex vertex;
-
- // Top left
- vertex.mPosition.x = quad.x - offsetX;
- vertex.mPosition.y = quad.y - offsetY;
- vertex.mColor = backgroundColor;
- mesh.mVertices.PushBack(vertex);
-
- // Top right
- vertex.mPosition.x = quad.z - offsetX;
- vertex.mPosition.y = quad.y - offsetY;
- vertex.mColor = backgroundColor;
- mesh.mVertices.PushBack(vertex);
-
- // Bottom left
- vertex.mPosition.x = quad.x - offsetX;
- vertex.mPosition.y = quad.w - offsetY;
- vertex.mColor = backgroundColor;
- mesh.mVertices.PushBack(vertex);
-
- // Bottom right
- vertex.mPosition.x = quad.z - offsetX;
- vertex.mPosition.y = quad.w - offsetY;
- vertex.mColor = backgroundColor;
- mesh.mVertices.PushBack(vertex);
-
- // Six indices in counter clockwise winding
- mesh.mIndices.PushBack(1u + 4 * numberOfQuads);
- mesh.mIndices.PushBack(0u + 4 * numberOfQuads);
- mesh.mIndices.PushBack(2u + 4 * numberOfQuads);
- mesh.mIndices.PushBack(2u + 4 * numberOfQuads);
- mesh.mIndices.PushBack(3u + 4 * numberOfQuads);
- mesh.mIndices.PushBack(1u + 4 * numberOfQuads);
-
- numberOfQuads++;
- }
-
- if(lineIndex != prevLineIndex)
- {
- prevLineIndex = lineIndex;
- }
- }
-
- // Only create the background actor if there are glyphs with background color
- if(mesh.mVertices.Count() > 0u)
- {
- Property::Map quadVertexFormat;
- quadVertexFormat["aPosition"] = Property::VECTOR2;
- quadVertexFormat["aColor"] = Property::VECTOR4;
-
- VertexBuffer quadVertices = VertexBuffer::New(quadVertexFormat);
- quadVertices.SetData(&mesh.mVertices[0], mesh.mVertices.Size());
-
- Geometry quadGeometry = Geometry::New();
- quadGeometry.AddVertexBuffer(quadVertices);
- quadGeometry.SetIndexBuffer(&mesh.mIndices[0], mesh.mIndices.Size());
-
- if(!mShaderBackground)
- {
- mShaderBackground = Shader::New(SHADER_TEXT_CONTROLLER_BACKGROUND_SHADER_VERT, SHADER_TEXT_CONTROLLER_BACKGROUND_SHADER_FRAG);
- }
-
- Dali::Renderer renderer = Dali::Renderer::New(quadGeometry, mShaderBackground);
- renderer.SetProperty(Dali::Renderer::Property::BLEND_MODE, BlendMode::ON);
- renderer.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, DepthIndex::CONTENT);
-
- actor = Actor::New();
- actor.SetProperty(Dali::Actor::Property::NAME, "TextBackgroundColorActor");
- actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
- actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
- actor.SetProperty(Actor::Property::SIZE, textSize);
- actor.SetProperty(Actor::Property::COLOR_MODE, USE_OWN_MULTIPLY_PARENT_COLOR);
- actor.AddRenderer(renderer);
- }
- }
-
- return actor;
-}
-