Dali::Toolkit::DevelText::BitmapFontDescription description;
Dali::Toolkit::DevelText::Glyph glyph;
glyph.url = "BitmapFontUrl";
- glyph.utf8 = "BitmapFontUrl";
+ glyph.utf8[0u] = 0u;
+ glyph.utf8[1u] = 0u;
+ glyph.utf8[2u] = 0u;
+ glyph.utf8[3u] = 0u;
glyph.ascender = 1.f;
glyph.descender = 1.f;
description.glyphs.push_back( glyph );
#include <dali-toolkit/internal/text/rendering/view-model.h>
#include <dali-toolkit/internal/text/text-controller.h>
#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
+#include <dali/devel-api/text-abstraction/bitmap-font.h>
+#include <dali-toolkit/devel-api/text/bitmap-font.h>
using namespace Dali;
using namespace Toolkit;
tet_result(TET_PASS);
END_TEST;
}
+
+int UtcDaliTextTypesetterBitmapFont(void)
+{
+ tet_infoline("UtcDaliTextTypesetterBitmapFont ");
+ ToolkitTestApplication application;
+
+ DevelText::BitmapFontDescription fontDescription;
+ fontDescription.name = "Digits";
+ fontDescription.underlinePosition = 0.f;
+ fontDescription.underlineThickness = 0.f;
+ fontDescription.isColorFont = true;
+
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0031.png", "0", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0032.png", "1", 34.f, 0.f } );
+
+ TextAbstraction::BitmapFont bitmapFont;
+ DevelText::CreateBitmapFont( fontDescription, bitmapFont );
+
+ TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+ fontClient.GetFontId( bitmapFont );
+
+ // Creates a text controller.
+ ControllerPtr controller = Controller::New();
+
+ // Configures the text controller similarly to the text-label.
+ ConfigureTextLabel( controller );
+
+ // Sets the text.
+ controller->SetMarkupProcessorEnabled( true );
+ controller->SetText( "<font family='Digits'><color 'value'='red'>0</color></font>" );
+
+ // Creates the text's model and relais-out the text.
+ const Size relayoutSize( 31.f, 34.f );
+ controller->Relayout( relayoutSize );
+
+ // Tests the rendering controller has been created.
+ TypesetterPtr renderingController = Typesetter::New( controller->GetTextModel() );
+ DALI_TEST_CHECK( renderingController );
+
+ controller->Relayout( relayoutSize );
+
+ // Renders the text and creates the final bitmap.
+ auto bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT );
+
+ DALI_TEST_EQUALS( 31u, bitmap.GetWidth(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 34u, bitmap.GetHeight(), TEST_LOCATION );
+
+ tet_result(TET_PASS);
+ END_TEST;
+}
#include <dali-toolkit/devel-api/controls/text-controls/text-label-devel.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-style-properties-devel.h>
#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
+#include <dali/devel-api/text-abstraction/bitmap-font.h>
+#include <dali-toolkit/devel-api/text/bitmap-font.h>
using namespace Dali;
using namespace Toolkit;
END_TEST;
}
+
+int UtcDaliToolkitTextLabelBitmapFont(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextLabelBitmapFont");
+
+ DevelText::BitmapFontDescription fontDescription;
+ fontDescription.name = "Digits";
+ fontDescription.underlinePosition = 0.f;
+ fontDescription.underlineThickness = 0.f;
+
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0030.png", ":", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0031.png", "0", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0032.png", "1", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0033.png", "2", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0034.png", "3", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0035.png", "4", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0036.png", "5", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0037.png", "6", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0038.png", "7", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0039.png", "8", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u003a.png", "9", 34.f, 0.f } );
+
+ TextAbstraction::BitmapFont bitmapFont;
+ DevelText::CreateBitmapFont( fontDescription, bitmapFont );
+
+ TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+ fontClient.GetFontId( bitmapFont );
+
+ TextLabel label = TextLabel::New();
+
+ label.SetProperty( TextLabel::Property::TEXT, "0123456789:" );
+ label.SetProperty( TextLabel::Property::FONT_FAMILY, "Digits" );
+
+ // The text has been laid out with the bitmap font if the natural size is the sum of all the width (322) and 34 height.
+ DALI_TEST_EQUALS( label.GetNaturalSize(), Vector3(322.f, 34.f, 0.f), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+ Stage::GetCurrent().Add( label );
+
+ application.SendNotification();
+ application.Render();
+
+ // The text has been rendered if the height of the text-label is the height of the line.
+ DALI_TEST_EQUALS( label.GetCurrentSize().height, 34.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+ END_TEST;
+}
#include <dali-toolkit/devel-api/text/bitmap-font.h>
// EXTERNAL INCLUDE
-#include <dali/public-api/common/dali-vector.h>
#include <dali/devel-api/text-abstraction/bitmap-font.h>
+#include <cstring>
// INTERNAL INCLUDE
#include <dali-toolkit/internal/text/character-set-conversion.h>
-#include <dali-toolkit/internal/text/text-definitions.h>
-
namespace Dali
{
namespace Toolkit
{
-using namespace Text;
+
namespace DevelText
{
Glyph::Glyph()
: url{},
- utf8{ 0u },
+ utf8{},
ascender{ 0.f },
descender{ 0.f }
{}
+Glyph::Glyph( const std::string& url, const std::string utf8Character, float ascender, float descender )
+: url{ url },
+ utf8{},
+ ascender{ ascender },
+ descender{ descender }
+{
+ DALI_ASSERT_DEBUG( utf8Character.size() <= 4u );
+
+ std::copy( utf8Character.begin(), utf8Character.end(), utf8 );
+}
+
Glyph::~Glyph()
{}
bitmapFont.name = description.name;
bitmapFont.underlinePosition = description.underlinePosition;
bitmapFont.underlineThickness = description.underlineThickness;
+ bitmapFont.isColorFont = description.isColorFont;
for( const auto& glyph : description.glyphs )
{
- // 1) Convert to utf32
- Vector<Character> utf32;
- utf32.Resize( glyph.utf8.size() );
-
- const uint32_t numberOfCharacters = ( glyph.utf8.size() == 0 ) ? 0 :
- Text::Utf8ToUtf32( reinterpret_cast<const uint8_t* const>( glyph.utf8.c_str() ),
- glyph.utf8.size(),
- &utf32[0u] );
- utf32.Resize( numberOfCharacters );
+ uint32_t c = 0u;
+ Text::Utf8ToUtf32( glyph.utf8, Text::GetUtf8Length( glyph.utf8[0u] ), &c );
- TextAbstraction::BitmapGlyph bitmapGlyph( glyph.url, utf32[0u], glyph.ascender, glyph.descender );
+ TextAbstraction::BitmapGlyph bitmapGlyph( glyph.url, c, glyph.ascender, glyph.descender );
bitmapFont.glyphs.push_back( std::move( bitmapGlyph ) );
}
Glyph();
/**
+ * @brief Constructor.
+ *
+ * Initialize the members with the given values.
+ *
+ * @param[in] url The url of the bitmap for that glyph.
+ * @param[in] utf8 The utf8 codification of the glyph.
+ * @param[in] ascender The ascender of the glyph.
+ * @param[in] descender The descender of the glyph.
+ */
+ Glyph( const std::string& url, const std::string utf8, float ascender, float descender );
+
+ /**
* @brief Default destructor.
*/
~Glyph();
- std::string url; ///< The url of the glyph.
- std::string utf8; ///< the glyph encoded in utf8
- float ascender; ///< The ascender. The distance from the base line to the top of the glyph.
- float descender; ///< The descender. The distance from the base line to the bottom of the glyph.
+ std::string url; ///< The url of the glyph.
+ uint8_t utf8[4]; ///< the glyph encoded in utf8
+ float ascender; ///< The ascender. The distance from the base line to the top of the glyph.
+ float descender; ///< The descender. The distance from the base line to the bottom of the glyph.
};
/**
std::string name; ///< Name of the font.
float underlinePosition; ///< The position of the underline from the base line.
float underlineThickness; ///< The thickness of the underline.
+ bool isColorFont:1; ///< Whether the glyphs of this font have their own colors.
};
/**
if ( Pixel::RGBA8888 == pixelFormat )
{
// Whether the given glyph is a color one.
- const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format;
+ const bool isColorGlyph = data.glyphBitmap.isColorEmoji || data.glyphBitmap.isColorBitmap;
+ const uint32_t glyphPixelSize = Pixel::GetBytesPerPixel( data.glyphBitmap.format );
+ const uint32_t alphaIndex = glyphPixelSize - 1u;
+ const bool swapChannelsBR = Pixel::BGRA8888 == data.glyphBitmap.format;
// Pointer to the color glyph if there is one.
const uint32_t* const colorGlyphBuffer = isColorGlyph ? reinterpret_cast<uint32_t*>( data.glyphBitmap.buffer ) : NULL;
// Initial vertical offset.
const int yOffset = data.verticalOffset + position->y;
+ uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() );
+
// Traverse the pixels of the glyph line per line.
for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
{
continue;
}
- uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() );
-
if( isColorGlyph )
{
- // Retrieves the color from the color glyph. The format is BGRA8888.
+ // Retrieves the color from the color glyph.
uint32_t packedColorGlyph = *( colorGlyphBuffer + glyphBufferOffset + index );
uint8_t* packedColorGlyphBuffer = reinterpret_cast<uint8_t*>( &packedColorGlyph );
}
else
{
- uint8_t colorAlpha = static_cast<uint8_t>( color->a * static_cast<float>( *( packedColorGlyphBuffer + 3u ) ) );
+ const uint8_t colorAlpha = static_cast<uint8_t>( color->a * static_cast<float>( *( packedColorGlyphBuffer + 3u ) ) );
*( packedColorGlyphBuffer + 3u ) = colorAlpha;
if( Typesetter::STYLE_SHADOW == style )
}
else
{
- std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R.
+ if( swapChannelsBR )
+ {
+ std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R.
+ }
*( packedColorGlyphBuffer + 2u ) = ( *( packedColorGlyphBuffer + 2u ) * colorAlpha / 255 );
*( packedColorGlyphBuffer + 1u ) = ( *( packedColorGlyphBuffer + 1u ) * colorAlpha / 255 );
*packedColorGlyphBuffer = ( *( packedColorGlyphBuffer ) * colorAlpha / 255 );
+
+ if( data.glyphBitmap.isColorBitmap )
+ {
+ *( packedColorGlyphBuffer + 2u ) = static_cast<uint8_t>( *( packedColorGlyphBuffer + 2u ) * color->b );
+ *( packedColorGlyphBuffer + 1u ) = static_cast<uint8_t>( *( packedColorGlyphBuffer + 1u ) * color->g );
+ *packedColorGlyphBuffer = static_cast<uint8_t>( *packedColorGlyphBuffer * color->r );
+ }
}
}
uint8_t* packedColorBuffer = reinterpret_cast<uint8_t*>( &packedColor );
// Update the alpha channel.
- const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
+ const uint8_t alpha = *( data.glyphBitmap.buffer + glyphPixelSize * ( glyphBufferOffset + index ) + alphaIndex );
// Copy non-transparent pixels only
if ( alpha > 0u )
else
{
// Whether the given glyph is a color one.
- const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format;
+ const bool isColorGlyph = data.glyphBitmap.isColorEmoji || data.glyphBitmap.isColorBitmap;
+ const uint32_t glyphPixelSize = Pixel::GetBytesPerPixel( data.glyphBitmap.format );
+ const uint32_t alphaIndex = glyphPixelSize - 1u;
// Initial vertical offset.
const int yOffset = data.verticalOffset + position->y;
+ uint8_t* bitmapBuffer = reinterpret_cast< uint8_t* >( data.bitmapBuffer.GetBuffer() );
+
// Traverse the pixels of the glyph line per line.
for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
{
continue;
}
- uint8_t* bitmapBuffer = reinterpret_cast< uint8_t* >( data.bitmapBuffer.GetBuffer() );
-
if ( !isColorGlyph )
{
// Update the alpha channel.
- const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
+ const uint8_t alpha = *( data.glyphBitmap.buffer + glyphPixelSize * ( glyphBufferOffset + index ) + alphaIndex );
// Copy non-transparent pixels only
if ( alpha > 0u )
// 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, alpha );
+ currentAlpha = std::max( currentAlpha, alpha );
}
}
}