X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Frendering%2Fatlas%2Ftext-atlas-renderer.cpp;h=016284aac8a29a0399bff82cb8b879f8bc38e01e;hp=fda82f4c0498fc0f143d4510dd39b277ed320602;hb=52117490d94d8242addbe1608efe64364fdb308a;hpb=f5b98922d42457ef4e33c05dc1fb612fa24e888f diff --git a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp index fda82f4..016284a 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -19,6 +19,7 @@ #include // EXTERNAL INCLUDES +#include #include #include @@ -38,6 +39,10 @@ using namespace Dali::Toolkit::Text; namespace { + const float ZERO( 0.0f ); + const float HALF( 0.5f ); + const float ONE( 1.0f ); + const float TWO( 2.0f ); const Vector2 DEFAULT_ATLAS_SIZE( 512.0f, 512.0f ); const Vector2 DEFAULT_BLOCK_SIZE( 16.0f, 16.0f ); const Vector2 PADDING( 4.0f, 4.0f ); // Allow for variation in font glyphs @@ -102,19 +107,21 @@ struct AtlasRenderer::Impl : public ConnectionTracker const Vector4& textColor, const Vector2& shadowOffset, const Vector4& shadowColor, - float underlineEnabled, - const Vector4& underlineColor ) + bool underlineEnabled, + const Vector4& underlineColor, + float underlineHeight ) { AtlasManager::AtlasSlot slot; std::vector< MeshRecord > meshContainer; Vector< Extent > extents; - float currentUnderlinePosition = 0.0f; - float currentUnderlineThickness = 0.0f; + float currentUnderlinePosition = ZERO; + float currentUnderlineThickness = underlineHeight; + FontId lastFontId = 0; Style style = STYLE_NORMAL; - if ( shadowOffset.x != 0.0f || shadowOffset.y != 0.0f ) + if ( fabsf( shadowOffset.x ) > Math::MACHINE_EPSILON_1 || fabsf( shadowOffset.y ) > Math::MACHINE_EPSILON_1 ) { style = STYLE_DROP_SHADOW; } @@ -140,13 +147,33 @@ struct AtlasRenderer::Impl : public ConnectionTracker // We need to fetch fresh font underline metrics FontMetrics fontMetrics; mFontClient.GetFontMetrics( glyph.fontId, fontMetrics ); - currentUnderlinePosition = fontMetrics.underlinePosition; - currentUnderlineThickness = fontMetrics.underlineThickness; + currentUnderlinePosition = FontMetricsRoundUp( fabsf( fontMetrics.underlinePosition ) ); + float descender = FontMetricsRoundUp( fabsf( fontMetrics.descender ) ); - // Ensure that an underline is at least 1 pixel high - if ( currentUnderlineThickness < 1.0f ) + if ( underlineHeight == ZERO ) { - currentUnderlineThickness = 1.0f; + currentUnderlineThickness = fontMetrics.underlineThickness; + + // Ensure underline will be at least a pixel high + if ( currentUnderlineThickness < ONE ) + { + currentUnderlineThickness = ONE; + } + else + { + currentUnderlineThickness = FontMetricsRoundUp( currentUnderlineThickness ); + } + } + + // Clamp the underline position at the font descender and check for ( as EFL describes it ) a broken font + if ( currentUnderlinePosition > descender ) + { + currentUnderlinePosition = descender; + } + if ( ZERO == currentUnderlinePosition ) + { + // Move offset down by one ( EFL behavior ) + currentUnderlinePosition = ONE; } } @@ -173,7 +200,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_SIZE, mBlockSizes[ j ].mNeededBlockSize ); } } - lastFontId = glyph.fontId; } // Glyph doesn't currently exist in atlas so upload @@ -199,6 +225,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker currentUnderlineThickness, slot ); } + lastFontId = glyph.fontId; } if ( underlineEnabled ) @@ -289,14 +316,13 @@ struct AtlasRenderer::Impl : public ConnectionTracker uint32_t index = 0; for ( std::vector< MeshRecord >::iterator mIt = meshContainer.begin(); mIt != meshContainer.end(); ++mIt, ++index ) { - if ( slot.mAtlasId == mIt->mAtlasId ) + if ( slot.mAtlasId == mIt->mAtlasId && color == mIt->mColor ) { // Stitch the mesh to the existing mesh and adjust any extents mGlyphManager.StitchMesh( mIt->mMeshData, newMeshData ); AdjustExtents( extents, meshContainer, index, - color, left, right, baseLine, @@ -318,7 +344,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker AdjustExtents( extents, meshContainer, meshContainer.size() - 1u, - color, left, right, baseLine, @@ -331,7 +356,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker void AdjustExtents( Vector< Extent >& extents, std::vector< MeshRecord>& meshRecords, uint32_t index, - const Vector4& color, float left, float right, float baseLine, @@ -343,21 +367,17 @@ struct AtlasRenderer::Impl : public ConnectionTracker { if ( Equals( baseLine, eIt->mBaseLine ) ) { - // If we've found an extent with the same color then we don't need to create a new extent - if ( color == meshRecords[ index ].mColor ) + foundExtent = true; + if ( left < eIt->mLeft ) { - foundExtent = true; - if ( left < eIt->mLeft ) - { - eIt->mLeft = left; - } - if ( right > eIt->mRight ) - { - eIt->mRight = right; - } + eIt->mLeft = left; } - // Font metrics use negative values for lower underline positions - if ( underlinePosition < eIt->mUnderlinePosition ) + if ( right > eIt->mRight ) + { + eIt->mRight = right; + } + + if ( underlinePosition > eIt->mUnderlinePosition ) { eIt->mUnderlinePosition = underlinePosition; } @@ -431,15 +451,25 @@ struct AtlasRenderer::Impl : public ConnectionTracker } } + float FontMetricsRoundUp( float value ) + { + double integral_part; + if ( modf( value, &integral_part ) ) + { + return ( static_cast< float >( integral_part ) + 1.0f ); + } + else + { + return static_cast< float >( integral_part ); + } + } + void GenerateUnderlines( std::vector< MeshRecord>& meshRecords, Vector< Extent >& extents, const Vector4& underlineColor, const Vector4& textColor ) { MeshData newMeshData; - const float zero = 0.0f; - const float half = 0.5f; - for ( Vector< Extent >::ConstIterator eIt = extents.Begin(); eIt != extents.End(); ++eIt ) { MeshData::VertexContainer newVerts; @@ -448,28 +478,28 @@ struct AtlasRenderer::Impl : public ConnectionTracker Vector2 uv = mGlyphManager.GetAtlasSize( meshRecords[ index ].mAtlasId ); // Make sure we don't hit texture edge for single pixel texture ( filled pixel is in top left of every atlas ) - float u = half / uv.x; - float v = half / uv.y; + float u = HALF / uv.x; + float v = HALF / uv.y; float thickness = eIt->mUnderlineThickness; - float baseLine = eIt->mBaseLine - eIt->mUnderlinePosition - ( thickness * 0.5f ); + float baseLine = eIt->mBaseLine + eIt->mUnderlinePosition - ( thickness * HALF ); float tlx = eIt->mLeft; float brx = eIt->mRight; - newVerts.push_back( MeshData::Vertex( Vector3( tlx, baseLine, zero ), - Vector2( zero, zero ), - Vector3( zero, zero, zero ) ) ); + newVerts.push_back( MeshData::Vertex( Vector3( tlx, baseLine, ZERO ), + Vector2::ZERO, + Vector3::ZERO ) ); - newVerts.push_back( MeshData::Vertex( Vector3( brx, baseLine, zero ), - Vector2( u, zero ), - Vector3( zero, zero, zero ) ) ); + newVerts.push_back( MeshData::Vertex( Vector3( brx, baseLine, ZERO ), + Vector2( u, ZERO ), + Vector3::ZERO ) ); - newVerts.push_back( MeshData::Vertex( Vector3( tlx, baseLine + thickness, zero ), - Vector2( zero, v ), - Vector3( zero, zero, zero ) ) ); + newVerts.push_back( MeshData::Vertex( Vector3( tlx, baseLine + thickness, ZERO ), + Vector2( ZERO, v ), + Vector3::ZERO ) ); - newVerts.push_back( MeshData::Vertex( Vector3( brx, baseLine + thickness, zero ), + newVerts.push_back( MeshData::Vertex( Vector3( brx, baseLine + thickness, ZERO ), Vector2( u, v ), - Vector3( zero, zero, zero ) ) ); + Vector3::ZERO ) ); newMeshData.SetVertices( newVerts ); newMeshData.SetFaceIndices( mFace ); @@ -500,12 +530,10 @@ struct AtlasRenderer::Impl : public ConnectionTracker { // Scan vertex buffer to determine width and height of effect buffer needed MeshData::VertexContainer verts = meshRecord.mMeshData.GetVertices(); - const float one = 1.0f; - const float zero = 0.0f; float tlx = verts[ 0 ].x; float tly = verts[ 0 ].y; - float brx = zero; - float bry = zero; + float brx = ZERO; + float bry = ZERO; for ( uint32_t i = 0; i < verts.size(); ++i ) { @@ -529,8 +557,8 @@ struct AtlasRenderer::Impl : public ConnectionTracker float width = brx - tlx; float height = bry - tly; - float divWidth = 2.0f / width; - float divHeight = 2.0f / height; + float divWidth = TWO / width; + float divHeight = TWO / height; // Create a buffer to render to meshRecord.mBuffer = FrameBufferImage::New( width, height ); @@ -539,21 +567,21 @@ struct AtlasRenderer::Impl : public ConnectionTracker MeshData::VertexContainer vertices; MeshData::FaceIndices face; - vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, tly + shadowOffset.y, zero ), - Vector2( zero, zero ), - Vector3( zero, zero, zero ) ) ); + vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, tly + shadowOffset.y, ZERO ), + Vector2::ZERO, + Vector3::ZERO ) ); - vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, tly + shadowOffset.y, zero ), - Vector2( one, zero ), - Vector3( zero, zero, zero ) ) ); + vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, tly + shadowOffset.y, ZERO ), + Vector2( ONE, ZERO ), + Vector3::ZERO ) ); - vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, bry + shadowOffset.y, zero ), - Vector2( zero, one ), - Vector3( zero, zero, zero ) ) ); + vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, bry + shadowOffset.y, ZERO ), + Vector2( ZERO, ONE ), + Vector3::ZERO ) ); - vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, bry + shadowOffset.y, zero ), - Vector2( one, one ), - Vector3( zero, zero, zero ) ) ); + vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, bry + shadowOffset.y, ZERO ), + Vector2::ONE, + Vector3::ZERO ) ); MeshData meshData; Material newMaterial = Material::New("effect buffer"); @@ -578,8 +606,8 @@ struct AtlasRenderer::Impl : public ConnectionTracker for ( uint32_t i = 0; i < verts.size(); ++i ) { MeshData::Vertex vertex = verts[ i ]; - vertex.x = ( ( vertex.x - tlx ) * divWidth ) - one; - vertex.y = ( ( vertex.y - tly ) * divHeight ) - one; + vertex.x = ( ( vertex.x - tlx ) * divWidth ) - ONE; + vertex.y = ( ( vertex.y - tly ) * divHeight ) - ONE; newVerts.push_back( vertex ); } @@ -676,7 +704,8 @@ RenderableActor AtlasRenderer::Render( Text::ViewInterface& view ) view.GetShadowOffset(), view.GetShadowColor(), view.IsUnderlineEnabled(), - view.GetUnderlineColor() ); + view.GetUnderlineColor(), + view.GetUnderlineHeight() ); } return mImpl->mActor; }