X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Fdevel-api%2Ftext%2Ftext-utils-devel.cpp;h=ccea7e016a137e1ff3ddca4e8858ce56862832f5;hb=763c96a171fb79c5ae983792434537c70ac231fb;hp=faa90c5f40330914752b19c0b2548ec8af16dee0;hpb=60adf82ffbedaf4f10b55cb5f5aac1cb7d514b16;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/devel-api/text/text-utils-devel.cpp b/dali-toolkit/devel-api/text/text-utils-devel.cpp index faa90c5..ccea7e0 100755 --- a/dali-toolkit/devel-api/text/text-utils-devel.cpp +++ b/dali-toolkit/devel-api/text/text-utils-devel.cpp @@ -32,14 +32,13 @@ #include #include #include -#include #include #include #include #include #include #include -#include +#include namespace Dali { @@ -105,6 +104,36 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( DevelText::CircularAlignment, CENTER ) DALI_ENUM_TO_STRING_WITH_SCOPE( DevelText::CircularAlignment, END ) DALI_ENUM_TO_STRING_TABLE_END( CIRCULAR_ALIGNMENT_TYPE ) +struct InternalDataModel +{ + InternalDataModel( FontClient& fontClient, + MetricsPtr metrics, + Text::ModelPtr textModel ) + : fontClient( fontClient ), + metrics( metrics ), + textModel( textModel ), + numberOfCharacters{ 0u }, + isTextMirrored{ false }, + numberOfGlyphs{ 0u } + { + layoutEngine.SetMetrics( metrics ); + } + + FontClient& fontClient; + MetricsPtr metrics; + Text::Layout::Engine layoutEngine; ///< The layout engine. + Text::ModelPtr textModel; ///< Pointer to the text's model. + Vector blendingMode; ///< How embedded items and bitmap font glyphs are blended with color text. + Vector isEmoji; ///< Whether the glyph is an emoji. + + Vector mirroredUtf32Characters; // The utf32Characters Characters but mirrored if there are RTL text. + + Length numberOfCharacters; // The number of characters (not glyphs!). + bool isTextMirrored ; // Whether the text has been mirrored. + + Length numberOfGlyphs; +}; + bool GetLayoutEnumeration(const Property::Value& propertyValue, DevelText::Layout::Type& layout) { return Scripting::GetEnumerationProperty(propertyValue, LAYOUT_TYPE_TABLE, LAYOUT_TYPE_TABLE_COUNT, layout); @@ -115,81 +144,38 @@ bool GetCircularAlignmentEnumeration(const Property::Value& propertyValue, Devel return Scripting::GetEnumerationProperty(propertyValue, CIRCULAR_ALIGNMENT_TYPE_TABLE, CIRCULAR_ALIGNMENT_TYPE_TABLE_COUNT, circularAlignment); } -Devel::PixelBuffer Render( const RendererParameters& textParameters, Vector& embeddedItemLayout ) -{ - if( textParameters.text.empty() ) - { - Dali::Devel::PixelBuffer pixelBuffer = Dali::Devel::PixelBuffer::New( textParameters.textWidth, - textParameters.textHeight, - Dali::Pixel::RGBA8888 ); - - const unsigned int bufferSize = textParameters.textWidth * textParameters.textHeight * Dali::Pixel::GetBytesPerPixel(Dali::Pixel::RGBA8888); - unsigned char* buffer = pixelBuffer.GetBuffer(); - memset(buffer, 0, bufferSize); - return pixelBuffer; - } +void ShapeTextPreprocess( const RendererParameters& textParameters, TextAbstraction::TextRenderer::Parameters& rendererParameters, InternalDataModel& internalDataModel ) +{ MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get(); - FontClient fontClient = FontClient::Get(); - MetricsPtr metrics; - Text::Layout::Engine layoutEngine; ///< The layout engine. - LogicalModelPtr logicalModel = LogicalModel::New(); ///< Pointer to the logical model. - VisualModelPtr visualModel = VisualModel::New(); ///< Pointer to the visual model. - Vector blendingMode; ///< How embedded items and bitmap font glyphs are blended with color text. - Vector isEmoji; ///< Whether the glyph is an emoji. - - // Use this to access FontClient i.e. to get down-scaled Emoji metrics. - metrics = Metrics::New( fontClient ); - layoutEngine.SetMetrics( metrics ); - - TextAbstraction::TextRenderer::Parameters rendererParameters( visualModel->mGlyphs, - visualModel->mGlyphPositions, - visualModel->mColors, - visualModel->mColorIndices, - blendingMode, - isEmoji ); + const uint8_t* utf8 = NULL; // pointer to the first character of the text (encoded in utf8) + Length textSize = 0u; // The length of the utf8 string. - rendererParameters.width = textParameters.textWidth; - rendererParameters.height = textParameters.textHeight; - rendererParameters.pixelFormat = TextAbstraction::TextRenderer::Parameters::RGBA8888; // @note: At the moment all textures are generated RGBA8888 + Length& numberOfCharacters = internalDataModel.numberOfCharacters; + Vector& mirroredUtf32Characters = internalDataModel.mirroredUtf32Characters; + Text::ModelPtr& textModel = internalDataModel.textModel; - Vector& utf32Characters = logicalModel->mText; // Characters encoded in utf32. - Vector mirroredUtf32Characters; // The utf32Characters Characters but mirrored if there are RTL text. - Vector& lineBreakInfo = logicalModel->mLineBreakInfo; // The line break info. - Vector& scripts = logicalModel->mScriptRuns; // Charactes's script. - Vector& fontDescriptionRuns = logicalModel->mFontDescriptionRuns; // Desired font descriptions. - Vector& validFonts = logicalModel->mFontRuns; // Validated fonts. - Vector& bidirectionalInfo = logicalModel->mBidirectionalParagraphInfo; // The bidirectional info per paragraph. - Vector& bidirectionalLineInfo = logicalModel->mBidirectionalLineInfo; // The bidirectional info per line. - Vector& directions = logicalModel->mCharacterDirections; // Character's directions. - Vector& colorRuns = logicalModel->mColorRuns; // colors of the text. - - Vector& glyphsToCharacters = visualModel->mGlyphsToCharacters; // Glyphs to character map. - Vector& charactersToGlyph = visualModel->mCharactersToGlyph; // Characters to glyphs map. - Vector& charactersPerGlyph = visualModel->mCharactersPerGlyph; // Number of characters per glyph. - Vector& glyphsPerCharacter = visualModel->mGlyphsPerCharacter; // The number of glyphs that are shaped. - Vector& lines = visualModel->mLines; // The laid out lines. - - Vector newParagraphGlyphs; // Glyphs for the new paragraph characters. + Vector& utf32Characters = textModel->mLogicalModel->mText; // Characters encoded in utf32. + Vector& lineBreakInfo = textModel->mLogicalModel->mLineBreakInfo; // The line break info. + Vector& scripts = textModel->mLogicalModel->mScriptRuns; // Charactes's script. + Vector& fontDescriptionRuns = textModel->mLogicalModel->mFontDescriptionRuns; // Desired font descriptions. + Vector& validFonts = textModel->mLogicalModel->mFontRuns; // Validated fonts. + Vector& bidirectionalInfo = textModel->mLogicalModel->mBidirectionalParagraphInfo; // The bidirectional info per paragraph. + Vector& directions = textModel->mLogicalModel->mCharacterDirections; // Character's directions. + Vector& colorRuns = textModel->mLogicalModel->mColorRuns; // colors of the text. // the default font's description. FontDescription defaultFontDescription; PointSize26Dot6 defaultPointSize = FontClient::DEFAULT_POINT_SIZE; - Length numberOfCharacters = 0u; // The number of characters (not glyphs!). - bool isTextMirrored = false; // Whether the text has been mirrored. - - const uint8_t* utf8 = NULL; // pointer to the first character of the text (encoded in utf8) - Length textSize = 0u; // The length of the utf8 string. - //////////////////////////////////////////////////////////////////////////////// // Process the markup string if the mark-up processor is enabled. //////////////////////////////////////////////////////////////////////////////// MarkupProcessData markupProcessData( colorRuns, - fontDescriptionRuns, - logicalModel->mEmbeddedItems ); + fontDescriptionRuns, + textModel->mLogicalModel->mEmbeddedItems ); if (textParameters.markupEnabled) { @@ -234,9 +220,9 @@ Devel::PixelBuffer Render( const RendererParameters& textParameters, Vector& embeddedItemLayout, InternalDataModel& internalDataModel ) +{ + Vector newParagraphGlyphs; // Glyphs for the new paragraph characters. + const Length numberOfCharacters = internalDataModel.numberOfCharacters; + const bool isTextMirrored = internalDataModel.isTextMirrored; + Text::ModelPtr& textModel = internalDataModel.textModel; + const Vector& mirroredUtf32Characters = internalDataModel.mirroredUtf32Characters; + FontClient& fontClient = internalDataModel.fontClient; + const Vector& utf32Characters = textModel->mLogicalModel->mText; // Characters encoded in utf32. + const Vector& lineBreakInfo = textModel->mLogicalModel->mLineBreakInfo; // The line break info. + const Vector& scripts = textModel->mLogicalModel->mScriptRuns; // Charactes's script. + const Vector& validFonts = textModel->mLogicalModel->mFontRuns; // Validated fonts. + + Vector& glyphsToCharacters = textModel->mVisualModel->mGlyphsToCharacters; // Glyphs to character map. + Vector& charactersPerGlyph = textModel->mVisualModel->mCharactersPerGlyph; // Number of characters per glyph. //////////////////////////////////////////////////////////////////////////////// // Retrieve the glyphs. Text shaping @@ -362,19 +365,19 @@ Devel::PixelBuffer Render( const RendererParameters& textParameters, VectorCreateGlyphsPerCharacterTable( 0u, 0u, numberOfCharacters ); - visualModel->CreateCharacterToGlyphTable( 0u, 0u, numberOfCharacters ); + textModel->mVisualModel->CreateGlyphsPerCharacterTable( 0u, 0u, numberOfCharacters ); + textModel->mVisualModel->CreateCharacterToGlyphTable( 0u, 0u, numberOfCharacters ); - const Length numberOfGlyphs = rendererParameters.glyphs.Count(); + internalDataModel.numberOfGlyphs = rendererParameters.glyphs.Count(); // Once the text has been shaped and the glyphs created it's possible to replace the font id of those glyphs // that represent an image or an item and create the embedded item layout info. // Note: the position of the embedded item can't be set until the text is laid-out. - embeddedItemLayout.Reserve( logicalModel->mEmbeddedItems.Count() ); - for( const auto& item : logicalModel->mEmbeddedItems ) + embeddedItemLayout.Reserve( textModel->mLogicalModel->mEmbeddedItems.Count() ); + for( const auto& item : textModel->mLogicalModel->mEmbeddedItems ) { // Get the glyph that matches with the character index. - const GlyphIndex glyphIndex = visualModel->mCharactersToGlyph[item.characterIndex]; + const GlyphIndex glyphIndex = textModel->mVisualModel->mCharactersToGlyph[item.characterIndex]; GlyphInfo& glyph = rendererParameters.glyphs[glyphIndex]; glyph.fontId = 0u; @@ -404,12 +407,18 @@ Devel::PixelBuffer Render( const RendererParameters& textParameters, Vector& blendingMode = internalDataModel.blendingMode; + + Vector& colorRuns = textModel->mLogicalModel->mColorRuns; // colors of the text. - metrics->GetGlyphMetrics( rendererParameters.glyphs.Begin(), numberOfGlyphs ); + Vector& charactersToGlyph = textModel->mVisualModel->mCharactersToGlyph; // Characters to glyphs map. + Vector& glyphsPerCharacter = textModel->mVisualModel->mGlyphsPerCharacter; // The number of glyphs that are shaped. //////////////////////////////////////////////////////////////////////////////// // Set the color runs in glyphs. @@ -420,24 +429,24 @@ Devel::PixelBuffer Render( const RendererParameters& textParameters, VectormColors, - visualModel->mColorIndices ); + internalDataModel.numberOfCharacters, + textModel->mVisualModel->mColors, + textModel->mVisualModel->mColorIndices ); // Insert the default color at the beginning of the vector. - visualModel->mColors.Insert( visualModel->mColors.Begin(),textParameters.textColor ); + textModel->mVisualModel->mColors.Insert( textModel->mVisualModel->mColors.Begin(),textParameters.textColor ); // Set how the embedded items are blended with text color. - blendingMode.Resize( numberOfGlyphs, textParameters.isTextColorSet ? ColorBlendingMode::MULTIPLY : ColorBlendingMode::NONE ); + blendingMode.Resize( internalDataModel.numberOfGlyphs, textParameters.isTextColorSet ? ColorBlendingMode::MULTIPLY : ColorBlendingMode::NONE ); if( !textParameters.isTextColorSet ) { // Traverse the color runs. for( const auto& run : colorRuns ) { - const GlyphIndex firstGlyph = visualModel->mCharactersToGlyph[run.characterRun.characterIndex]; + const GlyphIndex firstGlyph = textModel->mVisualModel->mCharactersToGlyph[run.characterRun.characterIndex]; const CharacterIndex lastCharacter = run.characterRun.characterIndex + run.characterRun.numberOfCharacters - 1u; - const GlyphIndex lastGlyphPlusOne = visualModel->mCharactersToGlyph[lastCharacter] + visualModel->mGlyphsPerCharacter[lastCharacter]; + const GlyphIndex lastGlyphPlusOne = textModel->mVisualModel->mCharactersToGlyph[lastCharacter] + textModel->mVisualModel->mGlyphsPerCharacter[lastCharacter]; for( GlyphIndex index = firstGlyph; index < lastGlyphPlusOne; ++index ) { @@ -447,12 +456,20 @@ Devel::PixelBuffer Render( const RendererParameters& textParameters, VectormEmbeddedItems ) + for( const auto& item : textModel->mLogicalModel->mEmbeddedItems ) { - const GlyphIndex glyphIndex = visualModel->mCharactersToGlyph[item.characterIndex]; + const GlyphIndex glyphIndex = textModel->mVisualModel->mCharactersToGlyph[item.characterIndex]; blendingMode[glyphIndex] = item.colorBlendingMode; } +} + +void SetEmojiVector( InternalDataModel& internalDataModel ) +{ + Vector& isEmoji = internalDataModel.isEmoji; + Text::ModelPtr& textModel = internalDataModel.textModel; + const Length numberOfGlyphs = internalDataModel.numberOfGlyphs; + const Vector& scripts = textModel->mLogicalModel->mScriptRuns; // Charactes's script. //////////////////////////////////////////////////////////////////////////////// // Set the isEmoji Vector //////////////////////////////////////////////////////////////////////////////// @@ -463,9 +480,9 @@ Devel::PixelBuffer Render( const RendererParameters& textParameters, VectormCharactersToGlyph[run.characterRun.characterIndex]; + const GlyphIndex firstGlyph = textModel->mVisualModel->mCharactersToGlyph[run.characterRun.characterIndex]; const CharacterIndex lastCharacter = run.characterRun.characterIndex + run.characterRun.numberOfCharacters - 1u; - const GlyphIndex lastGlyphPlusOne = visualModel->mCharactersToGlyph[lastCharacter] + visualModel->mGlyphsPerCharacter[lastCharacter]; + const GlyphIndex lastGlyphPlusOne = textModel->mVisualModel->mCharactersToGlyph[lastCharacter] + textModel->mVisualModel->mGlyphsPerCharacter[lastCharacter]; for( GlyphIndex index = firstGlyph; index < lastGlyphPlusOne; ++index ) { @@ -473,158 +490,21 @@ Devel::PixelBuffer Render( const RendererParameters& textParameters, Vector( maxAscenderDescender ); - - // Convert CircularAlignment to HorizontalAlignment. - if( isCircularTextLayout ) - { - switch( circularAlignment ) - { - case CircularAlignment::BEGIN: - { - horizontalCircularAlignment = Toolkit::HorizontalAlignment::BEGIN; - break; - } - case CircularAlignment::CENTER: - { - horizontalCircularAlignment = Toolkit::HorizontalAlignment::CENTER; - break; - } - case CircularAlignment::END: - { - horizontalCircularAlignment = Toolkit::HorizontalAlignment::END; - break; - } - } - } - - // Set the layout parameters. - Size textLayoutArea( static_cast( textParameters.textWidth ), - static_cast( textParameters.textHeight ) ); - - if( isCircularTextLayout ) - { - // In a circular layout, the length of the text area depends on the radius. - rendererParameters.radius = radius; - textLayoutArea.width = fabs( Radian( Degree( textParameters.incrementAngle ) ) * static_cast( rendererParameters.radius ) ); - } - - Text::Layout::Parameters layoutParameters( textLayoutArea, - textToShape.Begin(), - lineBreakInfo.Begin(), - nullptr, - ( 0u != directions.Count() ) ? directions.Begin() : nullptr, - rendererParameters.glyphs.Begin(), - glyphsToCharacters.Begin(), - charactersPerGlyph.Begin(), - charactersToGlyph.Begin(), - glyphsPerCharacter.Begin(), - numberOfGlyphs, - isCircularTextLayout ? horizontalCircularAlignment : horizontalAlignment, - LineWrap::WORD, - 0.f, - false, - false ); // Outline's width - - // Resize the vector of positions to have the same size than the vector of glyphs. - rendererParameters.positions.Resize( numberOfGlyphs ); - - // Whether the last character is a new paragraph character. - layoutParameters.isLastNewParagraph = TextAbstraction::IsNewParagraph( textToShape[numberOfCharacters - 1u] ); - - // The initial glyph and the number of glyphs to layout. - layoutParameters.startGlyphIndex = 0u; - layoutParameters.numberOfGlyphs = numberOfGlyphs; - layoutParameters.startLineIndex = 0u; - layoutParameters.estimatedNumberOfLines = 1u; - layoutParameters.interGlyphExtraAdvance = 0.f; - - // Update the visual model. - Size newLayoutSize; - bool isAutoScrollEnabled = false; - layoutEngine.LayoutText( layoutParameters, - rendererParameters.positions, - lines, - newLayoutSize, - textParameters.ellipsisEnabled, - isAutoScrollEnabled ); - //////////////////////////////////////////////////////////////////////////////// - // Reorder BiDirectional lines. - //////////////////////////////////////////////////////////////////////////////// +void Align( const RendererParameters& textParameters, TextAbstraction::TextRenderer::Parameters& rendererParameters, + Vector& embeddedItemLayout, InternalDataModel& internalDataModel, + Size& textLayoutArea, const Size& newLayoutSize, + const bool isCircularTextLayout, const bool isClockwise, + HorizontalAlignment::Type horizontalAlignment, VerticalAlignment::Type verticalAlignment, CircularAlignment::Type circularAlignment, + const unsigned int radius ) +{ + Text::Layout::Engine& layoutEngine = internalDataModel.layoutEngine; + Text::ModelPtr& textModel = internalDataModel.textModel; + const Length numberOfCharacters = internalDataModel.numberOfCharacters; - if( hasBidirectionalText ) - { - // Reorder the line. - bidirectionalLineInfo.Reserve( 1u ); - - ReorderLines( bidirectionalInfo, - 0u, - numberOfCharacters, - lines, - bidirectionalLineInfo ); - - // Set the bidirectional info per line into the layout parameters. - layoutParameters.lineBidirectionalInfoRunsBuffer = bidirectionalLineInfo.Begin(); - layoutParameters.numberOfBidirectionalInfoRuns = bidirectionalLineInfo.Count(); - - // Re-layout the text. Reorder those lines with right to left characters. - layoutEngine.ReLayoutRightToLeftLines( layoutParameters, - 0u, - numberOfCharacters, - rendererParameters.positions ); - } + Vector& lines = textModel->mVisualModel->mLines; // The laid out lines. //////////////////////////////////////////////////////////////////////////////// // Align the text. @@ -770,7 +650,7 @@ Devel::PixelBuffer Render( const RendererParameters& textParameters, Vector& embeddedItemLayout, Size& textLayoutArea, InternalDataModel& internalDataModel ) +{ + Text::ModelPtr& textModel = internalDataModel.textModel; + FontClient& fontClient = internalDataModel.fontClient; + + Vector& lines = textModel->mVisualModel->mLines; // The laid out lines. + Vector& isEmoji = internalDataModel.isEmoji; + //////////////////////////////////////////////////////////////////////////////// // Ellipsis the text. //////////////////////////////////////////////////////////////////////////////// @@ -1037,8 +926,150 @@ Devel::PixelBuffer Render( const RendererParameters& textParameters, Vector& embeddedItemLayout, InternalDataModel& internalDataModel ) +{ + //////////////////////////////////////////////////////////////////////////////// + // Layout the text. + //////////////////////////////////////////////////////////////////////////////// + Text::ModelPtr& textModel = internalDataModel.textModel; + Text::Layout::Engine& layoutEngine = internalDataModel.layoutEngine; + FontClient& fontClient = internalDataModel.fontClient; + const Length numberOfGlyphs = internalDataModel.numberOfGlyphs; + const bool isTextMirrored = internalDataModel.isTextMirrored; + const Vector& mirroredUtf32Characters = internalDataModel.mirroredUtf32Characters; + const Length numberOfCharacters = internalDataModel.numberOfCharacters; + + // Sets the alignment + HorizontalAlignment::Type horizontalAlignment = Toolkit::HorizontalAlignment::CENTER; + HorizontalAlignment::Type horizontalCircularAlignment = Toolkit::HorizontalAlignment::CENTER; + VerticalAlignment::Type verticalAlignment = VerticalAlignment::CENTER; + Layout::Type layout = Layout::SINGLELINE; + CircularAlignment::Type circularAlignment = CircularAlignment::BEGIN; + + Property::Value horizontalAlignmentStr( textParameters.horizontalAlignment ); + GetHorizontalAlignmentEnumeration( horizontalAlignmentStr, horizontalAlignment ); + horizontalCircularAlignment = horizontalAlignment; + + Property::Value verticalAlignmentStr( textParameters.verticalAlignment ); + GetVerticalAlignmentEnumeration( verticalAlignmentStr, verticalAlignment ); + + Property::Value layoutStr( textParameters.layout ); + GetLayoutEnumeration( layoutStr, layout ); + + Property::Value circularAlignmentStr( textParameters.circularAlignment ); + GetCircularAlignmentEnumeration( circularAlignmentStr, circularAlignment ); + + // Whether the layout is multi-line. + const Text::Layout::Engine::Type horizontalLayout = ( Layout::MULTILINE == layout ) ? Text::Layout::Engine::MULTI_LINE_BOX : Text::Layout::Engine::SINGLE_LINE_BOX; + layoutEngine.SetLayout( horizontalLayout ); // TODO: multi-line. + + + // Whether the layout is circular. + const bool isCircularTextLayout = (Layout::CIRCULAR == layout); + const bool isClockwise = isCircularTextLayout && ( 0.f < textParameters.incrementAngle ); + + // Calculates the max ascender or the max descender. + // Is used to calculate the radius of the base line of the text. + float maxAscenderDescender = 0.f; + if( isCircularTextLayout ) + { + FontId currentFontId = 0u; + for( const auto& glyph : rendererParameters.glyphs ) + { + if( currentFontId != glyph.fontId ) + { + currentFontId = glyph.fontId; + FontMetrics metrics; + fontClient.GetFontMetrics(currentFontId, metrics); + maxAscenderDescender = std::max( maxAscenderDescender, isClockwise ? metrics.ascender : metrics.descender ); + } + } + } + const unsigned int radius = textParameters.radius - static_cast( maxAscenderDescender ); + + // Convert CircularAlignment to HorizontalAlignment. + if( isCircularTextLayout ) + { + switch( circularAlignment ) + { + case CircularAlignment::BEGIN: + { + horizontalCircularAlignment = Toolkit::HorizontalAlignment::BEGIN; + break; + } + case CircularAlignment::CENTER: + { + horizontalCircularAlignment = Toolkit::HorizontalAlignment::CENTER; + break; + } + case CircularAlignment::END: + { + horizontalCircularAlignment = Toolkit::HorizontalAlignment::END; + break; + } + } + } + + // Set the layout parameters. + Size textLayoutArea( static_cast( textParameters.textWidth ), + static_cast( textParameters.textHeight ) ); + + if( isCircularTextLayout ) + { + // In a circular layout, the length of the text area depends on the radius. + rendererParameters.radius = radius; + textLayoutArea.width = fabs( Radian( Degree( textParameters.incrementAngle ) ) * static_cast( rendererParameters.radius ) ); + } + // Resize the vector of positions to have the same size than the vector of glyphs. + rendererParameters.positions.Resize( numberOfGlyphs ); + + + + textModel->mHorizontalAlignment = isCircularTextLayout ? horizontalCircularAlignment : horizontalAlignment; + textModel->mLineWrapMode = LineWrap::WORD; + textModel->mIgnoreSpacesAfterText = false; + textModel->mMatchSystemLanguageDirection = false; + Text::Layout::Parameters layoutParameters( textLayoutArea, + textModel ); + + + // Whether the last character is a new paragraph character. + const Vector& textToShape = isTextMirrored ? mirroredUtf32Characters : textModel->mLogicalModel->mText; + layoutParameters.isLastNewParagraph = TextAbstraction::IsNewParagraph( textToShape[numberOfCharacters - 1u] ); + + // The initial glyph and the number of glyphs to layout. + layoutParameters.startGlyphIndex = 0u; + layoutParameters.numberOfGlyphs = numberOfGlyphs; + layoutParameters.startLineIndex = 0u; + layoutParameters.estimatedNumberOfLines = 1u; + layoutParameters.interGlyphExtraAdvance = 0.f; + + // Update the visual model. + Size newLayoutSize; + bool isAutoScrollEnabled = false; + layoutEngine.LayoutText( layoutParameters, + newLayoutSize, + textParameters.ellipsisEnabled, + isAutoScrollEnabled ); //////////////////////////////////////////////////////////////////////////////// + // Align the text. + //////////////////////////////////////////////////////////////////////////////// + Align( textParameters, rendererParameters, embeddedItemLayout, internalDataModel, + textLayoutArea, newLayoutSize, isCircularTextLayout, isClockwise, + horizontalAlignment, verticalAlignment, circularAlignment, radius ); + + return textLayoutArea; + +} + + +Devel::PixelBuffer RenderText( const RendererParameters& textParameters, TextAbstraction::TextRenderer::Parameters& rendererParameters ) +{ + //////////////////////////////////////////////////////////////////////////////// // Render the text. //////////////////////////////////////////////////////////////////////////////// @@ -1049,6 +1080,88 @@ Devel::PixelBuffer Render( const RendererParameters& textParameters, Vector& embeddedItemLayout ) +{ + if( textParameters.text.empty() ) + { + Dali::Devel::PixelBuffer pixelBuffer = Dali::Devel::PixelBuffer::New( textParameters.textWidth, + textParameters.textHeight, + Dali::Pixel::RGBA8888 ); + + const unsigned int bufferSize = textParameters.textWidth * textParameters.textHeight * Dali::Pixel::GetBytesPerPixel(Dali::Pixel::RGBA8888); + unsigned char* buffer = pixelBuffer.GetBuffer(); + memset(buffer, 0, bufferSize); + + return pixelBuffer; + } + + FontClient fontClient = FontClient::Get(); + MetricsPtr metrics; + // Use this to access FontClient i.e. to get down-scaled Emoji metrics. + metrics = Metrics::New( fontClient ); + + Text::ModelPtr textModel = Text::Model::New(); + InternalDataModel internalData( fontClient, metrics, textModel ); + + TextAbstraction::TextRenderer::Parameters rendererParameters( internalData.textModel->mVisualModel->mGlyphs, + internalData.textModel->mVisualModel->mGlyphPositions, + internalData.textModel->mVisualModel->mColors, + internalData.textModel->mVisualModel->mColorIndices, + internalData.blendingMode, + internalData.isEmoji ); + + + rendererParameters.width = textParameters.textWidth; + rendererParameters.height = textParameters.textHeight; + rendererParameters.pixelFormat = TextAbstraction::TextRenderer::Parameters::RGBA8888; // @note: At the moment all textures are generated RGBA8888 + + + //////////////////////////////////////////////////////////////////////////////// + // Process the markup string if the mark-up processor is enabled. + //////////////////////////////////////////////////////////////////////////////// + ShapeTextPreprocess( textParameters, rendererParameters, internalData ); + + //////////////////////////////////////////////////////////////////////////////// + // Retrieve the glyphs. Text shaping + //////////////////////////////////////////////////////////////////////////////// + ShapeText( rendererParameters, embeddedItemLayout, internalData ); + + + //////////////////////////////////////////////////////////////////////////////// + // Retrieve the glyph's metrics. + //////////////////////////////////////////////////////////////////////////////// + + metrics->GetGlyphMetrics( rendererParameters.glyphs.Begin(), internalData.numberOfGlyphs ); + + //////////////////////////////////////////////////////////////////////////////// + // Set the color runs in glyphs. + //////////////////////////////////////////////////////////////////////////////// + SetColorSegmentation( textParameters, internalData ); + + + //////////////////////////////////////////////////////////////////////////////// + // Set the isEmoji Vector + //////////////////////////////////////////////////////////////////////////////// + SetEmojiVector( internalData ); + + //////////////////////////////////////////////////////////////////////////////// + // Layout the text and Align the text + //////////////////////////////////////////////////////////////////////////////// + Size textLayoutArea = LayoutText( textParameters, rendererParameters, embeddedItemLayout, internalData ); + + //////////////////////////////////////////////////////////////////////////////// + // Ellipsis the text. + //////////////////////////////////////////////////////////////////////////////// + Ellipsis( textParameters, rendererParameters, embeddedItemLayout, textLayoutArea, internalData ); + + //////////////////////////////////////////////////////////////////////////////// + // Render the text. + //////////////////////////////////////////////////////////////////////////////// + return RenderText( textParameters, rendererParameters ); +} + + Devel::PixelBuffer CreateShadow( const ShadowParameters& shadowParameters ) { // The size of the pixel data. @@ -1283,6 +1396,10 @@ void UpdateBuffer(Devel::PixelBuffer src, Devel::PixelBuffer dst, unsigned int x } const unsigned int bytesPerPixel = Dali::Pixel::GetBytesPerPixel(pixelFormat); + if( bytesPerPixel == 0u || bytesPerPixel == 12u || bytesPerPixel == 24u ) + { + return; + } const unsigned int alphaIndex = bytesPerPixel - 1u; const unsigned char* const srcBuffer = src.GetBuffer();