X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Frendering%2Ftext-typesetter.cpp;h=3184d4ac38dc9a10865a141e3773cf5c8c6ce5e7;hb=refs%2Fchanges%2F97%2F153897%2F12;hp=66bb797058df0432dfce0a5177bfc6e82c6fe966;hpb=58ae307297125b55c93c38a631a8745c6a7c51f1;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp old mode 100644 new mode 100755 index 66bb797..3184d4a --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -102,7 +102,7 @@ void TypesetGlyph( GlyphData& data, if( ( 0 > yOffsetIndex ) || ( yOffsetIndex > heightMinusOne ) ) { // Do not write out of bounds. - break; + continue; } const int verticalOffset = yOffsetIndex * data.width; @@ -114,7 +114,7 @@ void TypesetGlyph( GlyphData& data, if( ( 0 > xOffsetIndex ) || ( xOffsetIndex > widthMinusOne ) ) { // Don't write out of bounds. - break; + continue; } uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() ); @@ -138,7 +138,7 @@ void TypesetGlyph( GlyphData& data, } // Update the alpha channel. - if( Typesetter::STYLE_MASK == style ) + if( Typesetter::STYLE_MASK == style || Typesetter::STYLE_OUTLINE == style ) // Outline not shown for color glyph { // Create an alpha mask for color glyph. *( packedColorGlyphBuffer + 3u ) = 0u; @@ -181,6 +181,9 @@ void TypesetGlyph( GlyphData& data, } else { + // Whether the given glyph is a color one. + const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format; + // Initial vertical offset. const int yOffset = data.verticalOffset + position->y; @@ -191,7 +194,7 @@ void TypesetGlyph( GlyphData& data, if( ( 0 > yOffsetIndex ) || ( yOffsetIndex > heightMinusOne ) ) { // Do not write out of bounds. - break; + continue; } const int verticalOffset = yOffsetIndex * data.width; @@ -203,27 +206,29 @@ void TypesetGlyph( GlyphData& data, if( ( 0 > xOffsetIndex ) || ( xOffsetIndex > widthMinusOne ) ) { // Don't write out of bounds. - break; + continue; } uint8_t* bitmapBuffer = reinterpret_cast< uint8_t* >( data.bitmapBuffer.GetBuffer() ); - // Update the alpha channel. - const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index ); - - // Copy non-transparent pixels only - if ( alpha > 0u ) + if ( !isColorGlyph ) { - // Check alpha of overlapped pixels - uint8_t& currentAlpha = *( bitmapBuffer + verticalOffset + xOffsetIndex ); - uint8_t newAlpha = static_cast( color->a * static_cast( alpha ) ); -// printf("y: %d, x: %d: alpha: %u, currentAlpha: %u, newAlpha: %u, a: %u\n", yOffsetIndex, xOffsetIndex, alpha, currentAlpha, newAlpha, std::max( currentAlpha, newAlpha ) ); - - // For any pixel overlapped with the pixel in previous glyphs, make sure we don't - // overwrite a previous bigger alpha with a smaller alpha (in order to avoid - // semi-transparent gaps between joint glyphs with overlapped pixels, which could - // happen, for example, in the RTL text when we copy glyphs from right to left). - *( bitmapBuffer + verticalOffset + xOffsetIndex ) = std::max( currentAlpha, newAlpha ); + // Update the alpha channel. + const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index ); + + // Copy non-transparent pixels only + if ( alpha > 0u ) + { + // Check alpha of overlapped pixels + uint8_t& currentAlpha = *( bitmapBuffer + verticalOffset + xOffsetIndex ); + uint8_t newAlpha = static_cast( color->a * static_cast( alpha ) ); + + // For any pixel overlapped with the pixel in previous glyphs, make sure we don't + // overwrite a previous bigger alpha with a smaller alpha (in order to avoid + // semi-transparent gaps between joint glyphs with overlapped pixels, which could + // happen, for example, in the RTL text when we copy glyphs from right to left). + *( bitmapBuffer + verticalOffset + xOffsetIndex ) = std::max( currentAlpha, newAlpha ); + } } } } @@ -276,17 +281,17 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo switch( mModel->GetVerticalAlignment() ) { - case Layout::VERTICAL_ALIGN_TOP: + case VerticalAlignment::TOP: { // No offset to add. break; } - case Layout::VERTICAL_ALIGN_CENTER: + case VerticalAlignment::CENTER: { penY = static_cast( 0.5f * ( size.height - layoutSize.height ) ); break; } - case Layout::VERTICAL_ALIGN_BOTTOM: + case VerticalAlignment::BOTTOM: { penY = static_cast( size.height - layoutSize.height ); break; @@ -327,6 +332,18 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo if ( ( RENDER_NO_STYLES != behaviour ) && ( RENDER_MASK != behaviour ) ) { + + // Generate the outline if enabled + const float outlineWidth = mModel->GetOutlineWidth(); + if ( outlineWidth > Math::MACHINE_EPSILON_1 ) + { + // Create the image buffer for outline + Devel::PixelBuffer outlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_OUTLINE, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs -1 ); + + // Combine the two buffers + imageBuffer = CombineImageBuffer( imageBuffer, outlineImageBuffer, bufferWidth, bufferHeight ); + } + // @todo. Support shadow and underline for partial text later on. // Generate the shadow if enabled @@ -379,6 +396,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth glyphData.width = bufferWidth; glyphData.height = bufferHeight; glyphData.bitmapBuffer = Devel::PixelBuffer::New( bufferWidth, bufferHeight, pixelFormat ); + glyphData.horizontalOffset = 0; if ( Pixel::RGBA8888 == pixelFormat ) { @@ -405,14 +423,27 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth // Increases the vertical offset with the line's ascender. glyphData.verticalOffset += static_cast( line.ascender ); - if ( style == Typesetter::STYLE_SHADOW ) + // Retrieves the glyph's outline width + float outlineWidth = mModel->GetOutlineWidth(); + + if( style == Typesetter::STYLE_OUTLINE ) + { + glyphData.horizontalOffset -= outlineWidth; + if( lineIndex == 0u ) + { + // Only need to add the vertical outline offset for the first line + glyphData.verticalOffset -= outlineWidth; + } + } + else if ( style == Typesetter::STYLE_SHADOW ) { const Vector2& shadowOffset = mModel->GetShadowOffset(); - glyphData.horizontalOffset += shadowOffset.x; + glyphData.horizontalOffset += shadowOffset.x - outlineWidth; // if outline enabled then shadow should offset from outline + if ( lineIndex == 0u ) { - // Only need to add the vertical shadow offset for once - glyphData.verticalOffset += shadowOffset.y; + // Only need to add the vertical shadow offset for first line + glyphData.verticalOffset += shadowOffset.y - outlineWidth; } } @@ -532,6 +563,10 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth { color = &( mModel->GetShadowColor() ); } + else if ( style == Typesetter::STYLE_OUTLINE ) + { + color = &( mModel->GetOutlineColor() ); + } else { color = ( useDefaultColor || ( 0u == colorIndex ) ) ? &defaultColor : colorsBuffer + ( colorIndex - 1u ); @@ -541,9 +576,17 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth glyphData.glyphBitmap.buffer = NULL; glyphData.glyphBitmap.width = glyphInfo->width; // Desired width and height. glyphData.glyphBitmap.height = glyphInfo->height; + + if( style != Typesetter::STYLE_OUTLINE && style != Typesetter::STYLE_SHADOW ) + { + // Don't render outline for other styles + outlineWidth = 0.0f; + } + fontClient.CreateBitmap( glyphInfo->fontId, glyphInfo->index, - glyphData.glyphBitmap ); + glyphData.glyphBitmap, + outlineWidth ); // Sets the glyph's bitmap into the bitmap of the whole text. if( NULL != glyphData.glyphBitmap.buffer )