" \"vertexPrefix\": \"\",\n"
" \"vertex\": \"void main(void)\\n{\\n gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);\\n vTexCoord = aTexCoord;\\n}\\n\\n\",\n"
" \"fragmentPrefix\": \"\",\n"
- " \"fragment\": \"precision mediump float;\\nuniform float uAmplitude; // 0.02; (< 1)\\nuniform float uTime;\\nvoid main()\\n{\\n highp vec2 textureSize = sTextureRect.zw - sTextureRect.xy;\\n highp vec2 pos = -1.0 + 2.0 * vTexCoord.st/textureSize;\\n highp float len = length(pos);\\n highp vec2 texCoord = vTexCoord.st/textureSize + pos/len * sin( len * 12.0 - uTime * 4.0 ) * uAmplitude; \\n gl_FragColor = texture2D(sTexture, texCoord) * uColor;\\n}\\n\\n\\n\",\n"
+ " \"fragment\": \"precision mediump float;\\nuniform float uAmplitude; // 0.02; (< 1)\\nuniform float uTime;\\nvoid main()\\n{\\n highp vec2 textureSize = uTextureRect.zw - uTextureRect.xy;\\n highp vec2 pos = -1.0 + 2.0 * vTexCoord.st/textureSize;\\n highp float len = length(pos);\\n highp vec2 texCoord = vTexCoord.st/textureSize + pos/len * sin( len * 12.0 - uTime * 4.0 ) * uAmplitude; \\n gl_FragColor = texture2D(sTexture, texCoord) * uColor;\\n}\\n\\n\\n\",\n"
" \"geometryType\": \"GEOMETRY_TYPE_IMAGE\"\n"
" },\n"
" \"geometryHints\": \"HINT_NONE\",\n"
" \"vertexPrefix\": \"\",\n"
" \"vertex\": \"void main(void)\\n{\\n gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);\\n vTexCoord = aTexCoord;\\n}\\n\\n\",\n"
" \"fragmentPrefix\": \"\",\n"
- " \"fragment\": \"precision mediump float;\\nuniform float uAmplitude; // 0.02; (< 1)\\nuniform float uTime;\\nvoid main()\\n{\\n highp vec2 textureSize = sTextureRect.zw - sTextureRect.xy;\\n highp vec2 pos = -1.0 + 2.0 * vTexCoord.st/textureSize;\\n highp float len = length(pos);\\n highp vec2 texCoord = vTexCoord.st/textureSize + pos/len * sin( len * 12.0 - uTime * 4.0 ) * uAmplitude; \\n gl_FragColor = texture2D(sTexture, texCoord) * uColor;\\n}\\n\\n\\n\",\n"
+ " \"fragment\": \"precision mediump float;\\nuniform float uAmplitude; // 0.02; (< 1)\\nuniform float uTime;\\nvoid main()\\n{\\n highp vec2 textureSize = uTextureRect.zw - uTextureRect.xy;\\n highp vec2 pos = -1.0 + 2.0 * vTexCoord.st/textureSize;\\n highp float len = length(pos);\\n highp vec2 texCoord = vTexCoord.st/textureSize + pos/len * sin( len * 12.0 - uTime * 4.0 ) * uAmplitude; \\n gl_FragColor = texture2D(sTexture, texCoord) * uColor;\\n}\\n\\n\\n\",\n"
" \"geometryType\": \"GEOMETRY_TYPE_IMAGE\"\n"
" },\n"
" \"geometryHints\": \"HINT_NONE\",\n"
" \"vertexPrefix\": \"\",\n"
" \"vertex\": \"void main(void)\\n{\\n gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);\\n vTexCoord = aTexCoord;\\n}\\n\\n\",\n"
" \"fragmentPrefix\": \"\",\n"
- " \"fragment\": \"precision mediump float;\\nuniform float uAmplitude; // 0.02; (< 1)\\nuniform float uTime;\\nvoid main()\\n{\\n highp vec2 textureSize = sTextureRect.zw - sTextureRect.xy;\\n highp vec2 pos = -1.0 + 2.0 * vTexCoord.st/textureSize;\\n highp float len = length(pos);\\n highp vec2 texCoord = vTexCoord.st/textureSize + pos/len * sin( len * 12.0 - uTime * 4.0 ) * uAmplitude; \\n gl_FragColor = texture2D(sTexture, texCoord) * uColor;\\n}\\n\\n\\n\",\n"
+ " \"fragment\": \"precision mediump float;\\nuniform float uAmplitude; // 0.02; (< 1)\\nuniform float uTime;\\nvoid main()\\n{\\n highp vec2 textureSize = uTextureRect.zw - uTextureRect.xy;\\n highp vec2 pos = -1.0 + 2.0 * vTexCoord.st/textureSize;\\n highp float len = length(pos);\\n highp vec2 texCoord = vTexCoord.st/textureSize + pos/len * sin( len * 12.0 - uTime * 4.0 ) * uAmplitude; \\n gl_FragColor = texture2D(sTexture, texCoord) * uColor;\\n}\\n\\n\\n\",\n"
" \"geometryType\": \"GEOMETRY_TYPE_IMAGE\"\n"
" },\n"
" \"geometryHints\": \"HINT_NONE\",\n"
" \"vertexPrefix\": \"\",\n"
" \"vertex\": \"void main(void)\\n{\\n gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);\\n vTexCoord = aTexCoord;\\n}\\n\\n\",\n"
" \"fragmentPrefix\": \"\",\n"
- " \"fragment\": \"precision mediump float;\\nuniform float uAmplitude; // 0.02; (< 1)\\nuniform float uTime;\\nvoid main()\\n{\\n highp vec2 textureSize = sTextureRect.zw - sTextureRect.xy;\\n highp vec2 pos = -1.0 + 2.0 * vTexCoord.st/textureSize;\\n highp float len = length(pos);\\n highp vec2 texCoord = vTexCoord.st/textureSize + pos/len * sin( len * 12.0 - uTime * 4.0 ) * uAmplitude; \\n gl_FragColor = texture2D(sTexture, texCoord) * uColor;\\n}\\n\\n\\n\",\n"
+ " \"fragment\": \"precision mediump float;\\nuniform float uAmplitude; // 0.02; (< 1)\\nuniform float uTime;\\nvoid main()\\n{\\n highp vec2 textureSize = uTextureRect.zw - uTextureRect.xy;\\n highp vec2 pos = -1.0 + 2.0 * vTexCoord.st/textureSize;\\n highp float len = length(pos);\\n highp vec2 texCoord = vTexCoord.st/textureSize + pos/len * sin( len * 12.0 - uTime * 4.0 ) * uAmplitude; \\n gl_FragColor = texture2D(sTexture, texCoord) * uColor;\\n}\\n\\n\\n\",\n"
" \"geometryType\": \"GEOMETRY_TYPE_IMAGE\"\n"
" },\n"
" \"geometryHints\": \"HINT_NONE\",\n"
"void main()\n"
"{\n"
" mediump float lighting = 0.25;\n"
- " mediump vec4 position = uModelView * vec4(aPosition,1.0);\n"
+ " mediump vec4 position = uModelView * vec4(aPosition*uSize.xy, 0.0, 1.0);\n"
"\n"
" mediump vec2 d = position.xy - uCenter;\n"
" mediump float dist = max( 0.0, dot(d,uDirection) );\n"
"\n"
"vShade = 1.0 - abs(sn) * lighting;\n"
"\n"
- "vTexCoord = aTexCoord;\n"
+ "vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5) );\n;\n"
"}" );
std::string fragmentShader(
"\n"
"void main()\n"
"{\n"
- " mediump vec4 world = uModelView * vec4(aPosition,1.0);\n"
+ " mediump vec4 world = uModelView * vec4(aPosition*uSize.xy, 0.0, 1.0);\n"
" mediump vec2 d = (world.xy - uCenter) * uAnglePerUnit;\n"
" mediump float a = length(d);\n"
" mediump float cs = cos(radians(a));\n"
" world.z -= cs * uRadius;\n"
" gl_Position = uProjection * world;\n"
" \n"
- " vTexCoord = aTexCoord;\n"
+ " vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5) );\n;\n"
"}\n");
ShaderEffect shaderEffect = ShaderEffect::New(
"varying float vPercentage;\n"
"void main()\n"
"{\n"
- " vec4 position = uModelView * vec4( aPosition, 1.0 );\n"
+ " vec4 position = uModelView * vec4( aPosition*uSize.xy, 0.0, 1.0 );\n"
" float percentage = 0.0;\n"
" for( int i=0; i<NUMBER_OF_DIMPLE; ++i )\n"
" {\n"
" }\n"
" vPercentage = clamp( percentage, 0.0, 1.0 );\n"
" gl_Position = uProjection * position;\n"
- " vTexCoord = aTexCoord;\n"
+ " vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5) );\n;\n"
"}\n");
vertexShaderStringStream << vertexShader;
" position.xyz *= uSize;\n"
" gl_Position = uMvpMatrix * position;\n"
// The line below is doing the same as the following commented lines:
- //" vec2 imageSize = sTextureRect.zw - sTextureRect.xy;\n"
- //" vec2 topLeft = sTextureRect.xy + uTopLeft * imageSize;\n"
- //" vec2 bottomRight = sTextureRect.xy + uBottomRight * imageSize;\n"
- //" vec2 texCoord = (aTexCoord - sTextureRect.xy) / imageSize;\n"
+ //" vec2 imageSize = uTextureRect.zw - uTextureRect.xy;\n"
+ //" vec2 topLeft = uTextureRect.xy + uTopLeft * imageSize;\n"
+ //" vec2 bottomRight = uTextureRect.xy + uBottomRight * imageSize;\n"
+ //" vec2 texCoord = (aTexCoord - uTextureRect.xy) / imageSize;\n"
//" vTexCoord = topLeft + texCoord * ( bottomRight - topLeft );\n"
" vec2 texCoord = aPosition + vec2(0.5);\n"
"\n"
"void main()\n"
"{\n"
- " mediump vec4 world = uModelView * vec4(aPosition,1.0);\n"
+ " mediump vec4 world = uModelView * vec4(aPosition*uSize.xy, 0.0, 1.0);\n"
" gl_Position = uProjection * world;\n"
" \n"
- " vTexCoord = aTexCoord;\n"
- " vRelativePosition = aTexCoord - uCenter;\n"
+ " vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5) );;\n"
+ " vRelativePosition = vTexCoord - uCenter;\n"
"}\n");
std::string fragmentShader(
std::string vertexShader(
"void main() \n"
"{ \n"
- " mediump vec3 pos = aPosition; \n"
+ " mediump vec3 pos = vec3(aPosition, 0.0)*uSize; \n"
" pos.y = pos.y * 3.0; \n"
" mediump vec4 world = uModelView * vec4(pos,1.0); \n"
" gl_Position = uProjection * world; \n"
- " vTexCoord = aTexCoord; \n"
+ " vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5) ); \n"
"} \n" );
std::string fragmentShader(
"{\n"
"float lighting = uAmplitude * 0.02;\n"
"float waveLength = uAmplitude * 0.0016;\n"
- "vec4 world = uModelView * vec4(aPosition,1.0);\n"
+ "vec4 world = uModelView * vec4(aPosition*uSize.xy, 0.0, 1.0);\n"
"vec2 d = vec2(world.x - uCenter.x, world.y - uCenter.y);\n"
"float dist = length(d);\n"
"float amplitude = cos(uTime - dist*waveLength);\n"
"}\n"
"vShade = 1.0 - (dot * slope);\n"
"vLight = max(0.0, dot * -slope);\n"
- "vTexCoord = aTexCoord;\n"
+ "vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5) );\n;\n"
"}" );
// append the default version
"uniform float uTime;\n"
"void main()\n"
"{\n"
- " highp vec2 textureSize = sTextureRect.zw - sTextureRect.xy;\n"
+ " highp vec2 textureSize = uTextureRect.zw - uTextureRect.xy;\n"
" highp vec2 pos = -1.0 + 2.0 * vTexCoord.st/textureSize;\n"
" highp float len = length(pos);\n"
" highp vec2 texCoord = vTexCoord.st/textureSize + pos/len * sin( len * 12.0 - uTime * 4.0 ) * uAmplitude;\n"
"\n"
"void main()\n"
"{\n"
- "mediump vec4 world = uModelView * vec4(aPosition,1.0);\n"
+ "mediump vec4 world = uModelView * vec4(aPosition*uSize.xy, 0.0, 1.0);\n"
"\n"
"world.x = world.x + tan(radians(uAngleXAxis)) * (world.y - uCenter.y * world.w);\n"
"world.y = world.y + tan(radians(uAngleYAxis)) * (world.x - uCenter.x * world.w);\n"
"\n"
"gl_Position = uProjection * world;\n"
"\n"
- "vTexCoord = aTexCoord;\n"
+ "vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5) );\n;\n"
"}" );
// Create the implementation, temporarily owned on stack,
"void main()\n"
"{\n"
- " vTexCoord = aTexCoord;\n"
+ " vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5) );\n;\n"
// Get the rect coords of the effect region in -1..1 range, i.e. circle centred around the center of the rect
// Done in the vertex shader itself to make use of gl interpolation for varying.
" vCentredCoord = vec2( ( (vTexCoord.x - uEffectRegion.x)/(uEffectRegion.z - uEffectRegion.x) * 2.0 - 1.0 ), ( (vTexCoord.y - uEffectRegion.y)/(uEffectRegion.w - uEffectRegion.y) * 2.0 - 1.0 ) );\n"
- " gl_Position = uMvpMatrix * vec4(aPosition, 1.0);\n"
+ " gl_Position = uMvpMatrix * vec4(aPosition*uSize.xy, 0.0, 1.0);\n"
"}\n";
std::string fragmentSourceFixed;
"\n"
"void main()\n"
"{\n"
- " mediump vec4 world = vec4(aPosition, 1.0);\n"
+ " mediump vec4 world = vec4(aPosition*uSize.xy, 0.0, 1.0);\n"
" \n"
" mediump vec2 d = vec2(world.xy - uCenter);\n"
" mediump float dist = length(d);\n"
" vRange = max(0.1, range);\n"
" \n"
" gl_Position = uMvpMatrix * world;\n"
- " vTexCoord = aTexCoord;\n"
+ " vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5) );\n;\n"
"}");
std::string fragmentShader(
"uniform mediump vec2 uCenter;\n"
"void main()\n"
"{\n"
- " highp vec2 textureCenter = (sTextureRect.xy + sTextureRect.zw) * 0.5;\n"
+ " highp vec2 textureCenter = (uTextureRect.xy + uTextureRect.zw) * 0.5;\n"
" textureCenter = vTexCoord.st - textureCenter;\n"
" highp float distance = length(textureCenter);\n"
" if (distance >= uRadius)\n"
**/
inline ShaderEffect CreatePageTurnBookSpineEffect()
{
- std::string vertexSource = DALI_COMPOSE_SHADER(
- precision mediump float;\n
- void main()\n
- {\n
- gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);\n
- vTexCoord = aTexCoord;\n
- }\n);
-
// the simplified version of the fragment shader of page turn effect
std::string fragmentSource = DALI_COMPOSE_SHADER(
precision mediump float;\n
{\n
// flip the image horizontally by changing the x component of the texture coordinate
if( uIsBackImageVisible == 1.0 )\n
- gl_FragColor = texture2D( sTexture, vec2( sTextureRect.p+sTextureRect.s-vTexCoord.x, vTexCoord.y ) ) * uColor; \n
+ gl_FragColor = texture2D( sTexture, vec2( uTextureRect.p+uTextureRect.s-vTexCoord.x, vTexCoord.y ) ) * uColor; \n
else\n
gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
// display book spine, a stripe of shadowed texture
- float pixelPos = (vTexCoord.x-sTextureRect.s)*uPageWidth; \n
+ float pixelPos = (vTexCoord.x-uTextureRect.s)*uPageWidth; \n
if(pixelPos < uSpineShadowParameter.x) \n
{\n
float x = pixelPos - uSpineShadowParameter.x;\n
const Vector2 DEFAULT_SPINE_SHADOW_PARAMETER(50.0f, 20.0f);
- ShaderEffect shaderEffect = ShaderEffect::New( vertexSource, fragmentSource );
+ ShaderEffect shaderEffect = ShaderEffect::New( "", fragmentSource );
shaderEffect.SetUniform( "uIsBackImageVisible", -1.f );
shaderEffect.SetUniform( "uSpineShadowParameter", DEFAULT_SPINE_SHADOW_PARAMETER );
\n
void main()\n
{\n
- vec4 position = vec4( aPosition.xy, 0.0, 1.0);\n
+ vec4 position = vec4( aPosition*uSize.xy, 0.0, 1.0);\n
vec2 currentCenter = vec2( uCommonParameters[1][2], uCommonParameters[1][3]);\n
vec2 originalCenter = vec2( uCommonParameters[0][2], uCommonParameters[0][3]);\n
vec3 normal = vec3(0.0,0.0,1.0);\n
// change the coordinate origin from the top-left of the page to its center
position.xy -= uPageSize * 0.5; \n
}\n
- position.z += aPosition.z;\n
gl_Position = uMvpMatrix * position;\n
// varying parameters for fragment shader
- vTexCoord = aTexCoord;
+ vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5) );\n;
vNormal = uNormalMatrix*normal;\n
vPosition = uModelView * position;\n
}\n
float spineShadowCoef = 1.0; \n
// display page content
// display back image of the page, flip the texture
- if( dot(vPosition.xyz, normal) > 0.0 ) texel = texture2D( sTexture, vec2( sTextureRect.p+sTextureRect.s-vTexCoord.x, vTexCoord.y ) );\n
+ if( dot(vPosition.xyz, normal) > 0.0 ) texel = texture2D( sTexture, vec2( uTextureRect.p+uTextureRect.s-vTexCoord.x, vTexCoord.y ) );\n
// display front image of the page
else texel = texture2D( sTexture, vTexCoord );\n
// display book spine, a stripe of shadowed texture
- float pixelPos = (vTexCoord.x-sTextureRect.s)*uPageSize.x; \n
+ float pixelPos = (vTexCoord.x-uTextureRect.s)*uPageSize.x; \n
if(pixelPos < uSpineShadowParameter.x) \n
{\n
float x = pixelPos - uSpineShadowParameter.x;\n
const char* VERTEX_SHADER = MAKE_SHADER(
attribute mediump vec2 aPosition;
attribute mediump vec2 aTexCoord;
+attribute mediump vec4 aColor;
uniform mediump vec2 uOffset;
uniform mediump mat4 uMvpMatrix;
varying mediump vec2 vTexCoord;
+varying mediump vec4 vColor;
void main()
{
mediump vec4 position = vec4( aPosition.xy + uOffset, 0.0, 1.0 );
gl_Position = uMvpMatrix * position;
vTexCoord = aTexCoord;
+ vColor = aColor;
}
);
const char* FRAGMENT_SHADER_L8 = MAKE_SHADER(
-uniform lowp vec4 uColor;
uniform sampler2D sTexture;
varying mediump vec2 vTexCoord;
+varying mediump vec4 vColor;
void main()
{
mediump vec4 color = texture2D( sTexture, vTexCoord );
- gl_FragColor = vec4( uColor.rgb, uColor.a * color.r );
+ gl_FragColor = vec4( vColor.rgb, vColor.a * color.r );
}
);
{
Vector2 mPosition; ///< Vertex posiiton
Vector2 mTexCoords; ///< Vertex texture co-ordinates
+ Vector4 mColor; ///< Vertex color
};
struct Mesh2D
struct MeshRecord
{
MeshRecord()
- : mColor( Color::BLACK ),
- mAtlasId( 0 )
+ : mAtlasId( 0u )
{
}
- Vector4 mColor;
uint32_t mAtlasId;
AtlasManager::Mesh2D mMesh;
FrameBufferImage mBuffer;
mRight( 0.0f ),
mUnderlinePosition( 0.0f ),
mUnderlineThickness( 0.0f ),
- mMeshRecordIndex( 0 )
+ mMeshRecordIndex( 0u )
{
}
mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2;
mQuadVertexFormat[ "aTexCoord" ] = Property::VECTOR2;
+ mQuadVertexFormat[ "aColor" ] = Property::VECTOR4;
mQuadIndexFormat[ "indices" ] = Property::INTEGER;
}
void AddGlyphs( Text::ViewInterface& view,
const Vector<Vector2>& positions,
const Vector<GlyphInfo>& glyphs,
+ const Vector<Vector4>& colors,
int depth )
{
AtlasManager::AtlasSlot slot;
const Vector2& actorSize( view.GetControlSize() );
const Vector2 halfActorSize( actorSize * 0.5f );
- const Vector4& textColor( view.GetTextColor() );
const Vector2& shadowOffset( view.GetShadowOffset() );
const Vector4& shadowColor( view.GetShadowColor() );
const bool underlineEnabled( view.IsUnderlineEnabled() );
Vector< TextCacheEntry > newTextCache;
const GlyphInfo* const glyphsBuffer = glyphs.Begin();
const Vector2* const positionsBuffer = positions.Begin();
+ const Vector4* const colorsBuffer = colors.Begin();
for( uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i )
{
thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || underlineGlyph;
// No operation for white space
- if ( glyph.width && glyph.height )
+ if( glyph.width && glyph.height )
{
// Are we still using the same fontId as previous
- if ( underlineGlyph && ( glyph.fontId != lastUnderlinedFontId ) )
+ if( underlineGlyph && ( glyph.fontId != lastUnderlinedFontId ) )
{
// We need to fetch fresh font underline metrics
FontMetrics fontMetrics;
}
// Clamp the underline position at the font descender and check for ( as EFL describes it ) a broken font
- if ( currentUnderlinePosition > descender )
+ if( currentUnderlinePosition > descender )
{
currentUnderlinePosition = descender;
}
+
if( fabsf( currentUnderlinePosition ) < Math::MACHINE_EPSILON_1000 )
{
// Move offset down by one ( EFL behavior )
lastUnderlinedFontId = glyph.fontId;
} // underline
- if ( !mGlyphManager.IsCached( glyph.fontId, glyph.index, slot ) )
+ if( !mGlyphManager.IsCached( glyph.fontId, glyph.index, slot ) )
{
// Select correct size for new atlas if needed....?
- if ( lastFontId != glyph.fontId )
+ if( lastFontId != glyph.fontId )
{
- for ( uint32_t j = 0; j < mBlockSizes.size(); ++j )
+ uint32_t index = 0u;
+ for( std::vector<MaxBlockSize>::const_iterator it = mBlockSizes.begin(),
+ endIt = mBlockSizes.end();
+ it != endIt;
+ ++it, ++index )
{
- if ( mBlockSizes[ j ].mFontId == glyph.fontId )
+ const MaxBlockSize& blockSize = *it;
+ if( blockSize.mFontId == glyph.fontId )
{
- currentBlockSize = j;
+ currentBlockSize = index;
mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH,
DEFAULT_ATLAS_HEIGHT,
- mBlockSizes[ j ].mNeededBlockWidth,
- mBlockSizes[ j ].mNeededBlockHeight );
+ blockSize.mNeededBlockWidth,
+ blockSize.mNeededBlockHeight );
}
}
}
// Create a new image for the glyph
BufferImage bitmap = mFontClient.CreateBitmap( glyph.fontId, glyph.index );
- if ( bitmap )
+ if( bitmap )
{
+ MaxBlockSize& blockSize = mBlockSizes[currentBlockSize];
+
// Ensure that the next image will fit into the current block size
bool setSize = false;
- if ( bitmap.GetWidth() > mBlockSizes[ currentBlockSize ].mNeededBlockWidth )
+ if( bitmap.GetWidth() > blockSize.mNeededBlockWidth )
{
setSize = true;
- mBlockSizes[ currentBlockSize ].mNeededBlockWidth = bitmap.GetWidth();
+ blockSize.mNeededBlockWidth = bitmap.GetWidth();
}
- if ( bitmap.GetHeight() > mBlockSizes[ currentBlockSize ].mNeededBlockHeight )
+ if( bitmap.GetHeight() > blockSize.mNeededBlockHeight )
{
setSize = true;
- mBlockSizes[ currentBlockSize ].mNeededBlockHeight = bitmap.GetHeight();
+ blockSize.mNeededBlockHeight = bitmap.GetHeight();
}
- if ( setSize )
+ if( setSize )
{
mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH,
DEFAULT_ATLAS_HEIGHT,
- mBlockSizes[ currentBlockSize ].mNeededBlockWidth,
- mBlockSizes[ currentBlockSize ].mNeededBlockHeight );
+ blockSize.mNeededBlockWidth,
+ blockSize.mNeededBlockHeight );
}
// Locate a new slot for our glyph
}
// Move the origin (0,0) of the mesh to the center of the actor
- Vector2 position = *( positionsBuffer + i ) - halfActorSize;
+ const Vector2 position = *( positionsBuffer + i ) - halfActorSize;
// Generate mesh data for this quad, plugging in our supplied position
AtlasManager::Mesh2D newMesh;
textCacheEntry.mIndex = glyph.index;
newTextCache.PushBack( textCacheEntry );
+ AtlasManager::Vertex2D* verticesBuffer = newMesh.mVertices.Begin();
+
// Adjust the vertices if the fixed-size font should be down-scaled
if( glyph.scaleFactor > 0 )
{
- for( unsigned int i=0; i<newMesh.mVertices.Count(); ++i )
+ for( unsigned int index = 0u, size = newMesh.mVertices.Count();
+ index < size;
+ ++index )
{
- newMesh.mVertices[i].mPosition.x = position.x + ( ( newMesh.mVertices[i].mPosition.x - position.x ) * glyph.scaleFactor );
- newMesh.mVertices[i].mPosition.y = position.y + ( ( newMesh.mVertices[i].mPosition.y - position.y ) * glyph.scaleFactor );
+ AtlasManager::Vertex2D& vertex = *( verticesBuffer + index );
+
+ // Set the position of the vertex.
+ vertex.mPosition.x = position.x + ( ( vertex.mPosition.x - position.x ) * glyph.scaleFactor );
+ vertex.mPosition.y = position.y + ( ( vertex.mPosition.y - position.y ) * glyph.scaleFactor );
}
}
+ // Get the color of the character.
+ const Vector4& color = *( colorsBuffer + i );
+
+ for( unsigned int index = 0u, size = newMesh.mVertices.Count();
+ index < size;
+ ++index )
+ {
+ AtlasManager::Vertex2D& vertex = *( verticesBuffer + index );
+
+ // Set the color of the vertex.
+ vertex.mColor = color;
+ }
+
// Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
StitchTextMesh( meshContainer,
newMesh,
extents,
- textColor,
position.y + glyph.yBearing,
underlineGlyph,
currentUnderlinePosition,
if( thereAreUnderlinedGlyphs )
{
// Check to see if any of the text needs an underline
- GenerateUnderlines( meshContainer, extents, underlineColor, textColor );
+ GenerateUnderlines( meshContainer, extents, underlineColor );
}
// For each MeshData object, create a mesh actor and add to the renderable actor
- if ( meshContainer.size() )
+ if( !meshContainer.empty() )
{
- for ( std::vector< MeshRecord >::iterator mIt = meshContainer.begin(); mIt != meshContainer.end(); ++mIt )
+ for( std::vector< MeshRecord >::iterator it = meshContainer.begin(),
+ endIt = meshContainer.end();
+ it != endIt; ++it )
{
- Actor actor = CreateMeshActor( *mIt, actorSize );
+ MeshRecord& meshRecord = *it;
+
+ Actor actor = CreateMeshActor( meshRecord, actorSize );
// Create an effect if necessary
- if ( style == STYLE_DROP_SHADOW )
+ if( style == STYLE_DROP_SHADOW )
{
+ // Change the color of the vertices.
+ for( Vector<AtlasManager::Vertex2D>::Iterator vIt = meshRecord.mMesh.mVertices.Begin(),
+ vEndIt = meshRecord.mMesh.mVertices.End();
+ vIt != vEndIt;
+ ++vIt )
+ {
+ AtlasManager::Vertex2D& vertex = *vIt;
+
+ vertex.mColor = shadowColor;
+ }
+
// Create a container actor to act as a common parent for text and shadow, to avoid color inheritence issues.
Actor containerActor = Actor::New();
containerActor.SetParentOrigin( ParentOrigin::CENTER );
containerActor.SetSize( actorSize );
- Actor shadowActor = Actor::New();
+ Actor shadowActor = CreateMeshActor( meshRecord, actorSize );
#if defined(DEBUG_ENABLED)
shadowActor.SetName( "Text Shadow renderable actor" );
#endif
// Offset shadow in x and y
shadowActor.RegisterProperty("uOffset", shadowOffset );
- if ( actor.GetRendererCount() )
+ if( actor.GetRendererCount() )
{
- Dali::Renderer renderer( actor.GetRendererAt( 0 ) );
- Geometry geometry = renderer.GetGeometry();
- Material material = renderer.GetMaterial();
-
- Dali::Renderer shadowRenderer = Dali::Renderer::New( geometry, material );
- shadowRenderer.SetDepthIndex( renderer.GetDepthIndex() - 1 );
- shadowActor.AddRenderer( shadowRenderer );
+ Dali::Renderer renderer( shadowActor.GetRendererAt( 0 ) );
+ renderer.SetDepthIndex( renderer.GetDepthIndex() - 1 );
shadowActor.SetParentOrigin( ParentOrigin::CENTER );
shadowActor.SetSize( actorSize );
- shadowActor.SetColor( shadowColor );
containerActor.Add( shadowActor );
containerActor.Add( actor );
actor = containerActor;
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "%s\n", metrics.mVerboseGlyphCounts.c_str() );
- for ( uint32_t i = 0; i < metrics.mAtlasMetrics.mAtlasCount; ++i )
+ for( uint32_t i = 0; i < metrics.mAtlasMetrics.mAtlasCount; ++i )
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, " Atlas [%i] %sPixels: %s Size: %ix%i, BlockSize: %ix%i, BlocksUsed: %i/%i\n",
i + 1, i > 8 ? "" : " ",
void RemoveText()
{
- for ( Vector< TextCacheEntry >::Iterator oldTextIter = mTextCache.Begin(); oldTextIter != mTextCache.End(); ++oldTextIter )
+ for( Vector< TextCacheEntry >::Iterator oldTextIter = mTextCache.Begin(); oldTextIter != mTextCache.End(); ++oldTextIter )
{
mGlyphManager.AdjustReferenceCount( oldTextIter->mFontId, oldTextIter->mIndex, -1/*decrement*/ );
}
actor.AddRenderer( renderer );
actor.SetParentOrigin( ParentOrigin::CENTER ); // Keep all of the origins aligned
actor.SetSize( actorSize );
- actor.SetColor( meshRecord.mColor );
actor.RegisterProperty("uOffset", Vector2::ZERO );
return actor;
}
void StitchTextMesh( std::vector< MeshRecord >& meshContainer,
AtlasManager::Mesh2D& newMesh,
Vector< Extent >& extents,
- const Vector4& color,
float baseLine,
bool underlineGlyph,
float underlinePosition,
mIt != mEndIt;
++mIt, ++index )
{
- if ( slot.mAtlasId == mIt->mAtlasId && color == mIt->mColor )
+ if( slot.mAtlasId == mIt->mAtlasId )
{
// Append the mesh to the existing mesh and adjust any extents
Toolkit::Internal::AtlasMeshFactory::AppendMesh( mIt->mMesh, newMesh );
MeshRecord meshRecord;
meshRecord.mAtlasId = slot.mAtlasId;
meshRecord.mMesh = newMesh;
- meshRecord.mColor = color;
meshContainer.push_back( meshRecord );
if( underlineGlyph )
void CalculateBlocksSize( const Vector<GlyphInfo>& glyphs )
{
- MaxBlockSize maxBlockSize;
- for ( uint32_t i = 0; i < glyphs.Size(); ++i )
+ for( Vector<GlyphInfo>::ConstIterator glyphIt = glyphs.Begin(),
+ glyphEndIt = glyphs.End();
+ glyphIt != glyphEndIt;
+ ++glyphIt )
{
- FontId fontId = glyphs[ i ].fontId;
+ const FontId fontId = (*glyphIt).fontId;
bool foundFont = false;
- for ( uint32_t j = 0; j < mBlockSizes.size(); ++j )
+
+ for( std::vector< MaxBlockSize >::const_iterator blockIt = mBlockSizes.begin(),
+ blockEndIt = mBlockSizes.end();
+ blockIt != blockEndIt;
+ ++blockIt )
{
- if ( mBlockSizes[ j ].mFontId == fontId )
+ if( (*blockIt).mFontId == fontId )
{
foundFont = true;
+ break;
}
}
+
if ( !foundFont )
{
FontMetrics fontMetrics;
mFontClient.GetFontMetrics( fontId, fontMetrics );
+
+ MaxBlockSize maxBlockSize;
maxBlockSize.mNeededBlockWidth = static_cast< uint32_t >( fontMetrics.height );
- maxBlockSize.mNeededBlockHeight = static_cast< uint32_t >( fontMetrics.height );
+ maxBlockSize.mNeededBlockHeight = maxBlockSize.mNeededBlockWidth;
maxBlockSize.mFontId = fontId;
+
mBlockSizes.push_back( maxBlockSize );
}
}
void GenerateUnderlines( std::vector< MeshRecord >& meshRecords,
Vector< Extent >& extents,
- const Vector4& underlineColor,
- const Vector4& textColor )
+ const Vector4& underlineColor )
{
AtlasManager::Mesh2D newMesh;
unsigned short faceIndex = 0;
newMesh.mIndices.PushBack( faceIndex + 1u );
faceIndex += 4;
- if ( underlineColor == textColor )
- {
- Toolkit::Internal::AtlasMeshFactory::AppendMesh( meshRecords[ index ].mMesh, newMesh );
- }
- else
- {
- MeshRecord record;
- record.mMesh = newMesh;
- record.mAtlasId = meshRecords[ index ].mAtlasId;
- record.mColor = underlineColor;
- meshRecords.push_back( record );
- }
+ vert.mColor = underlineColor;
+
+ Toolkit::Internal::AtlasMeshFactory::AppendMesh( meshRecords[ index ].mMesh, newMesh );
}
}
Vector<Vector2> positions;
positions.Resize( numberOfGlyphs );
+ Vector<Vector4> colors;
+ colors.Resize( numberOfGlyphs, view.GetTextColor() );
+
numberOfGlyphs = view.GetGlyphs( glyphs.Begin(),
positions.Begin(),
+ colors.Begin(),
0u,
numberOfGlyphs );
+
glyphs.Resize( numberOfGlyphs );
positions.Resize( numberOfGlyphs );
+ colors.Resize( numberOfGlyphs );
mImpl->AddGlyphs( view,
positions,
glyphs,
+ colors,
depth );
- /* In the case where AddGlyphs does not create a renderable Actor for example when glyphs are all whitespace create a new Actor. */
- /* This renderable actor is used to position the text, other "decorations" can rely on there always being an Actor regardless of it is whitespace or regular text*/
+ /* In the case where AddGlyphs does not create a renderable Actor for example when glyphs are all whitespace create a new Actor. */
+ /* This renderable actor is used to position the text, other "decorations" can rely on there always being an Actor regardless of it is whitespace or regular text. */
if ( !mImpl->mActor )
{
mImpl->mActor = Actor::New();
}
}
-void Controller::Impl::RetrieveSelection( std::string& selectedText, bool deleteAfterRetreival )
+void Controller::Impl::RetrieveSelection( std::string& selectedText, bool deleteAfterRetrieval )
{
- if( mEventData->mLeftSelectionPosition == mEventData->mRightSelectionPosition )
+ if( mEventData->mLeftSelectionPosition == mEventData->mRightSelectionPosition )
{
// Nothing to select if handles are in the same place.
- selectedText="";
+ selectedText.clear();
return;
}
const bool handlesCrossed = mEventData->mLeftSelectionPosition > mEventData->mRightSelectionPosition;
//Get start and end position of selection
- uint32_t startOfSelectedText = handlesCrossed ? mEventData->mRightSelectionPosition : mEventData->mLeftSelectionPosition;
- uint32_t lengthOfSelectedText = ( handlesCrossed ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition ) - startOfSelectedText;
+ const CharacterIndex startOfSelectedText = handlesCrossed ? mEventData->mRightSelectionPosition : mEventData->mLeftSelectionPosition;
+ const Length lengthOfSelectedText = ( handlesCrossed ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition ) - startOfSelectedText;
// Validate the start and end selection points
- if( ( startOfSelectedText + lengthOfSelectedText ) <= mLogicalModel->mText.Count() )
+ if( ( startOfSelectedText + lengthOfSelectedText ) <= mLogicalModel->mText.Count() )
{
//Get text as a UTF8 string
Vector<Character>& utf32Characters = mLogicalModel->mText;
Utf32ToUtf8( &utf32Characters[startOfSelectedText], lengthOfSelectedText, selectedText );
- if ( deleteAfterRetreival ) // Only delete text if copied successfully
+ if( deleteAfterRetrieval ) // Only delete text if copied successfully
{
// Delete text between handles
Vector<Character>& currentText = mLogicalModel->mText;
ChangeState( EventData::EDITING );
}
-void Controller::Impl::GetTextFromClipboard( unsigned int itemIndex, std::string& retreivedString )
+void Controller::Impl::GetTextFromClipboard( unsigned int itemIndex, std::string& retrievedString )
{
if ( mClipboard )
{
- retreivedString = mClipboard.GetItem( itemIndex );
+ retrievedString = mClipboard.GetItem( itemIndex );
}
}
// Get the position of the first glyph.
const Vector2& position = *( positionsBuffer + firstLogicalGlyphIndex );
- // Whether the glyph can be split, like Latin ligatures fi, ff or Arabic ﻻ.
+ // Whether the glyph can be split, like Latin ligatures fi, ff or Arabic ﻻ.
const bool isInterglyphIndex = ( numberOfCharacters > numberOfGlyphs ) && HasLigatureMustBreak( script );
const Length numberOfBlocks = isInterglyphIndex ? numberOfCharacters : 1u;
const float glyphAdvance = glyphMetrics.advance / static_cast<float>( numberOfBlocks );
bool mUpdateRightSelectionPosition : 1; ///< True if the visual position of the right selection handle must be recalculated.
bool mScrollAfterUpdatePosition : 1; ///< Whether to scroll after the cursor position is updated.
bool mScrollAfterDelete : 1; ///< Whether to scroll after delete characters.
- bool mAllTextSelected : 1; ///< True if the selection handles are selecting all the text
+ bool mAllTextSelected : 1; ///< True if the selection handles are selecting all the text.
};
struct ModifyEvent
{
if( !mFontId )
{
- Dali::TextAbstraction::PointSize26Dot6 pointSize = mDefaultPointSize*64;
+ const PointSize26Dot6 pointSize = static_cast<PointSize26Dot6>( mDefaultPointSize * 64.f );
mFontId = fontClient.GetFontId( mFontDescription, pointSize );
}
mTextColor( Color::BLACK ),
mAlignmentOffset(),
mOperationsPending( NO_OPERATION ),
- mMaximumNumberOfCharacters( 50 ),
+ mMaximumNumberOfCharacters( 50u ),
mRecalculateNaturalSize( true ),
mUserDefinedFontFamily( false )
{
if( ModifyEvent::TEXT_REPLACED == type)
{
// Cancel previously queued inserts etc.
- mModifyEvents.clear();
+ mModifyEvents.Clear();
}
ModifyEvent event;
event.type = type;
- mModifyEvents.push_back( event );
+ mModifyEvents.PushBack( event );
// The event will be processed during relayout
RequestRelayout();
void OnSelectAllEvent();
- void RetrieveSelection( std::string& selectedText, bool deleteAfterRetreival );
+ void RetrieveSelection( std::string& selectedText, bool deleteAfterRetrieval );
void ShowClipboard();
void SendSelectionToClipboard( bool deleteAfterSending );
- void GetTextFromClipboard( unsigned int itemIndex, std::string& retreivedString );
+ void GetTextFromClipboard( unsigned int itemIndex, std::string& retrievedString );
void RepositionSelectionHandles();
void RepositionSelectionHandles( float visualX, float visualY );
View mView; ///< The view interface to the rendering back-end.
MetricsPtr mMetrics; ///< A wrapper around FontClient used to get metrics & potentially down-scaled Emoji metrics.
LayoutEngine mLayoutEngine; ///< The layout engine.
- std::vector<ModifyEvent> mModifyEvents; ///< Temporary stores the text set until the next relayout.
+ Vector<ModifyEvent> mModifyEvents; ///< Temporary stores the text set until the next relayout.
Vector4 mTextColor; ///< The regular text color
Vector2 mAlignmentOffset; ///< Vertical and horizontal offset of the whole text inside the control due to alignment.
OperationsMask mOperationsPending; ///< Operations pending to be done to layout the text.
void Controller::ProcessModifyEvents()
{
- std::vector<ModifyEvent>& events = mImpl->mModifyEvents;
+ Vector<ModifyEvent>& events = mImpl->mModifyEvents;
- for( unsigned int i=0; i<events.size(); ++i )
+ if( 0u == events.Count() )
{
- if( ModifyEvent::TEXT_REPLACED == events[i].type )
+ // Nothing to do.
+ return;
+ }
+
+ for( Vector<ModifyEvent>::ConstIterator it = events.Begin(),
+ endIt = events.End();
+ it != endIt;
+ ++it )
+ {
+ const ModifyEvent& event = *it;
+
+ if( ModifyEvent::TEXT_REPLACED == event.type )
{
// A (single) replace event should come first, otherwise we wasted time processing NOOP events
- DALI_ASSERT_DEBUG( 0 == i && "Unexpected TEXT_REPLACED event" );
+ DALI_ASSERT_DEBUG( it == events.Begin() && "Unexpected TEXT_REPLACED event" );
TextReplacedEvent();
}
- else if( ModifyEvent::TEXT_INSERTED == events[i].type )
+ else if( ModifyEvent::TEXT_INSERTED == event.type )
{
TextInsertedEvent();
}
- else if( ModifyEvent::TEXT_DELETED == events[i].type )
+ else if( ModifyEvent::TEXT_DELETED == event.type )
{
// Placeholder-text cannot be deleted
if( !mImpl->IsShowingPlaceholderText() )
}
}
- if( mImpl->mEventData &&
- 0 != events.size() )
+ if( mImpl->mEventData )
{
// When the text is being modified, delay cursor blinking
mImpl->mEventData->mDecorator->DelayCursorBlink();
}
// Discard temporary text
- events.clear();
+ events.Clear();
}
void Controller::ResetText()
Length maxSizeOfNewText = std::min ( ( mImpl->mMaximumNumberOfCharacters - numberOfCharactersInModel ), characterCount );
maxLengthReached = ( characterCount > maxSizeOfNewText );
- // Insert at current cursor position
+ // The cursor position.
CharacterIndex& cursorIndex = mImpl->mEventData->mPrimaryCursorPosition;
+ // Insert at current cursor position.
Vector<Character>& modifyText = mImpl->mLogicalModel->mText;
if( cursorIndex < numberOfCharactersInModel )
* @note The returned number of glyphs may be less than @p numberOfGlyphs if a line has ellipsis.
*
* @param[out] glyphs Pointer to a buffer where the glyphs are copied.
- * @param[out] glyphPositions Pointer to a buffer where the glyph positions are copied.
+ * @param[out] glyphPositions Pointer to a buffer where the glyph's positions are copied.
+ * @param[out] colors Pointer to a buffer where the glyph's colors are copied.
* @param[in] glyphIndex Index to the first glyph.
* @param[in] numberOfGlyphs Number of glyphs to be copied.
*
*/
virtual Length GetGlyphs( GlyphInfo* glyphs,
Vector2* glyphPositions,
+ Vector4* glyphColors,
GlyphIndex glyphIndex,
Length numberOfGlyphs ) const = 0;
Length View::GetGlyphs( GlyphInfo* glyphs,
Vector2* glyphPositions,
+ Vector4* glyphColors,
GlyphIndex glyphIndex,
Length numberOfGlyphs ) const
{
*/
virtual Length GetGlyphs( GlyphInfo* glyphs,
Vector2* glyphPositions,
+ Vector4* glyphColors,
GlyphIndex glyphIndex,
Length numberOfGlyphs ) const;
GlyphIndex glyphIndex,
Length numberOfGlyphs ) const;
- // Character <--> Glyph conversion
-
- /**
- * @brief Retrieves for each character the number of glyphs the character is shaped.
- *
- * @param[out] glyphsPerCharacter Pointer to a buffer where the number of glyphs for each character are copied.
- * @param[in] characterIndex Index to the first character.
- * @param[in] numberOfCharacters The number of characters.
- */
- void GetGlyphsPerCharacterMap( Length* glyphsPerCharacter,
- CharacterIndex characterIndex,
- Length numberOfCharacters ) const;
-
// Position interface
/**
{ "Raise", LayerApi::Raise, LAYER_API },
{ "Lower", LayerApi::Lower, LAYER_API },
{ "RaiseAbove", LayerApi::RaiseAbove, LAYER_API },
- { "RaiseBelow", LayerApi::LowerBelow, LAYER_API },
+ { "LowerBelow", LayerApi::LowerBelow, LAYER_API },
{ "RaiseToTop", LayerApi::RaiseToTop, LAYER_API },
- { "LowerToBottom", LayerApi::ToBottom, LAYER_API },
+ { "LowerToBottom", LayerApi::LowerToBottom, LAYER_API },
{ "MoveAbove", LayerApi::MoveAbove, LAYER_API },
{ "MoveBelow", LayerApi::MoveBelow, LAYER_API },
// ignore SetClipping, use layer.clippingEnable
* @for Layer
* @method lowerToBottom
*/
-void LayerApi::ToBottom( const v8::FunctionCallbackInfo<v8::Value>& args )
+void LayerApi::LowerToBottom( const v8::FunctionCallbackInfo<v8::Value>& args )
{
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope handleScope( isolate );
void RaiseAbove( const v8::FunctionCallbackInfo< v8::Value >& args );
void LowerBelow( const v8::FunctionCallbackInfo< v8::Value >& args );
void RaiseToTop( const v8::FunctionCallbackInfo< v8::Value >& args );
- void ToBottom( const v8::FunctionCallbackInfo< v8::Value >& args );
+ void LowerToBottom( const v8::FunctionCallbackInfo< v8::Value >& args );
void MoveBelow( const v8::FunctionCallbackInfo< v8::Value >& args );
void MoveAbove( const v8::FunctionCallbackInfo< v8::Value >& args );
void SetDepthTestDisabled( const v8::FunctionCallbackInfo< v8::Value >& args );