mController = Text::Controller::New();
}
+Vector3 TextLabel::GetNaturalSize()
+{
+ return mController->GetNaturalSize();
+}
+
+float TextLabel::GetHeightForWidth( float width )
+{
+ return mController->GetHeightForWidth( width );
+}
+
void TextLabel::OnRelayout( const Vector2& size, ActorSizeContainer& container )
{
if( mController->Relayout( size ) )
*/
virtual void OnRelayout( const Vector2& size, ActorSizeContainer& container );
+ /**
+ * @copydoc Control::GetNaturalSize()
+ */
+ virtual Vector3 GetNaturalSize();
+
+ /**
+ * @copydoc Control::GetHeightForWidth()
+ */
+ virtual float GetHeightForWidth( float width );
+
private: // Implementation
/**
if( TextAbstraction::UNKNOWN == script )
{
- script = TextAbstraction::LATIN;
- DALI_ASSERT_DEBUG( !"MultilanguageSupport::SetScripts. Unkown script!" );
+ if( IsZeroWidthNonJoiner( character ) ||
+ IsZeroWidthJoiner( character ) ||
+ IsZeroWidthSpace( character ) ||
+ IsLeftToRightMark( character ) ||
+ IsRightToLeftMark( character ) ||
+ IsThinSpace( character ) )
+ {
+ // Keep previous script if the character is a zero width joiner or a zero width non joiner.
+ script = currentScriptRun.script;
+ }
+ else
+ {
+ script = TextAbstraction::LATIN;
+ DALI_ASSERT_DEBUG( !"MultilanguageSupport::SetScripts. Unkown script!" );
+ }
}
if( script != currentScriptRun.script )
// FIXME Single font assumption
Text::FontMetrics fontMetrics;
GlyphInfo firstGlyph;
- visualModel.GetGlyphs( 0, &firstGlyph, 1 );
+ visualModel.GetGlyphs( &firstGlyph, 0, 1 );
mFontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics );
float penX( 0 );
for( unsigned int i=0; i<glyphCount; ++i )
{
GlyphInfo glyph;
- visualModel.GetGlyphs( i, &glyph, 1 );
+ visualModel.GetGlyphs( &glyph, i, 1 );
glyphPositions.push_back( Vector2( penX + glyph.xBearing,
penY - glyph.yBearing ) );
if( glyphCount > 0 )
{
+ Size actualSize;
+
// FIXME Single font assumption
Text::FontMetrics fontMetrics;
GlyphInfo firstGlyph;
- visualModel.GetGlyphs( 0, &firstGlyph, 1 );
+ visualModel.GetGlyphs( &firstGlyph, 0, 1 );
mFontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics );
float penX( 0 );
for( ; i<glyphCount; ++i )
{
GlyphInfo glyph;
- visualModel.GetGlyphs( i, &glyph, 1 );
+ visualModel.GetGlyphs( &glyph, i, 1 );
if( glyph.width > 0 &&
glyph.height > 0 )
for( ; j<glyphCount; ++j )
{
GlyphInfo glyph;
- visualModel.GetGlyphs( j, &glyph, 1 );
+ visualModel.GetGlyphs( &glyph, j, 1 );
endPenX += glyph.advance;
}
else if( endPenX > boundingBox.width )
{
+ actualSize.width = ( actualSize.width < endPenX - glyph.advance ) ? endPenX - glyph.advance : actualSize.width;
break;
}
}
for( ; i<endIndex; ++i )
{
GlyphInfo glyph;
- visualModel.GetGlyphs( i, &glyph, 1 );
+ visualModel.GetGlyphs( &glyph, i, 1 );
glyphPositions.push_back( Vector2( penX + glyph.xBearing,
penY - glyph.yBearing ) );
// Go to next line
penX = 0;
penY += fontMetrics.height;
+
+ actualSize.height += fontMetrics.height;
}
visualModel.SetGlyphPositions( &glyphPositions[0], glyphCount );
+
+ visualModel.SetActualSize( actualSize );
}
}
namespace Text
{
-class LogicalModel;
class VisualModel;
/**
Vector<GlyphInfo> glyphs;
glyphs.Resize( numberOfGlyphs );
- view.GetGlyphs( 0, &glyphs[0], numberOfGlyphs );
+ view.GetGlyphs( &glyphs[0], 0, numberOfGlyphs );
std::vector<Vector2> positions;
positions.resize( numberOfGlyphs );
- view.GetGlyphPositions( 0, &positions[0], numberOfGlyphs );
+ view.GetGlyphPositions( &positions[0], 0, numberOfGlyphs );
Atlas atlas = mImpl->CreateAtlas( glyphs );
namespace Text
{
+namespace
+{
+const unsigned int CHAR_ZWS = 0x200B; ///< Zero width space.
+const unsigned int CHAR_ZWNJ = 0x200C; ///< Zero width non joiner.
+const unsigned int CHAR_ZWJ = 0x200D; ///< Zero width joiner.
+const unsigned int CHAR_LTRM = 0x200E; ///< Left to Right Mark.
+const unsigned int CHAR_RTLM = 0x200F; ///< Right to Left Mark.
+const unsigned int CHAR_TS = 0x2009; ///< Thin Space.
+} // namespace
+
Script GetCharacterScript( Character character )
{
// Latin script:
// 0x0e00 - 0x0e7f Thai
// Burmese script
- // 0x1000 - 0x104f Myanmar
+ // 0x1000 - 0x109f Myanmar
if( character <= 0x0cff )
{
return TextAbstraction::LAO;
}
- if( ( 0x1000 <= character ) && ( character <= 0x104f ) )
+ if( ( 0x1000 <= character ) && ( character <= 0x109f ) )
{
return TextAbstraction::BURMESE;
}
return TextAbstraction::UNKNOWN;
}
+bool IsZeroWidthNonJoiner( Character character )
+{
+ return CHAR_ZWNJ == character;
+}
+
+bool IsZeroWidthJoiner( Character character )
+{
+ return CHAR_ZWJ == character;
+}
+
+bool IsZeroWidthSpace( Character character )
+{
+ return CHAR_ZWS == character;
+}
+
+bool IsLeftToRightMark( Character character )
+{
+ return CHAR_LTRM == character;
+}
+
+bool IsRightToLeftMark( Character character )
+{
+ return CHAR_RTLM == character;
+}
+
+bool IsThinSpace( Character character )
+{
+ return CHAR_TS == character;
+}
+
} // namespace Text
} // namespace Toolkit
*/
Script GetCharacterScript( Character character );
+/**
+ * @brief Whether the character is a zero width non joiner.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a zero width non joiner.
+ */
+bool IsZeroWidthNonJoiner( Character character );
+
+/**
+ * @brief Whether the character is a zero width joiner.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a zero width joiner.
+ */
+bool IsZeroWidthJoiner( Character character );
+
+/**
+ * @brief Whether the character is a zero width space.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a zero width space.
+ */
+bool IsZeroWidthSpace( Character character );
+
+/**
+ * @brief Whether the character is a left to right mark.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a left to right mark.
+ */
+bool IsLeftToRightMark( Character character );
+
+/**
+ * @brief Whether the character is a right to left mark.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a right to left mark.
+ */
+bool IsRightToLeftMark( Character character );
+
+/**
+ * @brief Whether the character is a thin space.
+ *
+ * @param[in] character The character.
+ *
+ * @return @e true if the character is a thin space.
+ */
+bool IsThinSpace( Character character );
+
} // namespace Text
} // namespace Toolkit
// CLASS HEADER
#include <dali-toolkit/public-api/text/text-controller.h>
-// EXTERNAL INCLUDES
-#include <dali/public-api/text-abstraction/font-client.h>
-
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/text/character-set-conversion.h>
#include <dali-toolkit/public-api/text/layouts/layout-engine.h>
#include <dali-toolkit/public-api/text/text-view.h>
#include <dali-toolkit/public-api/text/visual-model.h>
+// EXTERNAL INCLUDES
+#include <dali/public-api/text-abstraction/font-client.h>
+#include <limits>
+
namespace Dali
{
struct Controller::Impl
{
Impl()
- : mNewTextArrived( false )
+ : mNewText(),
+ mOperations( NO_OPERATION )
{
mLogicalModel = LogicalModel::New();
mVisualModel = VisualModel::New();
}
std::string mNewText;
- bool mNewTextArrived;
LogicalModelPtr mLogicalModel;
VisualModelPtr mVisualModel;
LayoutEngine mLayoutEngine;
TextAbstraction::FontClient mFontClient;
+
+ OperationsMask mOperations;
};
ControllerPtr Controller::New()
{
// Keep until size negotiation
mImpl->mNewText = text;
- mImpl->mNewTextArrived = true;
+ mImpl->mOperations = ALL_OPERATIONS;
}
bool Controller::Relayout( const Vector2& size )
{
+ if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
+ {
+ // Not worth to relayout if width or height is equal to zero.
+ return false;
+ }
+
+ bool viewUpdated = false;
+
+ if( size != mControlSize )
+ {
+ viewUpdated = DoRelayout( size, mImpl->mOperations );
+
+ // Do not re-do any operation until something changes.
+ mImpl->mOperations = NO_OPERATION;
+
+ mControlSize = size;
+ }
+
+ return viewUpdated;
+}
+
+bool Controller::DoRelayout( const Vector2& size, OperationsMask operations )
+{
bool viewUpdated( false );
- if( mImpl->mNewTextArrived )
+ Vector<Character> utf32Characters;
+ Length characterCount = 0u;
+ if( CONVERT_TO_UTF32 & operations )
{
std::string& text = mImpl->mNewText;
// Convert text into UTF-32
- Vector<Character> utf32Characters;
utf32Characters.Resize( text.size() );
// This is a bit horrible but std::string returns a (signed) char*
const uint8_t* utf8 = reinterpret_cast<const uint8_t*>( text.c_str() );
- Length characterCount = Utf8ToUtf32( utf8, text.size(), &utf32Characters[0] );
+ // Transform a text array encoded in utf8 into an array encoded in utf32.
+ // It returns the actual number of characters.
+ characterCount = Utf8ToUtf32( utf8, text.size(), utf32Characters.Begin() );
utf32Characters.Resize( characterCount );
- Vector<ScriptRun> scripts;
+ // Sets the text into the model.
+ mImpl->mLogicalModel->SetText( utf32Characters.Begin(), characterCount );
+
+ // Discard temporary text
+ text.clear();
+ }
+
+ const bool getScripts = GET_SCRIPTS & operations;
+ const bool validateFonts = VALIDATE_FONTS & operations;
+
+ Vector<ScriptRun> scripts;
+ Vector<FontRun> fonts;
+ if( getScripts || validateFonts )
+ {
+ // Validates the fonts assigned by the application or assigns default ones.
+ // It makes sure all the characters are going to be rendered by the correct font.
MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
- multilanguageSupport.SetScripts( utf32Characters,
- scripts );
+ if( getScripts )
+ {
+ // Retrieves the scripts used in the text.
+ multilanguageSupport.SetScripts( utf32Characters,
+ scripts );
- Vector<FontRun> fonts;
- multilanguageSupport.ValidateFonts( utf32Characters,
- scripts,
- fonts );
+ // Sets the scripts into the model.
+ mImpl->mLogicalModel->SetScripts( scripts.Begin(), scripts.Count() );
+ }
- Vector<LineBreakInfo> lineBreakInfo;
- lineBreakInfo.Resize( characterCount, TextAbstraction::LINE_NO_BREAK );
+ if( validateFonts )
+ {
+ // Validates the fonts. If there is a character with no assigned font it sets a default one.
+ // After this call, fonts are validated.
+ multilanguageSupport.ValidateFonts( utf32Characters,
+ scripts,
+ fonts );
+
+ // Sets the fonts into the model.
+ mImpl->mLogicalModel->SetFonts( fonts.Begin(), fonts.Count() );
+ }
+ }
- Vector<GlyphInfo> glyphs;
- Vector<CharacterIndex> characterIndices;
- Vector<Length> charactersPerGlyph;
+ Vector<LineBreakInfo> lineBreakInfo;
+ if( GET_LINE_BREAKS & operations )
+ {
+ // Retrieves the line break info. The line break info is used to split the text in 'paragraphs' to
+ // calculate the bidirectional info for each 'paragraph'.
+ // It's also used to layout the text (where it should be a new line) or to shape the text (text in different lines
+ // is not shaped together).
+ lineBreakInfo.Resize( characterCount, TextAbstraction::LINE_NO_BREAK );
+ mImpl->mLogicalModel->SetLineBreakInfo( lineBreakInfo.Begin(), characterCount );
+ }
+ Vector<GlyphInfo> glyphs;
+ Vector<CharacterIndex> characterIndices;
+ Vector<Length> charactersPerGlyph;
+ if( SHAPE_TEXT & operations )
+ {
+ // Shapes the text.
ShapeText( utf32Characters,
lineBreakInfo,
scripts,
glyphs,
characterIndices,
charactersPerGlyph );
+ }
- // Manipulate the logical model
- mImpl->mLogicalModel->SetText( &utf32Characters[0], characterCount );
- mImpl->mLogicalModel->SetLineBreakInfo( &lineBreakInfo[0], characterCount );
- mImpl->mLogicalModel->SetScripts( &scripts[0], scripts.Count() );
- mImpl->mLogicalModel->SetFonts( &fonts[0], fonts.Count() );
+ if( GET_GLYPH_METRICS & operations )
+ {
+ TextAbstraction::FontClient::Get().GetGlyphMetrics( glyphs.Begin(), glyphs.Count() );
+ }
- if( TextAbstraction::FontClient::Get().GetGlyphMetrics( &glyphs[0], glyphs.Size() ) )
+ if( LAYOUT & operations )
+ {
+ if( 0u == glyphs.Count() )
{
- // Update the visual model
- mImpl->mLayoutEngine.UpdateVisualModel( size,
- glyphs,
- characterIndices,
- charactersPerGlyph,
- *mImpl->mVisualModel );
+ const Length numberOfGlyphs = mImpl->mVisualModel->GetNumberOfGlyphs();
+
+ glyphs.Resize( numberOfGlyphs );
+ characterIndices.Resize( numberOfGlyphs );
+ charactersPerGlyph.Resize( numberOfGlyphs );
+
+ mImpl->mVisualModel->GetGlyphs( glyphs.Begin(),
+ 0u,
+ numberOfGlyphs );
+
+ mImpl->mVisualModel->GetGlyphToCharacterMap( characterIndices.Begin(),
+ 0u,
+ numberOfGlyphs );
+
+ mImpl->mVisualModel->GetCharactersPerGlyphMap( charactersPerGlyph.Begin(),
+ 0u,
+ numberOfGlyphs );
}
- // Discard temporary text
- mImpl->mNewTextArrived = false;
- text.clear();
+ // Update the visual model
+ mImpl->mLayoutEngine.UpdateVisualModel( size,
+ glyphs,
+ characterIndices,
+ charactersPerGlyph,
+ *mImpl->mVisualModel );
viewUpdated = true;
}
return viewUpdated;
}
+Vector3 Controller::GetNaturalSize()
+{
+ // Operations that can be done only once until the text changes.
+ const OperationsMask onlyOnceOperations = static_cast<OperationsMask>( CONVERT_TO_UTF32 |
+ GET_SCRIPTS |
+ VALIDATE_FONTS |
+ GET_LINE_BREAKS |
+ GET_WORD_BREAKS |
+ SHAPE_TEXT |
+ GET_GLYPH_METRICS );
+
+ // Operations that need to be done if the size or the text changes.
+ const OperationsMask sizeOperations = static_cast<OperationsMask>( LAYOUT |
+ REORDER );
+
+ const float maxFloat = std::numeric_limits<float>::max();
+ DoRelayout( Vector2( maxFloat, maxFloat ),
+ static_cast<OperationsMask>( onlyOnceOperations |
+ sizeOperations ) );
+
+ // Do not do again the only once operations.
+ mImpl->mOperations = static_cast<OperationsMask>( mImpl->mOperations & ~onlyOnceOperations );
+
+ // Do the size related operations again.
+ mImpl->mOperations = static_cast<OperationsMask>( mImpl->mOperations | sizeOperations );
+
+ return Vector3( mImpl->mVisualModel->GetNaturalSize() );
+}
+
+float Controller::GetHeightForWidth( float width )
+{
+ // Operations that can be done only once until the text changes.
+ const OperationsMask onlyOnceOperations = static_cast<OperationsMask>( CONVERT_TO_UTF32 |
+ GET_SCRIPTS |
+ VALIDATE_FONTS |
+ GET_LINE_BREAKS |
+ GET_WORD_BREAKS |
+ SHAPE_TEXT |
+ GET_GLYPH_METRICS );
+
+ // Operations that need to be done if the size or the text changes.
+ const OperationsMask sizeOperations = static_cast<OperationsMask>( LAYOUT |
+ REORDER );
+
+ DoRelayout( Size( width, 0.f ),
+ static_cast<OperationsMask>( onlyOnceOperations |
+ sizeOperations ) );
+
+ // Do not do again the only once operations.
+ mImpl->mOperations = static_cast<OperationsMask>( mImpl->mOperations & ~onlyOnceOperations );
+
+ // Do the size related operations again.
+ mImpl->mOperations = static_cast<OperationsMask>( mImpl->mOperations | sizeOperations );
+
+ return mImpl->mVisualModel->GetActualSize().height;
+}
+
View& Controller::GetView()
{
return mImpl->mView;
}
Controller::Controller()
-: mImpl( NULL )
+: mImpl( NULL ),
+ mControlSize()
{
mImpl = new Controller::Impl();
}
*/
// INTERNAL INCLUDES
-#include <dali/public-api/common/intrusive-ptr.h>
-#include <dali/public-api/object/ref-object.h>
#include <dali-toolkit/public-api/text/text-view.h>
// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/math/vector3.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/object/ref-object.h>
#include <string>
namespace Dali
*/
class Controller : public RefObject
{
+private:
+
+ /**
+ * @brief Text related operations to be done in the relayout process.
+ */
+ enum OperationsMask
+ {
+ NO_OPERATION = 0x0,
+ CONVERT_TO_UTF32 = 0x1,
+ GET_SCRIPTS = 0x2,
+ VALIDATE_FONTS = 0x4,
+ GET_LINE_BREAKS = 0x8,
+ GET_WORD_BREAKS = 0x10,
+ SHAPE_TEXT = 0x20,
+ GET_GLYPH_METRICS = 0x40,
+ LAYOUT = 0x80,
+ REORDER = 0x100,
+ ALIGNEMENT = 0x200,
+ RENDER = 0x400,
+ ALL_OPERATIONS = 0xFFF
+ };
+
public:
/**
bool Relayout( const Vector2& size );
/**
+ *
+ */
+ bool DoRelayout( const Vector2& size, OperationsMask operations );
+
+ /**
+ * @copydoc Control::GetNaturalSize()
+ */
+ Vector3 GetNaturalSize();
+
+ /**
+ * @copydoc Control::GetHeightForWidth()
+ */
+ float GetHeightForWidth( float width );
+
+ /**
* @brief Return the layout engine.
*
* @return A reference to the layout engine.
struct Impl;
Impl* mImpl;
+
+ Size mControlSize;
};
+
} // namespace Text
} // namespace Toolkit
namespace Text
{
-typedef TextAbstraction::FontId FontId; ///< The unique identifier for a font face (generated by FontClient).
-typedef TextAbstraction::FontMetrics FontMetrics; ///< The metrics for a Font expressed in 26.6 fractional pixel format.
-typedef TextAbstraction::PointSize26Dot6 PointSize26Dot6; ///< The point size in 26.6 fractional points.
-typedef TextAbstraction::FaceIndex FaceIndex; ///< Used with fonts which allow several font faces.
-typedef TextAbstraction::GlyphIndex GlyphIndex; ///< Uniquely identifies a glyph within a particular font.
-typedef TextAbstraction::Character Character; ///< A UTF-32 representation of a character.
-typedef TextAbstraction::GlyphInfo GlyphInfo; ///< The information describing a glyph (font ID, index, metrics).
-typedef TextAbstraction::CharacterIndex CharacterIndex; ///< An index into an array of characters.
-typedef TextAbstraction::Length Length; ///< The length of an array.
-typedef TextAbstraction::BidiInfoIndex BidiInfoIndex; ///< Index to the bidirectional info for a paragraph.
-typedef TextAbstraction::Script Script; ///< The character's script.
-typedef TextAbstraction::LineBreakInfo LineBreakInfo; ///< Line break info (must break, allow break, no break). Possible values are: @e LINE_MUST_BREAK, @e LINE_ALLOW_BREAK and @e LINE_NO_BREAK (in the TextAbstraction namespace).
-typedef TextAbstraction::WordBreakInfo WordBreakInfo; ///< Word break info (break, no break). Possible values are: @e WORD_BREAK and @e WORD_NO_BREAK (in the TextAbstraction namespace).
-
-typedef uint32_t GlyphIndex; ///< An index into an array of glyphs
-typedef bool CharacterDirection; ///< The character's direction: @e false is left to right, @e true is right to left.
+typedef TextAbstraction::FontId FontId; ///< The unique identifier for a font face (generated by FontClient).
+typedef TextAbstraction::FontMetrics FontMetrics; ///< The metrics for a Font expressed in 26.6 fractional pixel format.
+typedef TextAbstraction::PointSize26Dot6 PointSize26Dot6; ///< The point size in 26.6 fractional points.
+typedef TextAbstraction::FaceIndex FaceIndex; ///< Used with fonts which allow several font faces.
+typedef TextAbstraction::GlyphIndex GlyphIndex; ///< Uniquely identifies a glyph within a particular font.
+typedef TextAbstraction::Character Character; ///< A UTF-32 representation of a character.
+typedef TextAbstraction::GlyphInfo GlyphInfo; ///< The information describing a glyph (font ID, index, metrics).
+typedef TextAbstraction::CharacterIndex CharacterIndex; ///< An index into an array of characters.
+typedef TextAbstraction::Length Length; ///< The length of an array.
+typedef TextAbstraction::BidiInfoIndex BidiInfoIndex; ///< Index to the bidirectional info for a paragraph.
+typedef TextAbstraction::Script Script; ///< The character's script.
+typedef TextAbstraction::LineBreakInfo LineBreakInfo; ///< Line break info (must break, allow break, no break). Possible values are: @e LINE_MUST_BREAK, @e LINE_ALLOW_BREAK and @e LINE_NO_BREAK (in the TextAbstraction namespace).
+typedef TextAbstraction::WordBreakInfo WordBreakInfo; ///< Word break info (break, no break). Possible values are: @e WORD_BREAK and @e WORD_NO_BREAK (in the TextAbstraction namespace).
+
+typedef uint32_t GlyphIndex; ///< An index into an array of glyphs.
+typedef bool CharacterDirection; ///< The character's direction: @e false is left to right, @e true is right to left.
+typedef uint32_t LineIndex; ///< An index into an array of lines.
} // namespace Text
* @param[in] glyphIndex Index to the first glyph.
* @param[in] numberOfGlyphs Number of glyphs to be copied.
*/
- virtual void GetGlyphs( GlyphIndex glyphIndex,
- GlyphInfo* glyphs,
+ virtual void GetGlyphs( GlyphInfo* glyphs,
+ GlyphIndex glyphIndex,
Length numberOfGlyphs ) const = 0;
/**
* @brief Retrieves the glyph positions.
*
* @pre The size of the @p positions buffer needs to be big enough to copy the @p numberOfGlyphs positions.
- * @param[in] glyphIndex Index to the first glyph position.
* @param[out] glyphPositions Pointer to a buffer where the glyph positions are copied.
+ * @param[in] glyphIndex Index to the first glyph position.
* @param[in] numberOfGlyphs The number of positions to be copied.
*/
- virtual void GetGlyphPositions( GlyphIndex glyphIndex,
- Vector2* glyphPositions,
+ virtual void GetGlyphPositions( Vector2* glyphPositions,
+ GlyphIndex glyphIndex,
Length numberOfGlyphs ) const = 0;
};
return 0;
}
-void View::GetGlyphs( GlyphIndex glyphIndex,
- GlyphInfo* glyphs,
+void View::GetGlyphs( GlyphInfo* glyphs,
+ GlyphIndex glyphIndex,
Length numberOfGlyphs ) const
{
if( mImpl->mVisualModel )
{
- mImpl->mVisualModel->GetGlyphs( glyphIndex, glyphs, numberOfGlyphs );
+ mImpl->mVisualModel->GetGlyphs( glyphs, glyphIndex, numberOfGlyphs );
}
}
-void View::GetGlyphPositions( GlyphIndex glyphIndex,
- Vector2* glyphPositions,
+void View::GetGlyphPositions( Vector2* glyphPositions,
+ GlyphIndex glyphIndex,
Length numberOfGlyphs ) const
{
if( mImpl->mVisualModel )
{
- mImpl->mVisualModel->GetGlyphPositions( glyphIndex, glyphPositions, numberOfGlyphs );
+ mImpl->mVisualModel->GetGlyphPositions( glyphPositions, glyphIndex, numberOfGlyphs );
}
}
/**
* @copydoc Dali::Toolkit::Text::ViewInterface::GetGlyphs()
*/
- virtual void GetGlyphs( GlyphIndex glyphIndex,
- GlyphInfo* glyphs,
+ virtual void GetGlyphs( GlyphInfo* glyphs,
+ GlyphIndex glyphIndex,
Length numberOfGlyphs ) const;
/**
* @copydoc Dali::Toolkit::Text::ViewInterface::GetGlyphPositions()
*/
- virtual void GetGlyphPositions( GlyphIndex glyphIndex,
- Vector2* glyphPositions,
+ virtual void GetGlyphPositions( Vector2* glyphPositions,
+ GlyphIndex glyphIndex,
Length numberOfGlyphs ) const;
private:
// INTERNAL INCLUDES
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/math/vector2.h>
+#include <dali-toolkit/public-api/text/line-run.h>
// EXTERNAL INCLUDES
#include <memory.h>
namespace Text
{
+const GlyphInfo GLYPH_INFO; // VCC to be removed.
+
struct VisualModel::Impl
{
Vector<GlyphInfo> mGlyphs;
Vector<CharacterIndex> mGlyphsToCharacters;
Vector<Length> mCharactersPerGlyph;
std::vector<Vector2> mGlyphPositions;
+
+ Size mNaturalSize;
+ Size mActualSize;
};
VisualModelPtr VisualModel::New()
return mImpl->mGlyphs.Count();
}
-void VisualModel::GetGlyphs( GlyphIndex glyphIndex,
- GlyphInfo* glyphs,
+void VisualModel::GetGlyphs( GlyphInfo* glyphs,
+ GlyphIndex glyphIndex,
Length numberOfGlyphs ) const
{
Vector<GlyphInfo>& modelGlyphs = mImpl->mGlyphs;
memcpy( glyphs, &modelGlyphs[glyphIndex], numberOfGlyphs*sizeof(GlyphInfo) );
}
+const GlyphInfo& VisualModel::GetGlyphInfo( GlyphIndex glyphIndex ) const
+{
+ return GLYPH_INFO;
+}
+
CharacterIndex VisualModel::GetCharacterIndex( GlyphIndex glyphIndex ) const
{
return mImpl->mGlyphsToCharacters[glyphIndex];
return index;
}
+void VisualModel::GetCharacterToGlyphMap( GlyphIndex* characterToGlyphMap,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+}
+
+void VisualModel::GetCharactersPerGlyphMap( Length* charactersPerGlyph,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+}
+
+void VisualModel::GetGlyphToCharacterMap( CharacterIndex* glyphToCharacter,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+}
+
void VisualModel::SetGlyphPositions( const Vector2* glyphPositions,
Length numberOfGlyphs )
{
memcpy( &modelPositions[0], glyphPositions, numberOfGlyphs*sizeof(Vector2) );
}
-void VisualModel::GetGlyphPositions( GlyphIndex glyphIndex,
- Vector2* glyphPositions,
+void VisualModel::GetGlyphPositions( Vector2* glyphPositions,
+ GlyphIndex glyphIndex,
Length numberOfGlyphs ) const
{
std::vector<Vector2>& modelPositions = mImpl->mGlyphPositions;
memcpy( glyphPositions, &modelPositions[0], numberOfGlyphs*sizeof(Vector2) );
}
+const Vector2& VisualModel::GetGlyphPosition( GlyphIndex glyphIndex ) const
+{
+ return Vector2::ZERO;
+}
+
+void VisualModel::SetLines( const LineRun* const lines,
+ Length numberOfLines )
+{
+}
+
+Length VisualModel::GetNumberOfLines() const
+{
+ return 0u;
+}
+
+void VisualModel::GetLines( LineRun* lines,
+ LineIndex lineIndex,
+ Length numberOfLines ) const
+{
+}
+
+Length VisualModel::GetNumberOfLines( GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+ return 0u;
+}
+
+void VisualModel::GetLinesOfGlyphRange( LineRun* lines,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const
+{
+}
+
+void VisualModel::SetNaturalSize( const Vector2& size )
+{
+ mImpl->mNaturalSize = size;
+}
+
+const Vector2& VisualModel::GetNaturalSize() const
+{
+ return mImpl->mNaturalSize;
+}
+
+void VisualModel::SetActualSize( const Vector2& size )
+{
+ mImpl->mActualSize = size;
+}
+
+const Vector2& VisualModel::GetActualSize() const
+{
+ return mImpl->mActualSize;
+}
+
VisualModel::~VisualModel()
{
delete mImpl;
namespace Text
{
+struct LineRun;
class VisualModel;
typedef IntrusivePtr<VisualModel> VisualModelPtr;
* @param[in] glyphIndex Index to the first glyph.
* @param[in] numberOfGlyphs Number of glyphs to be copied.
*/
- void GetGlyphs( GlyphIndex glyphIndex,
- GlyphInfo* glyphs,
+ void GetGlyphs( GlyphInfo* glyphs,
+ GlyphIndex glyphIndex,
Length numberOfGlyphs ) const;
+ /**
+ * Retrieves a glyph.
+ *
+ * @param[in] glyphIndex Index to a glyph.
+ *
+ * @return A glyph.
+ */
+ const GlyphInfo& GetGlyphInfo( GlyphIndex glyphIndex ) const;
+
// Character <--> Glyph conversion
/**
*/
GlyphIndex GetGlyphIndex( CharacterIndex characterIndex ) const;
+ /**
+ * Retrieves the whole or part of the character to glyph conversion map.
+ *
+ * The size of the buffer needs to be big enough to copy the @p numberOfCharacters.
+ *
+ * @param[out] characterToGlyphMap Pointer to a buffer where the conversion map is copied.
+ * @param[in] characterIndex Index to the first character.
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void GetCharacterToGlyphMap( GlyphIndex* characterToGlyphMap,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const;
+
+ /**
+ * Retrieves for each glyph the number of characters the glyph represents.
+ *
+ * @param[out] charactersPerGlyph Pointer to a buffer where the number of characters for each glyph are copied.
+ * @param[in] glyphIndex Index to the first glyph.
+ * @param[in] numberOfGlyphs The number of glyphs.
+ */
+ void GetCharactersPerGlyphMap( Length* charactersPerGlyph,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+
+ /**
+ * Retrieves the whole or part of the glyph to character conversion map.
+ *
+ * The size of the buffer needs to be big enough to copy the @p numberOfGlyphs.
+ *
+ * @param[out] glyphToCharacter Pointer to a buffer where the conversion map is copied.
+ * @param[in] glyphIndex Index to the first glyph.
+ * @param[in] numberOfGlyphs The number of glyphs.
+ */
+ void GetGlyphToCharacterMap( CharacterIndex* glyphToCharacter,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+
// Position interface
/**
* @brief Retrieves the glyph positions.
*
* @pre The size of the @p positions buffer needs to be big enough to copy the @p numberOfGlyphs positions.
- * @param[in] glyphIndex Index to the first glyph position.
* @param[out] glyphPositions Pointer to a buffer where the glyph positions are copied.
+ * @param[in] glyphIndex Index to the first glyph position.
* @param[in] numberOfGlyphs The number of positions to be copied.
*/
- void GetGlyphPositions( GlyphIndex glyphIndex,
- Vector2* glyphPositions,
+ void GetGlyphPositions( Vector2* glyphPositions,
+ GlyphIndex glyphIndex,
Length numberOfGlyphs ) const;
+ /**
+ * Retrieve the glyph's position of the given glyph.
+ *
+ * @param[in] glyphIndex Index to the glyph.
+ *
+ * @return The glyph's position.
+ */
+ const Vector2& GetGlyphPosition( GlyphIndex glyphIndex ) const;
+
+ // Line interface.
+
+ /**
+ * Sets the lines.
+ *
+ * Replaces any lines previously set.
+ *
+ * Every line is an item run containing the index to the first glyph of the line and the number of glyphs.
+ *
+ * @param[in] lines Pointer to a buffer containing all the line runs.
+ * @param[in] numberOfLines The number of lines in the buffer.
+ */
+ void SetLines( const LineRun* const lines,
+ Length numberOfLines );
+
+ /**
+ * Retrieves the number of lines of the whole text.
+ *
+ * @return The number of lines.
+ */
+ Length GetNumberOfLines() const;
+
+ /**
+ * Retrieves lines.
+ *
+ * The size of the @p lines buffer needs to be big enough to copy the @p numberOfLines.
+ *
+ * @param[out] lines Pointer to a buffer where the lines are copied.
+ * @param[in] lineIndex Index to the first line.
+ * @param[in] numberOfLines Number of lines to be copied.
+ */
+ void GetLines( LineRun* lines,
+ LineIndex lineIndex,
+ Length numberOfLines ) const;
+
+ /**
+ * Retrieves the number of lines where the given range of glyphs is laid out.
+ *
+ * @param[in] glyphIndex Index to the first glyph.
+ * @param[in] numberOfGlyphs The number of glyph.
+ *
+ * @return The number of lines.
+ */
+ TextAbstraction::Length GetNumberOfLines( GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+ /**
+ * Retrieves the lines where the given range of glyphs is laid out.
+ *
+ * The size of the @p lines buffer needs to be big enough to copy the @p numberOfLines.
+ *
+ * @param[out] lines Pointer to a buffer where the lines are copied.
+ * @param[in] glyphIndex Index to the first glyphs of the range.
+ * @param[in] numberOfGlyphs Number of glyphs in the range.
+ */
+ void GetLinesOfGlyphRange( LineRun* lines,
+ GlyphIndex glyphIndex,
+ Length numberOfGlyphs ) const;
+
+ // Size interface
+
+ /**
+ * Sets the natural size.
+ *
+ * @param[in] size The text's natural size.
+ */
+ void SetNaturalSize( const Vector2& size );
+
+ /**
+ * Retrieves the natural size.
+ *
+ * @return The text's natural size.
+ */
+ const Vector2& GetNaturalSize() const;
+
+ /**
+ * Sets the text's actual size after it has been laid out.
+ *
+ * @param[in] size The text's size.
+ */
+ void SetActualSize( const Vector2& size );
+
+ /**
+ * Retrieves the text's actual size after it has been laid out.
+ *
+ * @return The text's size.
+ */
+ const Vector2& GetActualSize() const;
+
protected:
/**