2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/text/rendering/vector-based/vector-based-renderer.h>
22 #include <dali/integration-api/debug.h>
23 #include <dali/devel-api/rendering/renderer.h>
24 #include <dali/devel-api/rendering/geometry.h>
25 #include <dali/devel-api/text-abstraction/font-client.h>
28 #include <dali-toolkit/internal/text/glyph-run.h>
29 #include <dali-toolkit/internal/text/text-view.h>
30 #include <dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-shader.h>
31 #include <dali-toolkit/internal/text/rendering/vector-based/vector-blob-atlas.h>
32 #include <dali-toolkit/internal/text/rendering/vector-based/vector-blob-atlas-share.h>
35 using namespace Dali::Toolkit;
36 using namespace Dali::Toolkit::Text;
41 #if defined(DEBUG_ENABLED)
42 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
45 const float DEFAULT_POINT_SIZE = 13.f;
55 void AddVertex( Vector<Vertex2D>& vertices, float x, float y, float u, float v )
62 vertices.PushBack( meshVertex );
65 void AddTriangle( Vector<unsigned int>& indices, unsigned int v0, unsigned int v1, unsigned int v2 )
67 indices.PushBack( v0 );
68 indices.PushBack( v1 );
69 indices.PushBack( v2 );
72 bool CreateGeometry( const Vector<GlyphInfo>& glyphs,
73 unsigned int numberOfGlyphs,
74 const Vector<Vector2>& positions,
77 VectorBlobAtlas& atlas,
78 Dali::TextAbstraction::FontClient& fontClient,
79 Vector< Vertex2D >& vertices,
80 Vector< unsigned int >& indices )
82 bool atlasFull( false );
84 for( unsigned int i=0, idx=0; i<numberOfGlyphs && !atlasFull; ++i )
86 if( glyphs[i].width > 0 &&
87 glyphs[i].height > 0 )
89 bool foundBlob( true );
91 BlobCoordinate blobCoords[4];
93 if( ! atlas.FindGlyph( glyphs[i].fontId, glyphs[i].index, blobCoords ) )
96 VectorBlob* blob( NULL );
97 unsigned int blobLength( 0 );
98 unsigned int nominalWidth( 0 );
99 unsigned int nominalHeight( 0 );
100 fontClient.CreateVectorBlob( glyphs[i].fontId, glyphs[i].index, blob, blobLength, nominalWidth, nominalHeight );
102 if( 0 != blobLength )
104 bool glyphAdded = atlas.AddGlyph( glyphs[i].fontId, glyphs[i].index, blob, blobLength, nominalWidth, nominalHeight, blobCoords );
106 foundBlob = glyphAdded;
107 atlasFull = !glyphAdded;
117 const float x1( xOffset + positions[i].x );
118 const float x2( xOffset + positions[i].x + glyphs[i].width );
119 const float y1( yOffset + positions[i].y );
120 const float y2( yOffset + positions[i].y + glyphs[i].height );
122 AddVertex( vertices, x1, y2, blobCoords[0].u, blobCoords[0].v );
123 AddVertex( vertices, x1, y1, blobCoords[1].u, blobCoords[1].v );
124 AddVertex( vertices, x2, y2, blobCoords[2].u, blobCoords[2].v );
125 AddTriangle( indices, idx, idx+1, idx+2 );
128 AddVertex( vertices, x1, y1, blobCoords[1].u, blobCoords[1].v );
129 AddVertex( vertices, x2, y2, blobCoords[2].u, blobCoords[2].v );
130 AddVertex( vertices, x2, y1, blobCoords[3].u, blobCoords[3].v );
131 AddTriangle( indices, idx, idx+1, idx+2 );
137 // If the atlas is still partially empty, all the glyphs were added
141 } // unnamed namespace
143 struct VectorBasedRenderer::Impl
147 mFontClient = TextAbstraction::FontClient::Get();
149 mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2;
150 mQuadVertexFormat[ "aTexCoord" ] = Property::VECTOR2;
151 mQuadIndexFormat[ "indices" ] = Property::INTEGER;
154 Actor mActor; ///< The actor parent which renders the text
156 TextAbstraction::FontClient mFontClient; ///> The font client used to supply glyph information
158 Property::Map mQuadVertexFormat; ///> Describes the vertex format for text
159 Property::Map mQuadIndexFormat; ///> Describes the index format for text
161 Shader mShaderEffect;
163 IntrusivePtr<VectorBlobAtlas> mAtlas;
166 Text::RendererPtr VectorBasedRenderer::New()
168 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Text::VectorBasedRenderer::New()\n" );
170 return Text::RendererPtr( new VectorBasedRenderer() );
173 Actor VectorBasedRenderer::Render( Text::ViewInterface& view, int /*depth*/ )
175 UnparentAndReset( mImpl->mActor );
177 mImpl->mActor = Actor::New();
178 mImpl->mActor.SetParentOrigin( ParentOrigin::CENTER );
179 mImpl->mActor.SetSize( view.GetControlSize() );
180 mImpl->mActor.SetColor( Color::BLACK );
181 #if defined(DEBUG_ENABLED)
182 mImpl->mActor.SetName( "Text renderable actor" );
185 Length numberOfGlyphs = view.GetNumberOfGlyphs();
187 if( numberOfGlyphs > 0u )
189 Vector<GlyphInfo> glyphs;
190 glyphs.Resize( numberOfGlyphs );
192 Vector<Vector2> positions;
193 positions.Resize( numberOfGlyphs );
195 Vector<Vector4> colors;
196 colors.Resize( numberOfGlyphs, view.GetTextColor() );
198 numberOfGlyphs = view.GetGlyphs( glyphs.Begin(),
203 glyphs.Resize( numberOfGlyphs );
204 positions.Resize( numberOfGlyphs );
206 Vector< Vertex2D > vertices;
207 Vector< unsigned int > indices;
209 const Vector2& controlSize = view.GetControlSize();
210 float xOffset = controlSize.width * -0.5f;
211 float yOffset = controlSize.height * -0.5f;
213 if( ! mImpl->mAtlas ||
214 mImpl->mAtlas->IsFull() )
216 VectorBlobAtlasShare atlasShare = VectorBlobAtlasShare::Get();
217 mImpl->mAtlas = atlasShare.GetCurrentAtlas();
220 // First try adding the glyphs to the previous shared atlas
221 bool allGlyphsAdded = CreateGeometry( glyphs, numberOfGlyphs, positions, xOffset, yOffset, *mImpl->mAtlas, mImpl->mFontClient, vertices, indices );
223 if( ! allGlyphsAdded )
225 // The current atlas is full, abandon it and use a new one
226 mImpl->mAtlas.Reset();
230 VectorBlobAtlasShare atlasShare = VectorBlobAtlasShare::Get();
231 mImpl->mAtlas = atlasShare.GetNewAtlas();
233 CreateGeometry( glyphs, numberOfGlyphs, positions, xOffset, yOffset, *mImpl->mAtlas, mImpl->mFontClient, vertices, indices );
234 // Return value ignored; using more than an entire new atlas is not supported
237 if( 0 != vertices.Count() )
239 PropertyBuffer quadVertices = PropertyBuffer::New( mImpl->mQuadVertexFormat );
240 PropertyBuffer quadIndices = PropertyBuffer::New( mImpl->mQuadIndexFormat );
242 quadVertices.SetData( &vertices[ 0 ], vertices.Size() );
243 quadIndices.SetData( &indices[ 0 ], indices.Size() );
245 Geometry quadGeometry = Geometry::New();
246 quadGeometry.AddVertexBuffer( quadVertices );
247 quadGeometry.SetIndexBuffer( quadIndices );
249 TextureSet texture = mImpl->mAtlas->GetTextureSet();
251 const Vector4 atlasInfo = mImpl->mAtlas->GetInfo();
252 mImpl->mShaderEffect = GlyphyShader::New( atlasInfo );
254 Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, mImpl->mShaderEffect );
255 renderer.SetTextures( texture );
256 mImpl->mActor.AddRenderer( renderer );
260 return mImpl->mActor;
263 VectorBasedRenderer::VectorBasedRenderer()
268 VectorBasedRenderer::~VectorBasedRenderer()