From 4333ca02dec1372cdb6133b70799a4d4edebe0d8 Mon Sep 17 00:00:00 2001 From: Paul Wisbey Date: Mon, 2 Feb 2015 14:50:06 +0000 Subject: [PATCH] Added skeleton TextController Change-Id: I8bab60c53d11a95764fb22ca89190e202e9f603f --- .../controls/text-controls/text-label-impl.cpp | 30 +++- .../controls/text-controls/text-label-impl.h | 10 +- base/dali-toolkit/public-api/file.list | 2 + .../public-api/text/character-set-conversion.cpp | 84 ++++----- .../dali-toolkit/public-api/text/logical-model.cpp | 1 + .../public-api/text/text-controller.cpp | 187 +++++++++++++++++++++ .../dali-toolkit/public-api/text/text-controller.h | 111 ++++++++++++ .../public-api/text/text-definitions.h | 1 + base/dali-toolkit/public-api/text/text-view.cpp | 20 +-- base/dali-toolkit/public-api/text/text-view.h | 30 +--- base/dali-toolkit/public-api/text/visual-model.cpp | 1 + optional/dali-toolkit/dali-toolkit.h | 1 + 12 files changed, 395 insertions(+), 83 deletions(-) create mode 100644 base/dali-toolkit/public-api/text/text-controller.cpp create mode 100644 base/dali-toolkit/public-api/text/text-controller.h diff --git a/base/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/base/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index ed63ba3..38335ee 100644 --- a/base/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/base/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -18,8 +18,9 @@ // CLASS HEADER #include -// INTERNAL INCLUDES +// EXTERNAL INCLUDES #include +#include namespace { @@ -83,9 +84,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr { case Toolkit::TextLabel::PROPERTY_TEXT: { - labelImpl.mText = value.Get< std::string >(); - - // TODO - Update Model etc. + labelImpl.SetText( value.Get< std::string >() ); break; } } @@ -100,12 +99,11 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde if( label ) { - TextLabel& labelImpl( GetImpl( label ) ); switch( index ) { case Toolkit::TextLabel::PROPERTY_TEXT: { - value = labelImpl.mText; + DALI_LOG_WARNING( "UTF-8 text representation was discarded\n" ); break; } } @@ -116,6 +114,26 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde void TextLabel::OnInitialize() { + mController = Text::Controller::New(); +} + +void TextLabel::SetText( const std::string& text ) +{ + if( mController ) + { + // The Controller updates the View for the renderer + mController->SetText( text ); + + if( mRenderer ) + { + Actor renderableActor = mRenderer->Render( mController->GetView() ); + + if( renderableActor ) + { + Self().Add( renderableActor ); + } + } + } } TextLabel::TextLabel() diff --git a/base/dali-toolkit/internal/controls/text-controls/text-label-impl.h b/base/dali-toolkit/internal/controls/text-controls/text-label-impl.h index 53bddf2..b3ecd0e 100644 --- a/base/dali-toolkit/internal/controls/text-controls/text-label-impl.h +++ b/base/dali-toolkit/internal/controls/text-controls/text-label-impl.h @@ -21,6 +21,7 @@ // INTERNAL INCLUDES #include #include +#include namespace Dali { @@ -83,6 +84,12 @@ private: // From Control private: // Implementation /** + * Helper for SetProperty. + * @param[in] text The new "text" property value. + */ + void SetText( const std::string& text ); + + /** * Construct a new TextLabel. */ TextLabel(); @@ -100,9 +107,8 @@ private: private: // Data - // TODO - Use Controller/Model for storage + Text::ControllerPtr mController; Text::RendererPtr mRenderer; - std::string mText; }; } // namespace Internal diff --git a/base/dali-toolkit/public-api/file.list b/base/dali-toolkit/public-api/file.list index c5a1b0c..93780bc 100755 --- a/base/dali-toolkit/public-api/file.list +++ b/base/dali-toolkit/public-api/file.list @@ -42,6 +42,7 @@ public_api_base_src_files = \ $(public_api_base_src_dir)/controls/text-controls/text-label.cpp \ $(public_api_base_src_dir)/text/character-set-conversion.cpp \ $(public_api_base_src_dir)/text/logical-model.cpp \ + $(public_api_base_src_dir)/text/text-controller.cpp \ $(public_api_base_src_dir)/text/text-renderer.cpp \ $(public_api_base_src_dir)/text/text-view.cpp \ $(public_api_base_src_dir)/text/text-view-interface.cpp \ @@ -125,6 +126,7 @@ public_api_base_text_controls_header_files = \ public_api_base_text_header_files = \ $(public_api_base_src_dir)/text/character-set-conversion.h \ $(public_api_base_src_dir)/text/logical-model.h \ + $(public_api_base_src_dir)/text/text-controller.h \ $(public_api_base_src_dir)/text/text-definitions.h \ $(public_api_base_src_dir)/text/text-renderer.h \ $(public_api_base_src_dir)/text/text-view.h \ diff --git a/base/dali-toolkit/public-api/text/character-set-conversion.cpp b/base/dali-toolkit/public-api/text/character-set-conversion.cpp index d2a8c55..88356f4 100644 --- a/base/dali-toolkit/public-api/text/character-set-conversion.cpp +++ b/base/dali-toolkit/public-api/text/character-set-conversion.cpp @@ -15,7 +15,7 @@ * */ -// FILE HEATHER +// FILE HEADER #include namespace Dali @@ -122,47 +122,51 @@ uint32_t Utf8ToUtf32( const uint8_t* const utf8, uint32_t length, uint32_t* utf3 for( ; begin < end ; ++numberOfCharacters ) { const uint8_t leadByte = *begin; + switch( UTF8_LENGTH[leadByte] ) { - case U1: - { - *utf32 = leadByte; - begin++; - break; - } - case U2: - { - uint32_t& code = *utf32; - code = leadByte & 0x1fu; - begin++; - code <<= 6u; - code |= *begin++ & 0x3fu; - break; - } - case U3: - { - uint32_t& code = *utf32; - code = leadByte & 0x1fu; - begin++; - code <<= 6u; - code |= *begin++ & 0x3fu; - code <<= 6u; - code |= *begin++ & 0x3fu; - break; - } - case U4: - { - uint32_t& code = *utf32; - code = leadByte & 0x1fu; - begin++; - code <<= 6u; - code |= *begin++ & 0x3fu; - code <<= 6u; - code |= *begin++ & 0x3fu; - code <<= 6u; - code |= *begin++ & 0x3fu; - break; - } + case U1: + { + *utf32++ = leadByte; + begin++; + break; + } + + case U2: + { + uint32_t& code = *utf32++; + code = leadByte & 0x1fu; + begin++; + code <<= 6u; + code |= *begin++ & 0x3fu; + break; + } + + case U3: + { + uint32_t& code = *utf32++; + code = leadByte & 0x1fu; + begin++; + code <<= 6u; + code |= *begin++ & 0x3fu; + code <<= 6u; + code |= *begin++ & 0x3fu; + break; + } + + case U4: + { + uint32_t& code = *utf32++; + code = leadByte & 0x1fu; + begin++; + code <<= 6u; + code |= *begin++ & 0x3fu; + code <<= 6u; + code |= *begin++ & 0x3fu; + code <<= 6u; + code |= *begin++ & 0x3fu; + break; + } } } diff --git a/base/dali-toolkit/public-api/text/logical-model.cpp b/base/dali-toolkit/public-api/text/logical-model.cpp index 6343e90..9008233 100644 --- a/base/dali-toolkit/public-api/text/logical-model.cpp +++ b/base/dali-toolkit/public-api/text/logical-model.cpp @@ -60,6 +60,7 @@ void LogicalModel::GetText( CharacterIndex characterIndex, Character* text, Leng LogicalModel::~LogicalModel() { + delete mImpl; } LogicalModel::LogicalModel() diff --git a/base/dali-toolkit/public-api/text/text-controller.cpp b/base/dali-toolkit/public-api/text/text-controller.cpp new file mode 100644 index 0000000..2c8ff38 --- /dev/null +++ b/base/dali-toolkit/public-api/text/text-controller.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +struct Controller::Impl +{ + Impl() + { + mLogicalModel = LogicalModel::New(); + mVisualModel = VisualModel::New(); + + mView.SetVisualModel( mVisualModel ); + + mFontClient = TextAbstraction::FontClient::Get(); + } + + LogicalModelPtr mLogicalModel; + VisualModelPtr mVisualModel; + + View mView; + + TextAbstraction::FontClient mFontClient; +}; + +ControllerPtr Controller::New() +{ + return ControllerPtr( new Controller() ); +} + +void Controller::SetText( const std::string& text ) +{ + // Convert text into UTF-32 + Vector utf32Characters; + utf32Characters.Resize( text.size() ); + + // This is a bit horrible but std::string returns a (signed) char* + const uint8_t* utf8 = reinterpret_cast( text.c_str() ); + + Length characterCount = Utf8ToUtf32( utf8, text.size(), &utf32Characters[0] ); + + // Manipulate the logical model + mImpl->mLogicalModel->SetText( &utf32Characters[0], characterCount ); + + UpdateVisualModel(); +} + +View& Controller::GetView() +{ + return mImpl->mView; +} + +Controller::~Controller() +{ + delete mImpl; +} + +Controller::Controller() +: mImpl( NULL ) +{ + mImpl = new Controller::Impl(); +} + +// TODO - Move this with LayoutEngine +void Controller::UpdateVisualModel() +{ + if( mImpl->mLogicalModel && + mImpl->mVisualModel ) + { + const LogicalModel& logicalModel = *(mImpl->mLogicalModel); + VisualModel& visualModel = *(mImpl->mVisualModel); + + TextAbstraction::FontId fontId = mImpl->mFontClient.GetFontId( "/usr/share/fonts/truetype/ubuntu-font-family/UbuntuMono-R.ttf", 13*64 ); + + const Length characterCount = logicalModel.GetNumberOfCharacters(); + + Vector glyphs; + glyphs.Reserve( characterCount ); + + Vector characterIndices; + characterIndices.Reserve( characterCount ); + + std::vector charactersPerGlyph; + charactersPerGlyph.assign( characterCount, 1 ); + + for( unsigned int i=0; imFontClient.GetGlyphIndex( fontId, charcode ); + + glyphs.PushBack( GlyphInfo(fontId, glyphIndex) ); + characterIndices.PushBack( 1 ); + } + + if( mImpl->mFontClient.GetGlyphMetrics( &glyphs[0], glyphs.Size() ) ) + { + visualModel.SetGlyphs( &glyphs[0], + &characterIndices[0], + &charactersPerGlyph[0], + characterCount ); + + UpdateVisualPositions(); + } + } +} + +// TODO - Move this with LayoutEngine +void Controller::UpdateVisualPositions() +{ + if( mImpl->mVisualModel ) + { + VisualModel& visualModel = *(mImpl->mVisualModel); + + Length glyphCount = visualModel.GetNumberOfGlyphs(); + + std::vector glyphPositions; + glyphPositions.reserve( glyphCount ); + + if( glyphCount > 0 ) + { + // FIXME Single font assumption + Text::FontMetrics fontMetrics; + GlyphInfo firstGlyph; + visualModel.GetGlyphs( 0, &firstGlyph, 1 ); + mImpl->mFontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics ); + + int penX( 0 ); + int penY( fontMetrics.ascender ); // Move to baseline + + for( unsigned int i=0; i 0 && + glyph.height > 0 ) // Skip whitespace + { + glyphPositions.push_back( Vector2( penX + glyph.xBearing, + penY - glyph.yBearing ) ); + } + + penX += glyph.advance; + } + + visualModel.SetGlyphPositions( &glyphPositions[0], glyphCount ); + } + } +} + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali diff --git a/base/dali-toolkit/public-api/text/text-controller.h b/base/dali-toolkit/public-api/text/text-controller.h new file mode 100644 index 0000000..c03b256 --- /dev/null +++ b/base/dali-toolkit/public-api/text/text-controller.h @@ -0,0 +1,111 @@ +#ifndef __DALI_TOOLKIT_TEXT_CONTROLLER_H__ +#define __DALI_TOOLKIT_TEXT_CONTROLLER_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +class Controller; +typedef IntrusivePtr ControllerPtr; + +/** + * @brief A Text Controller is used by UI Controls which display text. + * + * It manipulates the Logical & Visual text models on behalf of the UI Controls. + * It provides a view of the text that can be used by rendering back-ends. + */ +class Controller : public RefObject +{ +public: + + /** + * @brief Create a new instance of a Controller. + * + * @return A pointer to a new Controller. + */ + static ControllerPtr New(); + + // TODO - Layouting options e.g. single vs multi-line + + /** + * @brief Replaces any text previously set. + * + * @note This will be converted into UTF-32 when stored in the text model. + * @param[in] text A string of UTF-8 characters. + */ + void SetText( const std::string& text ); + + /** + * @brief Return a view of the text. + * + * @return An interface to the view. + */ + View& GetView(); + +protected: + + /** + * @brief A reference counted object may only be deleted by calling Unreference(). + */ + virtual ~Controller(); + +private: + + /** + * @brief Private constructor. + */ + Controller(); + + /** + * TODO - Move these with LayoutEngine + */ + void UpdateVisualModel(); + void UpdateVisualPositions(); + + // Undefined + Controller( const Controller& handle ); + + // Undefined + Controller& operator=( const Controller& handle ); + +private: + + struct Impl; + Impl* mImpl; +}; +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_TEXT_CONTROLLER_H__ diff --git a/base/dali-toolkit/public-api/text/text-definitions.h b/base/dali-toolkit/public-api/text/text-definitions.h index 554e370..d129c08 100644 --- a/base/dali-toolkit/public-api/text/text-definitions.h +++ b/base/dali-toolkit/public-api/text/text-definitions.h @@ -31,6 +31,7 @@ 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 diff --git a/base/dali-toolkit/public-api/text/text-view.cpp b/base/dali-toolkit/public-api/text/text-view.cpp index b91fce5..37dbbbb 100644 --- a/base/dali-toolkit/public-api/text/text-view.cpp +++ b/base/dali-toolkit/public-api/text/text-view.cpp @@ -35,9 +35,15 @@ struct View::Impl VisualModelPtr mVisualModel; }; -ViewPtr View::New() +View::View() +: mImpl( NULL ) { - return ViewPtr( new View() ); + mImpl = new View::Impl(); +} + +View::~View() +{ + delete mImpl; } void View::SetVisualModel( VisualModelPtr visualModel ) @@ -75,16 +81,6 @@ void View::GetGlyphPositions( GlyphIndex glyphIndex, } } -View::~View() -{ -} - -View::View() -: mImpl( NULL ) -{ - mImpl = new View::Impl(); -} - } // namespace Text } // namespace Toolkit diff --git a/base/dali-toolkit/public-api/text/text-view.h b/base/dali-toolkit/public-api/text/text-view.h index 35f52d1..81c63dd 100644 --- a/base/dali-toolkit/public-api/text/text-view.h +++ b/base/dali-toolkit/public-api/text/text-view.h @@ -18,10 +18,6 @@ * */ -// EXTERNAL INCLUDES -#include -#include - // INTERNAL INCLUDES #include #include @@ -37,22 +33,22 @@ namespace Toolkit namespace Text { -class View; -typedef IntrusivePtr ViewPtr; - /** * @brief View provides an interface between the Text layout engine and rendering back-end. */ -class View : public RefObject, public ViewInterface +class View : public ViewInterface { public: /** * @brief Create a new instance of a View. - * - * @return A pointer to a new View. */ - static ViewPtr New(); + View(); + + /** + * @brief Virtual destructor. + */ + virtual ~View(); /** * @brief Set the visual model. @@ -80,20 +76,8 @@ public: Vector2* glyphPositions, Length numberOfGlyphs ) const; -protected: - - /** - * @brief A reference counted object may only be deleted by calling Unreference(). - */ - virtual ~View(); - private: - /** - * @brief Private constructor. - */ - View(); - // Undefined View( const View& handle ); diff --git a/base/dali-toolkit/public-api/text/visual-model.cpp b/base/dali-toolkit/public-api/text/visual-model.cpp index 27ae89e..a8b0f79 100644 --- a/base/dali-toolkit/public-api/text/visual-model.cpp +++ b/base/dali-toolkit/public-api/text/visual-model.cpp @@ -120,6 +120,7 @@ void VisualModel::GetGlyphPositions( GlyphIndex glyphIndex, VisualModel::~VisualModel() { + delete mImpl; } VisualModel::VisualModel() diff --git a/optional/dali-toolkit/dali-toolkit.h b/optional/dali-toolkit/dali-toolkit.h index d5c0dd4..267e176 100644 --- a/optional/dali-toolkit/dali-toolkit.h +++ b/optional/dali-toolkit/dali-toolkit.h @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include -- 2.7.4