From: Victor Cebollada Date: Wed, 25 Nov 2015 15:17:13 +0000 (+0000) Subject: Markup procesor - Font. X-Git-Tag: dali_1.1.17~3^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=4d763eb68b5aa2448dfc81d90fc5ce598c68c99f Markup procesor - Font. Signed-off-by: Victor Cebollada Change-Id: Icd3e97862b96f2631a17595136359a08fdfd2371 --- diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp index 8ad3b15..11a2af7 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp @@ -33,7 +33,11 @@ using namespace Text; // Tests the following functions with different scripts. // Constructor, destructor and MultilanguageSupport::Get() // void MultilanguageSupport::SetScripts( const Vector& text, const Vector& lineBreakInfo, Vector& scripts ); -// void MultilanguageSupport::ValidateFonts( const Vector& text, const Vector& scripts, Vector& fonts ); +// void MultilanguageSupport::ValidateFonts( const Vector& text, +// const Vector& scripts, +// const Vector& fontDescriptions, +// FontId defaultFontId, +// Vector& fonts ); ////////////////////////////////////////////////////////// @@ -127,12 +131,17 @@ bool ValidateFontTest( const ValidateFontsData& data ) multilanguageSupport.SetScripts( utf32, scripts ); + // To be completed ... + Vector fontDescriptions; + FontId defaultFontId = 0u; Vector fonts; + // 3) Validate the fonts multilanguageSupport.ValidateFonts( utf32, scripts, + fontDescriptions, + defaultFontId, fonts ); - return true; } diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp index 9fe5e53..31e5126 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp @@ -76,6 +76,9 @@ const char* const PROPERTY_NAME_DECORATION_BOUNDING_BOX = "decorati const char* const PROPERTY_NAME_INPUT_METHOD_SETTINGS = "inputMethodSettings"; const char* const PROPERTY_NAME_INPUT_COLOR = "inputColor"; const char* const PROPERTY_NAME_ENABLE_MARKUP = "enableMarkup"; +const char* const PROPERTY_NAME_INPUT_FONT_FAMILY = "inputFontFamily"; +const char* const PROPERTY_NAME_INPUT_FONT_STYLE = "inputFontStyle"; +const char* const PROPERTY_NAME_INPUT_POINT_SIZE = "inputPointSize"; const int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND; @@ -266,6 +269,9 @@ int UtcDaliTextFieldGetPropertyP(void) DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_METHOD_SETTINGS ) == TextField::Property::INPUT_METHOD_SETTINGS ); DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_COLOR ) == TextField::Property::INPUT_COLOR ); DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_MARKUP ) == TextField::Property::ENABLE_MARKUP ); + DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_FONT_FAMILY ) == TextField::Property::INPUT_FONT_FAMILY ); + DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_FONT_STYLE ) == TextField::Property::INPUT_FONT_STYLE ); + DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_POINT_SIZE ) == TextField::Property::INPUT_POINT_SIZE ); END_TEST; } @@ -393,7 +399,7 @@ int UtcDaliTextFieldSetPropertyP(void) field.SetProperty( TextField::Property::DECORATION_BOUNDING_BOX, Rect( 0, 0, 1, 1 ) ); DALI_TEST_EQUALS( field.GetProperty >( TextField::Property::DECORATION_BOUNDING_BOX ), Rect( 0, 0, 1, 1 ), TEST_LOCATION ); - // Input color + // Check input color property. field.SetProperty( TextField::Property::INPUT_COLOR, Color::YELLOW ); DALI_TEST_EQUALS( field.GetProperty( TextField::Property::INPUT_COLOR ), Color::YELLOW, TEST_LOCATION ); @@ -402,6 +408,14 @@ int UtcDaliTextFieldSetPropertyP(void) field.SetProperty( TextField::Property::ENABLE_MARKUP, true ); DALI_TEST_CHECK( field.GetProperty( TextField::Property::ENABLE_MARKUP ) ); + // Check input font properties. + field.SetProperty( TextField::Property::INPUT_FONT_FAMILY, "Setting input font family" ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::INPUT_FONT_FAMILY ), "Setting input font family", TEST_LOCATION ); + field.SetProperty( TextField::Property::INPUT_FONT_STYLE, "Setting input font style" ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::INPUT_FONT_STYLE ), "Setting input font style", TEST_LOCATION ); + field.SetProperty( TextField::Property::INPUT_POINT_SIZE, 12.f ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::INPUT_POINT_SIZE ), 12.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + END_TEST; } diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 8b7ea1d..a0417df 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -30,8 +30,8 @@ // INTERNAL INCLUDES #include #include -#include #include +#include #include #include @@ -120,6 +120,9 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "decorationBoundingBox", DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputMethodSettings", MAP, INPUT_METHOD_SETTINGS ) DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputColor", VECTOR4, INPUT_COLOR ) DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableMarkup", BOOLEAN, ENABLE_MARKUP ) +DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputFontFamily", STRING, INPUT_FONT_FAMILY ) +DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputFontStyle", STRING, INPUT_FONT_STYLE ) +DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputPointSize", FLOAT, INPUT_POINT_SIZE ) DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged", SIGNAL_TEXT_CHANGED ) DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED ) @@ -214,7 +217,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr } case Toolkit::TextField::Property::FONT_STYLE: { - SetFontStyleProperty( impl.mController, value ); + SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT ); break; } case Toolkit::TextField::Property::POINT_SIZE: @@ -578,6 +581,31 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr } break; } + case Toolkit::TextField::Property::INPUT_FONT_FAMILY: + { + if( impl.mController ) + { + const std::string fontFamily = value.Get< std::string >(); + DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() ); + impl.mController->SetInputFontFamily( fontFamily ); + } + break; + } + case Toolkit::TextField::Property::INPUT_FONT_STYLE: + { + SetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT ); + break; + } + case Toolkit::TextField::Property::INPUT_POINT_SIZE: + { + if( impl.mController ) + { + const float pointSize = value.Get< float >(); + DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize ); + impl.mController->SetInputFontPointSize( pointSize ); + } + break; + } } // switch } // textfield } @@ -640,7 +668,7 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde } case Toolkit::TextField::Property::FONT_STYLE: { - GetFontStyleProperty( impl.mController, value ); + GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT ); break; } case Toolkit::TextField::Property::POINT_SIZE: @@ -708,14 +736,6 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde } break; } - case Toolkit::TextField::Property::INPUT_COLOR: - { - if( impl.mController ) - { - value = impl.mController->GetInputColor(); - } - break; - } case Toolkit::TextField::Property::SHADOW_OFFSET: { if ( impl.mController ) @@ -869,6 +889,14 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde { break; } + case Toolkit::TextField::Property::INPUT_COLOR: + { + if( impl.mController ) + { + value = impl.mController->GetInputColor(); + } + break; + } case Toolkit::TextField::Property::ENABLE_MARKUP: { if( impl.mController ) @@ -877,6 +905,27 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde } break; } + case Toolkit::TextField::Property::INPUT_FONT_FAMILY: + { + if( impl.mController ) + { + value = impl.mController->GetInputFontFamily(); + } + break; + } + case Toolkit::TextField::Property::INPUT_FONT_STYLE: + { + GetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT ); + break; + } + case Toolkit::TextField::Property::INPUT_POINT_SIZE: + { + if( impl.mController ) + { + value = impl.mController->GetInputFontPointSize(); + } + break; + } } //switch } diff --git a/dali-toolkit/internal/controls/text-controls/text-font-style.cpp b/dali-toolkit/internal/controls/text-controls/text-font-style.cpp deleted file mode 100644 index 2c29f68..0000000 --- a/dali-toolkit/internal/controls/text-controls/text-font-style.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* - * 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. - * - */ - -// FILE HEADER -#include - -// INTERNAL INCLUDES -#include -#include - -namespace Dali -{ - -namespace Toolkit -{ - -namespace Text -{ - -namespace -{ -const std::string STYLE_KEY( "style" ); -const std::string WIDTH_KEY( "width" ); -const std::string WEIGHT_KEY( "weight" ); -const std::string SLANT_KEY( "slant" ); -const std::string EMPTY_STRING( "" ); - -} // namespace - -/** - * @brief Creates a map with pairs 'key,value' with the font's style parameters. - * - * @param[in] node Data structure with the font's style parameters. - * @param[out] map A map with the font's style parameters. - * - */ -void CreateFontStyleMap( const TreeNode* const node, Property::Map& map ) -{ - switch( node->GetType() ) - { - case TreeNode::IS_NULL: - case TreeNode::OBJECT: - case TreeNode::ARRAY: // FALL THROUGH - { - break; - } - case TreeNode::STRING: - { - map.Insert( node->GetName(), Property::Value( node->GetString() ) ); - break; - } - case TreeNode::INTEGER: - case TreeNode::FLOAT: - case TreeNode::BOOLEAN: // FALL THROUGH - { - break; - } - } - - for( TreeNode::ConstIterator it = node->CBegin(), endIt = node->CEnd(); it != endIt; ++it ) - { - const TreeNode::KeyNodePair& pair = *it; - CreateFontStyleMap( &pair.second, map ); - } -} - -/** - * @brief Parses the font's style string. - * - * @param[in] style The font's style string. - * @param[out] map A map with the font's style parameters. - * - */ -void ParseFontStyleString( const std::string& style, Property::Map& map ) -{ - Toolkit::JsonParser parser = Toolkit::JsonParser::New(); - - if( parser.Parse( style ) ) - { - const TreeNode* const node = parser.GetRoot(); - - CreateFontStyleMap( node, map ); - } -} - -void SetFontStyleProperty( ControllerPtr controller, const Property::Value& value ) -{ - if( controller ) - { - const std::string style = value.Get< std::string >(); - - // Stores the string to be recovered by the GetFontStyleProperty() function. - controller->SetDefaultFontStyle( style ); - - // Parses and applies the style. - Property::Map map; - ParseFontStyleString( style, map ); - - if( !map.Empty() ) - { - /// Width key - Property::Value* widthValue = map.Find( WIDTH_KEY ); - - if( widthValue ) - { - const std::string widthStr = widthValue->Get(); - - FontWidth width = TextAbstraction::FontWidth::NORMAL; - if( Scripting::GetEnumeration< FontWidth >( widthStr.c_str(), - FONT_WIDTH_STRING_TABLE, - FONT_WIDTH_STRING_TABLE_COUNT, - width ) ) - { - if( controller->GetDefaultFontWidth() != width ) - { - controller->SetDefaultFontWidth( width ); - } - } - } - else - { - controller->SetDefaultFontWidth( TextAbstraction::FontWidth::NORMAL ); - } - - /// Weight key - Property::Value* weightValue = map.Find( WEIGHT_KEY ); - - if( weightValue ) - { - const std::string weightStr = weightValue->Get(); - - FontWeight weight = TextAbstraction::FontWeight::NORMAL; - if( Scripting::GetEnumeration< FontWeight >( weightStr.c_str(), - FONT_WEIGHT_STRING_TABLE, - FONT_WEIGHT_STRING_TABLE_COUNT, - weight ) ) - { - if( controller->GetDefaultFontWeight() != weight ) - { - controller->SetDefaultFontWeight( weight ); - } - } - } - else - { - controller->SetDefaultFontWeight( TextAbstraction::FontWeight::NORMAL ); - } - - /// Slant key - Property::Value* slantValue = map.Find( SLANT_KEY ); - - if( slantValue ) - { - const std::string slantStr = slantValue->Get(); - - FontSlant slant = TextAbstraction::FontSlant::NORMAL; - if( Scripting::GetEnumeration< FontSlant >( slantStr.c_str(), - FONT_SLANT_STRING_TABLE, - FONT_SLANT_STRING_TABLE_COUNT, - slant ) ) - { - if( controller->GetDefaultFontSlant() != slant ) - { - controller->SetDefaultFontSlant( slant ); - } - } - } - else - { - controller->SetDefaultFontSlant( TextAbstraction::FontSlant::NORMAL ); - } - } - } -} - -void GetFontStyleProperty( ControllerPtr controller, Property::Value& value ) -{ - if( controller ) - { - value = controller->GetDefaultFontStyle(); - } -} - -} // namespace Text - -} // namespace Toolkit - -} // namespace Dali diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index 0094c9b..f717bbf 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -25,8 +25,8 @@ // INTERNAL INCLUDES #include #include -#include #include +#include #include #include @@ -156,7 +156,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr } case Toolkit::TextLabel::Property::FONT_STYLE: { - SetFontStyleProperty( impl.mController, value ); + SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT ); break; } case Toolkit::TextLabel::Property::POINT_SIZE: @@ -340,7 +340,7 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde } case Toolkit::TextLabel::Property::FONT_STYLE: { - GetFontStyleProperty( impl.mController, value ); + GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT ); break; } case Toolkit::TextLabel::Property::POINT_SIZE: diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 6a8f4dc..345c107 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -61,7 +61,6 @@ toolkit_src_files = \ $(toolkit_src_dir)/controls/super-blur-view/super-blur-view-impl.cpp \ $(toolkit_src_dir)/controls/table-view/table-view-impl.cpp \ $(toolkit_src_dir)/controls/text-controls/text-field-impl.cpp \ - $(toolkit_src_dir)/controls/text-controls/text-font-style.cpp \ $(toolkit_src_dir)/controls/text-controls/text-label-impl.cpp \ $(toolkit_src_dir)/controls/text-controls/text-selection-popup-impl.cpp \ $(toolkit_src_dir)/controls/text-controls/text-selection-toolbar-impl.cpp \ @@ -87,6 +86,7 @@ toolkit_src_files = \ $(toolkit_src_dir)/text/logical-model-impl.cpp \ $(toolkit_src_dir)/text/markup-processor.cpp \ $(toolkit_src_dir)/text/markup-processor-color.cpp \ + $(toolkit_src_dir)/text/markup-processor-font.cpp \ $(toolkit_src_dir)/text/markup-processor-helper-functions.cpp \ $(toolkit_src_dir)/text/multi-language-support.cpp \ $(toolkit_src_dir)/text/segmentation.cpp \ @@ -94,6 +94,7 @@ toolkit_src_files = \ $(toolkit_src_dir)/text/text-control-interface.cpp \ $(toolkit_src_dir)/text/text-controller.cpp \ $(toolkit_src_dir)/text/text-controller-impl.cpp \ + $(toolkit_src_dir)/text/text-font-style.cpp \ $(toolkit_src_dir)/text/text-io.cpp \ $(toolkit_src_dir)/text/text-view.cpp \ $(toolkit_src_dir)/text/text-view-interface.cpp \ diff --git a/dali-toolkit/internal/text/font-description-run.h b/dali-toolkit/internal/text/font-description-run.h new file mode 100644 index 0000000..ada640c --- /dev/null +++ b/dali-toolkit/internal/text/font-description-run.h @@ -0,0 +1,63 @@ +#ifndef __DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H__ +#define __DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H__ + +/* + * Copyright (c) 2016 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 + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +/** + * @brief Run of characters with the same font. + */ +struct FontDescriptionRun +{ + CharacterRun characterRun; ///< The initial character index and the number of characters of the run. + char* familyName; ///< The font's family name. + Length familyLength; ///< The length of the font's family name. + FontWeight weight; ///< The font's weight. + FontWidth width; ///< The font's width. + FontSlant slant; ///< The font's slant. + PointSize26Dot6 size; ///< The font's size. + + bool familyDefined : 1; ///< Whether the font's family is defined. + bool weightDefined : 1; ///< Whether the font's weight is defined. + bool widthDefined : 1; ///< Whether the font's width is defined. + bool slantDefined : 1; ///< Whether the font's slant is defined. + bool sizeDefined : 1; ///< Whether the font's size is defined. +}; + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H__ diff --git a/dali-toolkit/internal/text/font-run.h b/dali-toolkit/internal/text/font-run.h index 2a9680a..6027ef7 100644 --- a/dali-toolkit/internal/text/font-run.h +++ b/dali-toolkit/internal/text/font-run.h @@ -37,7 +37,6 @@ struct FontRun { CharacterRun characterRun; ///< The initial character index and the number of characters of the run. FontId fontId; ///< Font id of the run. - bool isDefault; ///< Whether the font is a default font not defined by the user. }; } // namespace Text diff --git a/dali-toolkit/internal/text/input-style.h b/dali-toolkit/internal/text/input-style.h index cd562ec..a9e6eab 100644 --- a/dali-toolkit/internal/text/input-style.h +++ b/dali-toolkit/internal/text/input-style.h @@ -21,6 +21,9 @@ // EXTERNAL INCLUDES #include +// INTERNAL INCLUDES +#include + namespace Dali { @@ -35,7 +38,37 @@ namespace Text */ struct InputStyle { -Vector4 textColor; + InputStyle() + : textColor( Color::BLACK ), + fontStyle(), + familyName(), + weight( TextAbstraction::FontWeight::NORMAL ), + width( TextAbstraction::FontWidth::NORMAL ), + slant( TextAbstraction::FontSlant::NORMAL ), + size( 0.f ), + familyDefined( false ), + weightDefined( false ), + widthDefined( false ), + slantDefined( false ), + sizeDefined( false ) + {} + + ~InputStyle() + {}; + + Vector4 textColor; ///< The text's color. + std::string fontStyle; ///< The font's style string. + std::string familyName; ///< The font's family name. + FontWeight weight; ///< The font's weight. + FontWidth width; ///< The font's width. + FontSlant slant; ///< The font's slant. + float size; ///< The font's size. + + bool familyDefined : 1; ///< Whether the font's family is defined. + bool weightDefined : 1; ///< Whether the font's weight is defined. + bool widthDefined : 1; ///< Whether the font's width is defined. + bool slantDefined : 1; ///< Whether the font's slant is defined. + bool sizeDefined : 1; ///< Whether the font's size is defined. }; } // namespace Text diff --git a/dali-toolkit/internal/text/logical-model-impl.cpp b/dali-toolkit/internal/text/logical-model-impl.cpp index bdbbbfe..d4a9d94 100644 --- a/dali-toolkit/internal/text/logical-model-impl.cpp +++ b/dali-toolkit/internal/text/logical-model-impl.cpp @@ -31,6 +31,19 @@ namespace Toolkit namespace Text { +void FreeFontFamilyNames( Vector& fontDescriptionRuns ) +{ + for( Vector::Iterator it = fontDescriptionRuns.Begin(), + endIt = fontDescriptionRuns.End(); + it != endIt; + ++it ) + { + delete (*it).familyName; + } + + fontDescriptionRuns.Clear(); +} + LogicalModelPtr LogicalModel::New() { return LogicalModelPtr( new LogicalModel() ); @@ -256,16 +269,28 @@ void LogicalModel::UpdateTextStyleRuns( CharacterIndex index, int numberOfCharac totalNumberOfCharacters, mColorRuns, removedColorRuns ); + + // Process the font description runs. + Vector removedFontDescriptionRuns; + UpdateCharacterRuns( index, + numberOfCharacters, + totalNumberOfCharacters, + mFontDescriptionRuns, + removedFontDescriptionRuns ); + + // Free memory allocated for the font family name. + FreeFontFamilyNames( removedFontDescriptionRuns ); } void LogicalModel::RetrieveStyle( CharacterIndex index, InputStyle& style ) { unsigned int runIndex = 0u; - unsigned int lastRunIndex = 0u; - bool overriden = false; // Set the text color. - for( Vector::ConstIterator it = mColorRuns.Begin(), + bool colorOverriden = false; + unsigned int colorIndex = 0u; + const ColorRun* const colorRunsBuffer = mColorRuns.Begin(); + for( Vector::ConstIterator it = colorRunsBuffer, endIt = mColorRuns.End(); it != endIt; ++it, ++runIndex ) @@ -275,20 +300,131 @@ void LogicalModel::RetrieveStyle( CharacterIndex index, InputStyle& style ) if( ( colorRun.characterRun.characterIndex <= index ) && ( index < colorRun.characterRun.characterIndex + colorRun.characterRun.numberOfCharacters ) ) { - lastRunIndex = runIndex; - overriden = true; + colorIndex = runIndex; + colorOverriden = true; } } // Set the text's color if it's overriden. - if( overriden ) + if( colorOverriden ) { - style.textColor = ( *( mColorRuns.Begin() + lastRunIndex ) ).color; + style.textColor = ( *( colorRunsBuffer + colorIndex ) ).color; } + + // Reset the run index. + runIndex = 0u; + + // Set the font's parameters. + bool nameOverriden = false; + bool weightOverriden = false; + bool widthOverriden = false; + bool slantOverriden = false; + bool sizeOverriden = false; + unsigned int nameIndex = 0u; + unsigned int weightIndex = 0u; + unsigned int widthIndex = 0u; + unsigned int slantIndex = 0u; + unsigned int sizeIndex = 0u; + const FontDescriptionRun* const fontDescriptionRunsBuffer = mFontDescriptionRuns.Begin(); + for( Vector::ConstIterator it = fontDescriptionRunsBuffer, + endIt = mFontDescriptionRuns.End(); + it != endIt; + ++it, ++runIndex ) + { + const FontDescriptionRun& fontDescriptionRun = *it; + + if( ( fontDescriptionRun.characterRun.characterIndex <= index ) && + ( index < fontDescriptionRun.characterRun.characterIndex + fontDescriptionRun.characterRun.numberOfCharacters ) ) + { + if( fontDescriptionRun.familyDefined ) + { + nameIndex = runIndex; + nameOverriden = true; + } + + if( fontDescriptionRun.weightDefined ) + { + weightIndex = runIndex; + weightOverriden = true; + } + + if( fontDescriptionRun.widthDefined ) + { + widthIndex = runIndex; + widthOverriden = true; + } + + if( fontDescriptionRun.slantDefined ) + { + slantIndex = runIndex; + slantOverriden = true; + } + + if( fontDescriptionRun.sizeDefined ) + { + sizeIndex = runIndex; + sizeOverriden = true; + } + } + } + + // Set the font's family name if it's overriden. + if( nameOverriden ) + { + const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + nameIndex ); + + style.familyName = std::string( fontDescriptionRun.familyName, fontDescriptionRun.familyLength ); + style.familyDefined = true; + } + + // Set the font's weight if it's overriden. + if( weightOverriden ) + { + const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + weightIndex ); + + style.weight = fontDescriptionRun.weight; + style.weightDefined = true; + } + + // Set the font's width if it's overriden. + if( widthOverriden ) + { + const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + widthIndex ); + + style.width = fontDescriptionRun.width; + style.widthDefined = true; + } + + // Set the font's slant if it's overriden. + if( slantOverriden ) + { + const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + slantIndex ); + + style.slant = fontDescriptionRun.slant; + style.slantDefined = true; + } + + // Set the font's size if it's overriden. + if( sizeOverriden ) + { + const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + sizeIndex ); + + style.size = static_cast( fontDescriptionRun.size ) / 64.f; + style.sizeDefined = true; + } + + // Reset the run index. + runIndex = 0u; +} + +void LogicalModel::ClearFontDescriptionRuns() +{ + FreeFontFamilyNames( mFontDescriptionRuns ); } LogicalModel::~LogicalModel() { + ClearFontDescriptionRuns(); } LogicalModel::LogicalModel() diff --git a/dali-toolkit/internal/text/logical-model-impl.h b/dali-toolkit/internal/text/logical-model-impl.h index 6842cf6..7a28ba6 100644 --- a/dali-toolkit/internal/text/logical-model-impl.h +++ b/dali-toolkit/internal/text/logical-model-impl.h @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace Dali @@ -124,6 +125,11 @@ public: */ void RetrieveStyle( CharacterIndex index, InputStyle& style ); + /** + * @brief Clears the font description runs. + */ + void ClearFontDescriptionRuns(); + protected: /** @@ -150,6 +156,7 @@ public: Vector mScriptRuns; Vector mFontRuns; Vector mColorRuns; + Vector mFontDescriptionRuns; Vector mLineBreakInfo; Vector mWordBreakInfo; Vector mBidirectionalParagraphInfo; diff --git a/dali-toolkit/internal/text/markup-processor-font.cpp b/dali-toolkit/internal/text/markup-processor-font.cpp new file mode 100644 index 0000000..b745317 --- /dev/null +++ b/dali-toolkit/internal/text/markup-processor-font.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016 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. + * + */ + +// FILE HEADER +#include + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +namespace +{ +const std::string XHTML_FAMILY_ATTRIBUTE("family"); +const std::string XHTML_SIZE_ATTRIBUTE("size"); +const std::string XHTML_WEIGHT_ATTRIBUTE("weight"); +const std::string XHTML_WIDTH_ATTRIBUTE("width"); +const std::string XHTML_SLANT_ATTRIBUTE("slant"); + +const unsigned int MAX_FONT_ATTRIBUTE_SIZE = 15u; ///< The maximum length of any of the possible 'weight', 'width' or 'slant' values. +} + +void ProcessFontTag( const Tag& tag, FontDescriptionRun& fontRun ) +{ + for( Vector::ConstIterator it = tag.attributes.Begin(), + endIt = tag.attributes.End(); + it != endIt; + ++it ) + { + const Attribute& attribute( *it ); + if( TokenComparison( XHTML_FAMILY_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) ) + { + fontRun.familyDefined = true; + fontRun.familyLength = attribute.valueLength; + fontRun.familyName = new char[fontRun.familyLength]; + memcpy( fontRun.familyName, attribute.valueBuffer, fontRun.familyLength ); + // The memory is freed when the font run is removed from the logical model. + } + else if( TokenComparison( XHTML_SIZE_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) ) + { + // 64.f is used to convert from point size to 26.6 pixel format. + fontRun.size = static_cast( StringToFloat( attribute.valueBuffer ) * 64.f ); + fontRun.sizeDefined = true; + } + else if( TokenComparison( XHTML_WEIGHT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) ) + { + // The StringToWeight() uses the Scripting::GetEnumeration() function which requires the input string to end with a '\0' char. + char value[MAX_FONT_ATTRIBUTE_SIZE+1u]; + const Length length = attribute.valueLength > MAX_FONT_ATTRIBUTE_SIZE ? MAX_FONT_ATTRIBUTE_SIZE : attribute.valueLength; + memcpy( value, attribute.valueBuffer, length ); + value[length] = 0; + + fontRun.weight = StringToWeight( value ); + fontRun.weightDefined = true; + } + else if( TokenComparison( XHTML_WIDTH_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) ) + { + // The StringToWidth() uses the Scripting::GetEnumeration() function which requires the input string to end with a '\0' char. + char value[MAX_FONT_ATTRIBUTE_SIZE+1u]; + const Length length = attribute.valueLength > MAX_FONT_ATTRIBUTE_SIZE ? MAX_FONT_ATTRIBUTE_SIZE : attribute.valueLength; + memcpy( value, attribute.valueBuffer, length ); + value[length] = 0; + + fontRun.width = StringToWidth( value ); + fontRun.widthDefined = true; + } + else if( TokenComparison( XHTML_SLANT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) ) + { + // The StringToSlant() uses the Scripting::GetEnumeration() function which requires the input string to end with a '\0' char. + char value[MAX_FONT_ATTRIBUTE_SIZE+1u]; + const Length length = attribute.valueLength > MAX_FONT_ATTRIBUTE_SIZE ? MAX_FONT_ATTRIBUTE_SIZE : attribute.valueLength; + memcpy( value, attribute.valueBuffer, length ); + value[length] = 0; + + fontRun.slant = StringToSlant( value ); + fontRun.slantDefined = true; + } + } +} + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/text/markup-processor-font.h b/dali-toolkit/internal/text/markup-processor-font.h new file mode 100644 index 0000000..c804011 --- /dev/null +++ b/dali-toolkit/internal/text/markup-processor-font.h @@ -0,0 +1,47 @@ +#ifndef __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_FONT_H__ +#define __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_FONT_H__ + +/* + * Copyright (c) 2016 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. + * + */ + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +struct Tag; +struct FontDescriptionRun; + +/** + * @brief Retrieves the font attributes from the tag and sets it to the font run. + * + * @param[in] tag The font tag and its attributes. + * @param[in,out] fontRun The font description run. + */ +void ProcessFontTag( const Tag& tag, FontDescriptionRun& fontRun ); + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_FONT_H__ diff --git a/dali-toolkit/internal/text/markup-processor-helper-functions.cpp b/dali-toolkit/internal/text/markup-processor-helper-functions.cpp index c460747..3c02c27 100644 --- a/dali-toolkit/internal/text/markup-processor-helper-functions.cpp +++ b/dali-toolkit/internal/text/markup-processor-helper-functions.cpp @@ -86,6 +86,11 @@ unsigned int StringToHex( const char* const uintStr ) return static_cast( strtoul( uintStr, NULL, 16 ) ); } +float StringToFloat( const char* const floatStr ) +{ + return static_cast( strtod( floatStr, NULL ) ); +} + void UintColorToVector4( unsigned int color, Vector4& retColor ) { retColor.a = static_cast( ( color & 0xFF000000 ) >> 24u ) / 255.f; diff --git a/dali-toolkit/internal/text/markup-processor-helper-functions.h b/dali-toolkit/internal/text/markup-processor-helper-functions.h index 5934467..62be6c8 100644 --- a/dali-toolkit/internal/text/markup-processor-helper-functions.h +++ b/dali-toolkit/internal/text/markup-processor-helper-functions.h @@ -94,6 +94,15 @@ void SkipWhiteSpace( const char*& markupStringBuffer, unsigned int StringToHex( const char* const uintStr ); /** + * @brief Converts a string into a float value. + * + * @param[in] floatStr A float packed inside a string. + * + * @return The float value. + */ +float StringToFloat( const char* const floatStr ); + +/** * @brief Converts an ARGB color packed in 4 byte unsigned int into a Vector4 color used in Dali. * * @param[in] color An ARGB color packed in an unsigned int. diff --git a/dali-toolkit/internal/text/markup-processor.cpp b/dali-toolkit/internal/text/markup-processor.cpp index 51a1efb..53ccf0b 100644 --- a/dali-toolkit/internal/text/markup-processor.cpp +++ b/dali-toolkit/internal/text/markup-processor.cpp @@ -21,6 +21,7 @@ // INTERNAL INCLUDES #include #include +#include #include namespace Dali @@ -58,7 +59,6 @@ const char BACK_SLASH = '\\'; const char WHITE_SPACE = 0x20; // ASCII value of the white space. const unsigned int MAX_NUM_OF_ATTRIBUTES = 5u; ///< The font tag has the 'family', 'size' 'weight', 'width' and 'slant' attrubutes. - const unsigned int DEFAULT_VECTOR_SIZE = 16u; ///< Default size of run vectors. /** @@ -347,9 +347,11 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma // Points the next free position in the vector of runs. StyleStack::RunIndex colorRunIndex = 0u; + StyleStack::RunIndex fontRunIndex = 0u; // Give an initial default value to the model's vectors. markupProcessData.colorRuns.Reserve( DEFAULT_VECTOR_SIZE ); + markupProcessData.fontRuns.Reserve( DEFAULT_VECTOR_SIZE ); // Get the mark-up string buffer. const char* markupStringBuffer = markupString.c_str(); @@ -398,10 +400,34 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma if( !tag.isEndTag ) { // Create a new font run. + FontDescriptionRun fontRun; + fontRun.characterRun.numberOfCharacters = 0u; + + // Fill the run with the parameters. + fontRun.characterRun.characterIndex = characterIndex; + fontRun.slant = TextAbstraction::FontSlant::ITALIC; + + fontRun.familyName = NULL; + fontRun.familyDefined = false; + fontRun.weightDefined = false; + fontRun.widthDefined = false; + fontRun.slantDefined = true; + fontRun.sizeDefined = false; + + // Push the font run in the logical model. + markupProcessData.fontRuns.PushBack( fontRun ); + + // Push the index of the run into the stack. + styleStack.Push( fontRunIndex ); + + // Point the next free font run. + ++fontRunIndex; } else { // Pop the top of the stack and set the number of characters of the run. + FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() ); + fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex; } } // else if( TokenComparison( XHTML_U_TAG, tag.buffer, tag.length ) ) @@ -420,10 +446,35 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma if( !tag.isEndTag ) { // Create a new font run. + FontDescriptionRun fontRun; + fontRun.characterRun.numberOfCharacters = 0u; + + // Fill the run with the parameters. + fontRun.characterRun.characterIndex = characterIndex; + + fontRun.weight = TextAbstraction::FontWeight::BOLD; + + fontRun.familyName = NULL; + fontRun.familyDefined = false; + fontRun.weightDefined = true; + fontRun.widthDefined = false; + fontRun.slantDefined = false; + fontRun.sizeDefined = false; + + // Push the font run in the logical model. + markupProcessData.fontRuns.PushBack( fontRun ); + + // Push the index of the run into the stack. + styleStack.Push( fontRunIndex ); + + // Point the next free font run. + ++fontRunIndex; } else { // Pop the top of the stack and set the number of characters of the run. + FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() ); + fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex; } } // else if( TokenComparison( XHTML_FONT_TAG, tag.buffer, tag.length ) ) @@ -431,10 +482,35 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma if( !tag.isEndTag ) { // Create a new font run. + FontDescriptionRun fontRun; + fontRun.characterRun.numberOfCharacters = 0u; + + // Fill the run with the parameters. + fontRun.characterRun.characterIndex = characterIndex; + + fontRun.familyName = NULL; + fontRun.familyDefined = false; + fontRun.weightDefined = false; + fontRun.widthDefined = false; + fontRun.slantDefined = false; + fontRun.sizeDefined = false; + + ProcessFontTag( tag, fontRun ); + + // Push the font run in the logical model. + markupProcessData.fontRuns.PushBack( fontRun ); + + // Push the index of the run into the stack. + styleStack.Push( fontRunIndex ); + + // Point the next free font run. + ++fontRunIndex; } else { // Pop the top of the stack and set the number of characters of the run. + FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() ); + fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex; } } // else if( TokenComparison( XHTML_SHADOW_TAG, tag.buffer, tag.length ) ) @@ -510,6 +586,15 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma } // Resize the model's vectors. + if( 0u == fontRunIndex ) + { + markupProcessData.fontRuns.Clear(); + } + else + { + markupProcessData.fontRuns.Resize( fontRunIndex ); + } + if( 0u == colorRunIndex ) { markupProcessData.colorRuns.Clear(); diff --git a/dali-toolkit/internal/text/markup-processor.h b/dali-toolkit/internal/text/markup-processor.h index 966622e..0c43300 100644 --- a/dali-toolkit/internal/text/markup-processor.h +++ b/dali-toolkit/internal/text/markup-processor.h @@ -24,6 +24,7 @@ // INTERNAL INCLUDES #include +#include namespace Dali { @@ -39,14 +40,17 @@ namespace Text */ struct MarkupProcessData { - MarkupProcessData( Vector& colorRuns ) +MarkupProcessData( Vector& colorRuns, + Vector& fontRuns ) : colorRuns( colorRuns ), + fontRuns( fontRuns ), markupProcessedText() {} - Vector& colorRuns; + Vector& colorRuns; ///< The color runs. + Vector& fontRuns; ///< The font description runs. - std::string markupProcessedText; + std::string markupProcessedText; ///< The mark-up string. }; /** diff --git a/dali-toolkit/internal/text/multi-language-support-impl.cpp b/dali-toolkit/internal/text/multi-language-support-impl.cpp index 37cf040..f37bdc2 100644 --- a/dali-toolkit/internal/text/multi-language-support-impl.cpp +++ b/dali-toolkit/internal/text/multi-language-support-impl.cpp @@ -45,40 +45,78 @@ namespace Internal { /** - * @brief Retrieves the font Id from the font run for a given character's @p index. + * @brief Merges the font descriptions to retrieve the font Id for each character. * - * If the character's index exceeds the current font run it increases the iterator to get the next one. - * - * @param[in] index The character's index. - * @param[in,out] fontRunIt Iterator to the current font run. - * @param[in] fontRunEndIt Iterator to one after the last font run. - * - * @return The font id. + * @param[in] fontDescriptions The font descriptions. + * @param[out] fontIds The font id for each character. + * @param[in] defaultFontDescription The default font description. + * @param[in] defaultPointSize The default font size. */ -FontId GetFontId( Length index, - Vector::ConstIterator& fontRunIt, - const Vector::ConstIterator& fontRunEndIt ) +void MergeFontDescriptions( const Vector& fontDescriptions, + Vector& fontIds, + const TextAbstraction::FontDescription& defaultFontDescription, + TextAbstraction::PointSize26Dot6 defaultPointSize ) { - FontId fontId = 0u; + // Get the handle to the font client. + TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); - if( fontRunIt != fontRunEndIt ) - { - const FontRun& fontRun = *fontRunIt; + // Pointer to the font id buffer. + FontId* fontIdsBuffer = fontIds.Begin(); - if( ( index >= fontRun.characterRun.characterIndex ) && - ( index < fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters ) ) + // Traverse all the characters. + const Length numberOfCharacters = fontIds.Count(); + for( CharacterIndex index = 0u; index < numberOfCharacters; ++index ) + { + // The default font description and font point size. + TextAbstraction::FontDescription fontDescription = defaultFontDescription; + TextAbstraction::PointSize26Dot6 fontSize = defaultPointSize; + bool defaultFont = true; + + // Traverse all the font descriptions. + for( Vector::ConstIterator it = fontDescriptions.Begin(), + endIt = fontDescriptions.End(); + it != endIt; + ++it ) { - fontId = fontRun.fontId; + // Check whether the character's font is modified by the current font description. + const FontDescriptionRun& fontRun = *it; + if( ( index >= fontRun.characterRun.characterIndex ) && + ( index < fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters ) ) + { + if( fontRun.familyDefined ) + { + fontDescription.family = std::string( fontRun.familyName, fontRun.familyLength ); + defaultFont = false; + } + if( fontRun.weightDefined ) + { + fontDescription.weight = fontRun.weight; + defaultFont = false; + } + if( fontRun.widthDefined ) + { + fontDescription.width = fontRun.width; + defaultFont = false; + } + if( fontRun.slantDefined ) + { + fontDescription.slant = fontRun.slant; + defaultFont = false; + } + if( fontRun.sizeDefined ) + { + fontSize = fontRun.size; + defaultFont = false; + } + } } - if( index + 1u == fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters ) + // Get the font id if is not the default font. + if( !defaultFont ) { - // All the characters of the current run have been traversed. Get the next one for the next iteration. - ++fontRunIt; + *( fontIdsBuffer + index ) = fontClient.GetFontId( fontDescription, fontSize ); } } - - return fontId; } /** @@ -349,8 +387,13 @@ void MultilanguageSupport::SetScripts( const Vector& text, void MultilanguageSupport::ValidateFonts( const Vector& text, const Vector& scripts, + const Vector& fontDescriptions, + FontId defaultFontId, Vector& fonts ) { + // Clear any previously validated font. + fonts.Clear(); + DALI_LOG_INFO( gLogFilter, Debug::General, "-->MultilanguageSupport::ValidateFonts\n" ); const Length numberOfCharacters = text.Count(); @@ -361,11 +404,6 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, return; } - // Copy the fonts set by application developers. - const Length numberOfFontRuns = fonts.Count(); - const Vector userSetFonts = fonts; - fonts.Clear(); - // Traverse the characters and validate/set the fonts. // Get the caches. @@ -373,33 +411,46 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, ValidateFontsPerScript** validFontsPerScriptCacheBuffer = mValidFontsPerScriptCache.Begin(); // Stores the validated font runs. - fonts.Reserve( numberOfFontRuns ); + fonts.Reserve( fontDescriptions.Count() ); // Initializes a validated font run. FontRun currentFontRun; currentFontRun.characterRun.characterIndex = 0u; currentFontRun.characterRun.numberOfCharacters = 0u; currentFontRun.fontId = 0u; - currentFontRun.isDefault = false; // Get the font client. TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); - // Iterators of the font and script runs. - Vector::ConstIterator fontRunIt = userSetFonts.Begin(); - Vector::ConstIterator fontRunEndIt = userSetFonts.End(); + // Get the default font description and default size. + TextAbstraction::FontDescription defaultFontDescription; + TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE; + if( defaultFontId > 0u ) + { + fontClient.GetDescription( defaultFontId, defaultFontDescription ); + defaultPointSize = fontClient.GetPointSize( defaultFontId ); + } + + // Merge font descriptions + Vector fontIds; + fontIds.Resize( numberOfCharacters, defaultFontId ); + MergeFontDescriptions( fontDescriptions, + fontIds, + defaultFontDescription, + defaultPointSize ); + + const Character* const textBuffer = text.Begin(); + const FontId* const fontIdsBuffer = fontIds.Begin(); Vector::ConstIterator scriptRunIt = scripts.Begin(); Vector::ConstIterator scriptRunEndIt = scripts.End(); for( Length index = 0u; index < numberOfCharacters; ++index ) { // Get the character. - const Character character = *( text.Begin() + index ); + const Character character = *( textBuffer + index ); // Get the font for the character. - FontId fontId = GetFontId( index, - fontRunIt, - fontRunEndIt ); + FontId fontId = *( fontIdsBuffer + index ); // Get the script for the character. Script script = GetScript( index, @@ -427,92 +478,77 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, } // Whether the font being validated is a default one not set by the user. - const bool isDefault = ( 0u == fontId ); FontId preferredFont = fontId; - DALI_LOG_INFO( gLogFilter, - Debug::Verbose, - " Is a default font : %s\n", - ( isDefault ? "true" : "false" ) ); + // Validate if the font set by the user supports the character. - // The default font point size. - PointSize26Dot6 pointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE; + // Check first in the caches. - if( !isDefault ) + // The user may have set the default font. Check it. Otherwise check in the valid fonts cache. + if( fontId != *( defaultFontPerScriptCacheBuffer + script ) ) { - // Validate if the font set by the user supports the character. - - // Check first in the caches. + // Check in the valid fonts cache. + ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script ); - // The user may have set the default font. Check it. Otherwise check in the valid fonts cache. - if( fontId != *( defaultFontPerScriptCacheBuffer + script ) ) + if( NULL == validateFontsPerScript ) { - // Check in the valid fonts cache. - ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script ); - - if( NULL == validateFontsPerScript ) - { - validateFontsPerScript = new ValidateFontsPerScript(); + validateFontsPerScript = new ValidateFontsPerScript(); - *( validFontsPerScriptCacheBuffer + script ) = validateFontsPerScript; - } + *( validFontsPerScriptCacheBuffer + script ) = validateFontsPerScript; + } - if( NULL != validateFontsPerScript ) + if( NULL != validateFontsPerScript ) + { + if( !validateFontsPerScript->FindValidFont( fontId ) ) { - if( !validateFontsPerScript->FindValidFont( fontId ) ) - { - // Use the font client to validate the font. - GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character ); + // Use the font client to validate the font. + GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character ); - // Emojis are present in many monochrome fonts; prefer color by default. - if( TextAbstraction::EMOJI == script && - 0u != glyphIndex ) + // Emojis are present in many monochrome fonts; prefer color by default. + if( ( TextAbstraction::EMOJI == script ) && + ( 0u != glyphIndex ) ) + { + BufferImage bitmap = fontClient.CreateBitmap( fontId, glyphIndex ); + if( bitmap && + ( Pixel::BGRA8888 != bitmap.GetPixelFormat() ) ) { - BufferImage bitmap = fontClient.CreateBitmap( fontId, glyphIndex ); - if( bitmap && - Pixel::BGRA8888 != bitmap.GetPixelFormat() ) - { - glyphIndex = 0; - } + glyphIndex = 0u; } + } - if( 0u == glyphIndex ) + if( 0u == glyphIndex ) + { + // The font is not valid. Set to zero and a default one will be set. + fontId = 0u; + } + else + { + // Add the font to the valid font cache. + + // At this point the validated font supports the given character. However, characters + // common for all scripts, like white spaces or new paragraph characters, need to be + // processed differently. + // + // i.e. A white space can have assigned a DEVANAGARI script but the font assigned may not + // support none of the DEVANAGARI glyphs. This font can't be added to the cache as a valid + // font for the DEVANAGARI script but the COMMON one. + if( TextAbstraction::IsCommonScript( character ) ) { - // Get the point size of the current font. It will be used to get a default font id. - pointSize = fontClient.GetPointSize( fontId ); + validateFontsPerScript = *( validFontsPerScriptCacheBuffer + TextAbstraction::COMMON ); - // The font is not valid. Set to zero and a default one will be set. - fontId = 0u; - } - else - { - // Add the font to the valid font cache. - - // At this point the validated font supports the given character. However, characters - // common for all scripts, like white spaces or new paragraph characters, need to be - // processed differently. - // - // i.e. A white space can have assigned a DEVANAGARI script but the font assigned may not - // support none of the DEVANAGARI glyphs. This font can't be added to the cache as a valid - // font for the DEVANAGARI script but the COMMON one. - if( TextAbstraction::IsCommonScript( character ) ) + if( NULL == validateFontsPerScript ) { - validateFontsPerScript = *( validFontsPerScriptCacheBuffer + TextAbstraction::COMMON ); - - if( NULL == validateFontsPerScript ) - { - validateFontsPerScript = new ValidateFontsPerScript(); + validateFontsPerScript = new ValidateFontsPerScript(); - *( validFontsPerScriptCacheBuffer + TextAbstraction::COMMON ) = validateFontsPerScript; - } + *( validFontsPerScriptCacheBuffer + TextAbstraction::COMMON ) = validateFontsPerScript; } - - validateFontsPerScript->mValidFonts.PushBack( fontId ); } + + validateFontsPerScript->mValidFonts.PushBack( fontId ); } } } - } // !isDefault + } // The font has not been validated. Find a default one. if( 0u == fontId ) @@ -527,7 +563,7 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, bool preferColor = ( TextAbstraction::EMOJI == script ); // Find a fallback-font. - fontId = fontClient.FindFallbackFont( preferredFont, character, pointSize, preferColor ); + fontId = fontClient.FindFallbackFont( preferredFont, character, defaultPointSize, preferColor ); // If the system does not support a suitable font, fallback to Latin if( 0u == fontId ) @@ -536,7 +572,7 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, } if( 0u == fontId ) { - fontId = fontClient.FindDefaultFont( UTF32_A, pointSize ); + fontId = fontClient.FindDefaultFont( UTF32_A, defaultPointSize ); } // Cache the font. @@ -559,8 +595,7 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, // The font is now validated. - if( ( fontId != currentFontRun.fontId ) || - ( isDefault != currentFontRun.isDefault ) ) + if( fontId != currentFontRun.fontId ) { // Current run needs to be stored and a new one initialized. @@ -574,7 +609,6 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, currentFontRun.characterRun.characterIndex = currentFontRun.characterRun.characterIndex + currentFontRun.characterRun.numberOfCharacters; currentFontRun.characterRun.numberOfCharacters = 0u; currentFontRun.fontId = fontId; - currentFontRun.isDefault = isDefault; } // Add one more character to the run. diff --git a/dali-toolkit/internal/text/multi-language-support-impl.h b/dali-toolkit/internal/text/multi-language-support-impl.h index 4dfc85c..e6105ac 100644 --- a/dali-toolkit/internal/text/multi-language-support-impl.h +++ b/dali-toolkit/internal/text/multi-language-support-impl.h @@ -97,10 +97,12 @@ public: Vector& scripts ); /** - * @copydoc Dali::MultilanguageSupport::ValidateFonts( const Vector& text, const Vector& scripts, Vector& fonts ) + * @copydoc Dali::MultilanguageSupport::ValidateFonts() */ void ValidateFonts( const Vector& text, const Vector& scripts, + const Vector& fontDescriptions, + FontId defaultFontId, Vector& fonts ); private: diff --git a/dali-toolkit/internal/text/multi-language-support.cpp b/dali-toolkit/internal/text/multi-language-support.cpp index 46d2cb5..87e594d 100644 --- a/dali-toolkit/internal/text/multi-language-support.cpp +++ b/dali-toolkit/internal/text/multi-language-support.cpp @@ -57,10 +57,14 @@ void MultilanguageSupport::SetScripts( const Vector& text, void MultilanguageSupport::ValidateFonts( const Vector& text, const Vector& scripts, + const Vector& fontDescriptions, + FontId defaultFontId, Vector& fonts ) { GetImplementation( *this ).ValidateFonts( text, scripts, + fontDescriptions, + defaultFontId, fonts ); } diff --git a/dali-toolkit/internal/text/multi-language-support.h b/dali-toolkit/internal/text/multi-language-support.h index 7e47fd2..bcbb130 100644 --- a/dali-toolkit/internal/text/multi-language-support.h +++ b/dali-toolkit/internal/text/multi-language-support.h @@ -24,6 +24,7 @@ // INTERNAL INCLUDES #include +#include #include namespace Dali @@ -97,8 +98,6 @@ public: /** * @brief Validates the character's font of the whole text. * - * It may update fonts set by application developers. - * * This method ensures all characters are going to be rendered using an appropriate font. Provided a valid font * exists in the platform. * @@ -109,10 +108,14 @@ public: * * @param[in] text Vector of UTF-32 characters. * @param[in] scripts Vector containing the script runs for the whole text. - * @param[in,out] fonts Initially contains the fonts set by the application developers. Returns the validated fonts. + * @param[in] fontDescriptions The fonts set by the application developers. + * @param[in] defaultFontId The default font's id. + * @param[out] fonts The validated fonts. */ void ValidateFonts( const Vector& text, const Vector& scripts, + const Vector& fontDescriptions, + FontId defaultFontId, Vector& fonts ); }; diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index a197d32..f85d410 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -368,17 +368,18 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired ) if( validateFonts ) { - if( 0u == validFonts.Count() ) - { - // Copy the requested font defaults received via the property system. - // These may not be valid i.e. may not contain glyphs for the necessary scripts. - GetDefaultFonts( validFonts, numberOfCharacters ); - } + // Validate the fonts set through the mark-up string. + Vector& fontDescriptionRuns = mLogicalModel->mFontDescriptionRuns; + + // Get the default font id. + const FontId defaultFontId = ( NULL == mFontDefaults ) ? 0u : mFontDefaults->GetFontId( mFontClient ); // 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, + fontDescriptionRuns, + defaultFontId, validFonts ); } } @@ -517,22 +518,37 @@ bool Controller::Impl::UpdateModelStyle( OperationsMask operationsRequired ) void Controller::Impl::RetrieveDefaultInputStyle( InputStyle& inputStyle ) { - // Set the default text's color. + // Sets the default text's color. inputStyle.textColor = mTextColor; -} -void Controller::Impl::GetDefaultFonts( Vector& fonts, Length numberOfCharacters ) -{ + // Sets the default font's family name, weight, width, slant and size. if( mFontDefaults ) { - DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::GetDefaultFonts font family(%s)\n", mFontDefaults->mFontDescription.family.c_str() ); - FontRun fontRun; - fontRun.characterRun.characterIndex = 0; - fontRun.characterRun.numberOfCharacters = numberOfCharacters; - fontRun.fontId = mFontDefaults->GetFontId( mFontClient ); - fontRun.isDefault = true; + inputStyle.familyName = mFontDefaults->mFontDescription.family; + inputStyle.weight = mFontDefaults->mFontDescription.weight; + inputStyle.width = mFontDefaults->mFontDescription.width; + inputStyle.slant = mFontDefaults->mFontDescription.slant; + inputStyle.size = mFontDefaults->mDefaultPointSize; - fonts.PushBack( fontRun ); + inputStyle.familyDefined = mFontDefaults->familyDefined; + inputStyle.weightDefined = mFontDefaults->weightDefined; + inputStyle.widthDefined = mFontDefaults->widthDefined; + inputStyle.slantDefined = mFontDefaults->slantDefined; + inputStyle.sizeDefined = mFontDefaults->sizeDefined; + } + else + { + inputStyle.familyName.clear(); + inputStyle.weight = TextAbstraction::FontWeight::NORMAL; + inputStyle.width = TextAbstraction::FontWidth::NORMAL; + inputStyle.slant = TextAbstraction::FontSlant::NORMAL; + inputStyle.size = 0.f; + + inputStyle.familyDefined = false; + inputStyle.weightDefined = false; + inputStyle.widthDefined = false; + inputStyle.slantDefined = false; + inputStyle.sizeDefined = false; } } @@ -1157,9 +1173,15 @@ void Controller::Impl::RepositionSelectionHandles() const Vector2 primaryPosition = primaryCursorInfo.primaryPosition + offset; const Vector2 secondaryPosition = secondaryCursorInfo.primaryPosition + offset; - mEventData->mDecorator->SetPosition( LEFT_SELECTION_HANDLE, primaryPosition.x, primaryPosition.y, primaryCursorInfo.lineHeight ); + mEventData->mDecorator->SetPosition( LEFT_SELECTION_HANDLE, + primaryPosition.x, + primaryCursorInfo.lineOffset + offset.y, + primaryCursorInfo.lineHeight ); - mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE, secondaryPosition.x, secondaryPosition.y, secondaryCursorInfo.lineHeight ); + mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE, + secondaryPosition.x, + secondaryCursorInfo.lineOffset + offset.y, + secondaryCursorInfo.lineHeight ); // Cursor to be positioned at end of selection so if selection interrupted and edit mode restarted the cursor will be at end of selection mEventData->mPrimaryCursorPosition = ( indicesSwapped ) ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition; @@ -1642,6 +1664,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, // If there is no font's family set, use the default font. // Use the current alignment to place the cursor at the beginning, center or end of the box. + cursorInfo.lineOffset = 0.f; cursorInfo.lineHeight = GetDefaultFontLineHeight(); cursorInfo.primaryCursorHeight = cursorInfo.lineHeight; @@ -1721,7 +1744,8 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, cursorInfo.isSecondaryCursor = ( !isLastPosition && ( isCurrentRightToLeft != isNextRightToLeft ) ) || ( isLastPosition && ( isRightToLeftParagraph != isCurrentRightToLeft ) ); - // Set the line height. + // Set the line offset and height. + cursorInfo.lineOffset = 0.f; cursorInfo.lineHeight = line.ascender + -line.descender; // Calculate the primary cursor. @@ -1934,7 +1958,7 @@ void Controller::Impl::UpdateCursorPosition( const CursorInfo& cursorInfo ) // Sets the grab handle position. mEventData->mDecorator->SetPosition( GRAB_HANDLE, cursorPosition.x, - cursorPosition.y, + cursorInfo.lineOffset + offset.y, cursorInfo.lineHeight ); if( cursorInfo.isSecondaryCursor ) @@ -1976,12 +2000,13 @@ void Controller::Impl::UpdateSelectionHandle( HandleType handleType, return; } - const Vector2 cursorPosition = cursorInfo.primaryPosition + mEventData->mScrollPosition + mAlignmentOffset; + const Vector2 offset = mEventData->mScrollPosition + mAlignmentOffset; + const Vector2 cursorPosition = cursorInfo.primaryPosition + offset; // Sets the handle's position. mEventData->mDecorator->SetPosition( handleType, cursorPosition.x, - cursorPosition.y, + cursorInfo.lineOffset + offset.y, cursorInfo.lineHeight ); // If selection handle at start of the text and other at end of the text then all text is selected. diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index 3ae0c7f..9ee83cc 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -81,6 +81,7 @@ struct CursorInfo CursorInfo() : primaryPosition(), secondaryPosition(), + lineOffset( 0.f ), lineHeight( 0.f ), primaryCursorHeight( 0.f ), secondaryCursorHeight( 0.f ), @@ -92,6 +93,7 @@ struct CursorInfo Vector2 primaryPosition; ///< The primary cursor's position. Vector2 secondaryPosition; ///< The secondary cursor's position. + float lineOffset; ///< The vertical offset where the line containing the cursor starts. float lineHeight; ///< The height of the line where the cursor is placed. float primaryCursorHeight; ///< The primary cursor's height. float secondaryCursorHeight; ///< The secondary cursor's height. @@ -187,7 +189,12 @@ struct FontDefaults : mFontDescription(), mFontStyle(), mDefaultPointSize( 0.f ), - mFontId( 0u ) + mFontId( 0u ), + familyDefined( false ), + weightDefined( false ), + widthDefined( false ), + slantDefined( false ), + sizeDefined( false ) { // Initially use the default platform font TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); @@ -205,10 +212,15 @@ struct FontDefaults return mFontId; } - TextAbstraction::FontDescription mFontDescription; - std::string mFontStyle; - float mDefaultPointSize; - FontId mFontId; + TextAbstraction::FontDescription mFontDescription; ///< The default font's description. + std::string mFontStyle; ///< The font's style string set through the property system. + float mDefaultPointSize; ///< The default font's point size. + FontId mFontId; ///< The font's id of the default font. + bool familyDefined:1; ///< Whether the default font's family name is defined. + bool weightDefined:1; ///< Whether the default font's weight is defined. + bool widthDefined:1; ///< Whether the default font's width is defined. + bool slantDefined:1; ///< Whether the default font's slant is defined. + bool sizeDefined:1; ///< Whether the default font's point size is defined. }; struct Controller::Impl @@ -230,7 +242,6 @@ struct Controller::Impl mOperationsPending( NO_OPERATION ), mMaximumNumberOfCharacters( 50u ), mRecalculateNaturalSize( true ), - mUserDefinedFontFamily( false ), mMarkupProcessorEnabled( false ) { mLogicalModel = LogicalModel::New(); @@ -388,14 +399,6 @@ struct Controller::Impl void RetrieveDefaultInputStyle( InputStyle& inputStyle ); /** - * @brief Retrieve the default fonts. - * - * @param[out] fonts The default font family, style and point sizes. - * @param[in] numberOfCharacters The number of characters in the logical model. - */ - void GetDefaultFonts( Dali::Vector& fonts, Length numberOfCharacters ); - - /** * @brief Retrieve the line height of the default font. */ float GetDefaultFontLineHeight(); @@ -542,7 +545,6 @@ struct Controller::Impl Length mMaximumNumberOfCharacters; ///< Maximum number of characters that can be inserted. bool mRecalculateNaturalSize:1; ///< Whether the natural size needs to be recalculated. - bool mUserDefinedFontFamily:1; ///< Whether the Font family was set by the user instead of being left as sytem default. bool mMarkupProcessorEnabled:1; ///< Whether the mark-up procesor is enabled. }; diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index f22278a..3143603 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -20,6 +20,7 @@ // EXTERNAL INCLUDES #include +#include #include #include #include @@ -61,6 +62,39 @@ namespace Toolkit namespace Text { +/** + * @brief Adds a new font description run for the selected text. + * + * The new font parameters are added after the call to this method. + * + * @param[in] eventData The event data pointer. + * @param[in] logicalModel The logical model where to add the new font description run. + */ +FontDescriptionRun& UpdateSelectionFontStyleRun( EventData* eventData, + LogicalModelPtr logicalModel ) +{ + const bool handlesCrossed = eventData->mLeftSelectionPosition > eventData->mRightSelectionPosition; + + // Get start and end position of selection + const CharacterIndex startOfSelectedText = handlesCrossed ? eventData->mRightSelectionPosition : eventData->mLeftSelectionPosition; + const Length lengthOfSelectedText = ( handlesCrossed ? eventData->mLeftSelectionPosition : eventData->mRightSelectionPosition ) - startOfSelectedText; + + // Add the font run. + const VectorBase::SizeType numberOfRuns = logicalModel->mFontDescriptionRuns.Count(); + logicalModel->mFontDescriptionRuns.Resize( numberOfRuns + 1u ); + + FontDescriptionRun& fontDescriptionRun = *( logicalModel->mFontDescriptionRuns.Begin() + numberOfRuns ); + + fontDescriptionRun.characterRun.characterIndex = startOfSelectedText; + fontDescriptionRun.characterRun.numberOfCharacters = lengthOfSelectedText; + + // Recalculate the selection highlight as the metrics may have changed. + eventData->mUpdateLeftSelectionPosition = true; + eventData->mUpdateRightSelectionPosition = true; + + return fontDescriptionRun; +} + ControllerPtr Controller::New( ControlInterface& controlInterface ) { return ControllerPtr( new Controller( controlInterface ) ); @@ -113,7 +147,8 @@ void Controller::SetText( const std::string& text ) if( !text.empty() ) { - MarkupProcessData markupProcessData( mImpl->mLogicalModel->mColorRuns ); + MarkupProcessData markupProcessData( mImpl->mLogicalModel->mColorRuns, + mImpl->mLogicalModel->mFontDescriptionRuns ); Length textSize = 0u; const uint8_t* utf8 = NULL; @@ -269,7 +304,7 @@ void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily ) mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily; DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str()); - mImpl->mUserDefinedFontFamily = true; + mImpl->mFontDefaults->familyDefined = true; // Clear the font-specific data ClearFontData(); @@ -310,14 +345,15 @@ const std::string& Controller::GetDefaultFontStyle() const return EMPTY_STRING; } -void Controller::SetDefaultFontWidth( FontWidth width ) +void Controller::SetDefaultFontWeight( FontWeight weight ) { if( NULL == mImpl->mFontDefaults ) { mImpl->mFontDefaults = new FontDefaults(); } - mImpl->mFontDefaults->mFontDescription.width = width; + mImpl->mFontDefaults->mFontDescription.weight = weight; + mImpl->mFontDefaults->weightDefined = true; // Clear the font-specific data ClearFontData(); @@ -328,24 +364,25 @@ void Controller::SetDefaultFontWidth( FontWidth width ) mImpl->RequestRelayout(); } -FontWidth Controller::GetDefaultFontWidth() const +FontWeight Controller::GetDefaultFontWeight() const { if( NULL != mImpl->mFontDefaults ) { - return mImpl->mFontDefaults->mFontDescription.width; + return mImpl->mFontDefaults->mFontDescription.weight; } - return TextAbstraction::FontWidth::NORMAL; + return TextAbstraction::FontWeight::NORMAL; } -void Controller::SetDefaultFontWeight( FontWeight weight ) +void Controller::SetDefaultFontWidth( FontWidth width ) { if( NULL == mImpl->mFontDefaults ) { mImpl->mFontDefaults = new FontDefaults(); } - mImpl->mFontDefaults->mFontDescription.weight = weight; + mImpl->mFontDefaults->mFontDescription.width = width; + mImpl->mFontDefaults->widthDefined = true; // Clear the font-specific data ClearFontData(); @@ -356,14 +393,14 @@ void Controller::SetDefaultFontWeight( FontWeight weight ) mImpl->RequestRelayout(); } -FontWeight Controller::GetDefaultFontWeight() const +FontWidth Controller::GetDefaultFontWidth() const { if( NULL != mImpl->mFontDefaults ) { - return mImpl->mFontDefaults->mFontDescription.weight; + return mImpl->mFontDefaults->mFontDescription.width; } - return TextAbstraction::FontWeight::NORMAL; + return TextAbstraction::FontWidth::NORMAL; } void Controller::SetDefaultFontSlant( FontSlant slant ) @@ -374,6 +411,7 @@ void Controller::SetDefaultFontSlant( FontSlant slant ) } mImpl->mFontDefaults->mFontDescription.slant = slant; + mImpl->mFontDefaults->slantDefined = true; // Clear the font-specific data ClearFontData(); @@ -402,6 +440,7 @@ void Controller::SetDefaultPointSize( float pointSize ) } mImpl->mFontDefaults->mDefaultPointSize = pointSize; + mImpl->mFontDefaults->sizeDefined = true; unsigned int horizontalDpi( 0u ); unsigned int verticalDpi( 0u ); @@ -435,7 +474,7 @@ void Controller::UpdateAfterFontChange( std::string& newDefaultFont ) { DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange"); - if( !mImpl->mUserDefinedFontFamily ) // If user defined font then should not update when system font changes + if( !mImpl->mFontDefaults->familyDefined ) // If user defined font then should not update when system font changes { DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str() ); ClearFontData(); @@ -651,6 +690,220 @@ const Vector4& Controller::GetInputColor() const } +void Controller::SetInputFontFamily( const std::string& fontFamily ) +{ + if( NULL != mImpl->mEventData ) + { + mImpl->mEventData->mInputStyle.familyName = fontFamily; + mImpl->mEventData->mInputStyle.familyDefined = true; + + if( EventData::SELECTING == mImpl->mEventData->mState ) + { + FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, + mImpl->mLogicalModel ); + + fontDescriptionRun.familyLength = fontFamily.size(); + fontDescriptionRun.familyName = new char[fontDescriptionRun.familyLength]; + memcpy( fontDescriptionRun.familyName, fontFamily.c_str(), fontDescriptionRun.familyLength ); + fontDescriptionRun.familyDefined = true; + + // The memory allocated for the font family name is freed when the font description is removed from the logical model. + + // Request to relayout. + mImpl->mOperationsPending = ALL_OPERATIONS; + mImpl->mRecalculateNaturalSize = true; + mImpl->RequestRelayout(); + + // As the font changes, recalculate the handle positions is needed. + mImpl->mEventData->mUpdateLeftSelectionPosition = true; + mImpl->mEventData->mUpdateRightSelectionPosition = true; + mImpl->mEventData->mScrollAfterUpdatePosition = true; + } + } +} + +const std::string& Controller::GetInputFontFamily() const +{ + if( NULL != mImpl->mEventData ) + { + return mImpl->mEventData->mInputStyle.familyName; + } + + // Return the default font's family if there is no EventData. + return GetDefaultFontFamily(); +} + +void Controller::SetInputFontStyle( const std::string& fontStyle ) +{ + if( NULL != mImpl->mEventData ) + { + mImpl->mEventData->mInputStyle.fontStyle = fontStyle; + } +} + +const std::string& Controller::GetInputFontStyle() const +{ + if( NULL != mImpl->mEventData ) + { + return mImpl->mEventData->mInputStyle.fontStyle; + } + + // Return the default font's style if there is no EventData. + return GetDefaultFontStyle(); +} + +void Controller::SetInputFontWeight( FontWeight weight ) +{ + if( NULL != mImpl->mEventData ) + { + mImpl->mEventData->mInputStyle.weight = weight; + mImpl->mEventData->mInputStyle.weightDefined = true; + + if( EventData::SELECTING == mImpl->mEventData->mState ) + { + FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, + mImpl->mLogicalModel ); + + fontDescriptionRun.weight = weight; + fontDescriptionRun.weightDefined = true; + + // Request to relayout. + mImpl->mOperationsPending = ALL_OPERATIONS; + mImpl->mRecalculateNaturalSize = true; + mImpl->RequestRelayout(); + + // As the font might change, recalculate the handle positions is needed. + mImpl->mEventData->mUpdateLeftSelectionPosition = true; + mImpl->mEventData->mUpdateRightSelectionPosition = true; + mImpl->mEventData->mScrollAfterUpdatePosition = true; + } + } +} + +FontWeight Controller::GetInputFontWeight() const +{ + if( NULL != mImpl->mEventData ) + { + return mImpl->mEventData->mInputStyle.weight; + } + + return GetDefaultFontWeight(); +} + +void Controller::SetInputFontWidth( FontWidth width ) +{ + if( NULL != mImpl->mEventData ) + { + mImpl->mEventData->mInputStyle.width = width; + mImpl->mEventData->mInputStyle.widthDefined = true; + + if( EventData::SELECTING == mImpl->mEventData->mState ) + { + FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, + mImpl->mLogicalModel ); + + fontDescriptionRun.width = width; + fontDescriptionRun.widthDefined = true; + + // Request to relayout. + mImpl->mOperationsPending = ALL_OPERATIONS; + mImpl->mRecalculateNaturalSize = true; + mImpl->RequestRelayout(); + + // As the font might change, recalculate the handle positions is needed. + mImpl->mEventData->mUpdateLeftSelectionPosition = true; + mImpl->mEventData->mUpdateRightSelectionPosition = true; + mImpl->mEventData->mScrollAfterUpdatePosition = true; + } + } +} + +FontWidth Controller::GetInputFontWidth() const +{ + if( NULL != mImpl->mEventData ) + { + return mImpl->mEventData->mInputStyle.width; + } + + return GetDefaultFontWidth(); +} + +void Controller::SetInputFontSlant( FontSlant slant ) +{ + if( NULL != mImpl->mEventData ) + { + mImpl->mEventData->mInputStyle.slant = slant; + mImpl->mEventData->mInputStyle.slantDefined = true; + + if( EventData::SELECTING == mImpl->mEventData->mState ) + { + FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, + mImpl->mLogicalModel ); + + fontDescriptionRun.slant = slant; + fontDescriptionRun.slantDefined = true; + + // Request to relayout. + mImpl->mOperationsPending = ALL_OPERATIONS; + mImpl->mRecalculateNaturalSize = true; + mImpl->RequestRelayout(); + + // As the font might change, recalculate the handle positions is needed. + mImpl->mEventData->mUpdateLeftSelectionPosition = true; + mImpl->mEventData->mUpdateRightSelectionPosition = true; + mImpl->mEventData->mScrollAfterUpdatePosition = true; + } + } +} + +FontSlant Controller::GetInputFontSlant() const +{ + if( NULL != mImpl->mEventData ) + { + return mImpl->mEventData->mInputStyle.slant; + } + + return GetDefaultFontSlant(); +} + +void Controller::SetInputFontPointSize( float size ) +{ + if( NULL != mImpl->mEventData ) + { + mImpl->mEventData->mInputStyle.size = size; + + if( EventData::SELECTING == mImpl->mEventData->mState ) + { + FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, + mImpl->mLogicalModel ); + + fontDescriptionRun.size = static_cast( size * 64.f ); + fontDescriptionRun.sizeDefined = true; + + // Request to relayout. + mImpl->mOperationsPending = ALL_OPERATIONS; + mImpl->mRecalculateNaturalSize = true; + mImpl->RequestRelayout(); + + // As the font might change, recalculate the handle positions is needed. + mImpl->mEventData->mUpdateLeftSelectionPosition = true; + mImpl->mEventData->mUpdateRightSelectionPosition = true; + mImpl->mEventData->mScrollAfterUpdatePosition = true; + } + } +} + +float Controller::GetInputFontPointSize() const +{ + if( NULL != mImpl->mEventData ) + { + return mImpl->mEventData->mInputStyle.size; + } + + // Return the default font's point size if there is no EventData. + return GetDefaultPointSize(); +} + void Controller::SetEnableCursorBlink( bool enable ) { DALI_ASSERT_DEBUG( NULL != mImpl->mEventData && "TextInput disabled" ); @@ -1564,7 +1817,9 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ // The cursor position. CharacterIndex& cursorIndex = mImpl->mEventData->mPrimaryCursorPosition; - // Updates the text style runs. + // Update the text's style. + + // Updates the text style runs by adding characters. mImpl->mLogicalModel->UpdateTextStyleRuns( cursorIndex, maxSizeOfNewText ); // Get the character index from the cursor index. @@ -1577,6 +1832,13 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ // Whether to add a new text color run. const bool addColorRun = style.textColor != mImpl->mEventData->mInputStyle.textColor; + // Whether to add a new font run. + const bool addFontNameRun = style.familyName != mImpl->mEventData->mInputStyle.familyName; + const bool addFontWeightRun = style.weight != mImpl->mEventData->mInputStyle.weight; + const bool addFontWidthRun = style.width != mImpl->mEventData->mInputStyle.width; + const bool addFontSlantRun = style.slant != mImpl->mEventData->mInputStyle.slant; + const bool addFontSizeRun = style.size != mImpl->mEventData->mInputStyle.size; + // Add style runs. if( addColorRun ) { @@ -1589,6 +1851,55 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ colorRun.characterRun.numberOfCharacters = maxSizeOfNewText; } + if( addFontNameRun || + addFontWeightRun || + addFontWidthRun || + addFontSlantRun || + addFontSizeRun ) + { + const VectorBase::SizeType numberOfRuns = mImpl->mLogicalModel->mFontDescriptionRuns.Count(); + mImpl->mLogicalModel->mFontDescriptionRuns.Resize( numberOfRuns + 1u ); + + FontDescriptionRun& fontDescriptionRun = *( mImpl->mLogicalModel->mFontDescriptionRuns.Begin() + numberOfRuns ); + + if( addFontNameRun ) + { + fontDescriptionRun.familyLength = mImpl->mEventData->mInputStyle.familyName.size(); + fontDescriptionRun.familyName = new char[fontDescriptionRun.familyLength]; + memcpy( fontDescriptionRun.familyName, mImpl->mEventData->mInputStyle.familyName.c_str(), fontDescriptionRun.familyLength ); + fontDescriptionRun.familyDefined = true; + + // The memory allocated for the font family name is freed when the font description is removed from the logical model. + } + + if( addFontWeightRun ) + { + fontDescriptionRun.weight = mImpl->mEventData->mInputStyle.weight; + fontDescriptionRun.weightDefined = true; + } + + if( addFontWidthRun ) + { + fontDescriptionRun.width = mImpl->mEventData->mInputStyle.width; + fontDescriptionRun.widthDefined = true; + } + + if( addFontSlantRun ) + { + fontDescriptionRun.slant = mImpl->mEventData->mInputStyle.slant; + fontDescriptionRun.slantDefined = true; + } + + if( addFontSizeRun ) + { + fontDescriptionRun.size = static_cast( mImpl->mEventData->mInputStyle.size * 64.f ); + fontDescriptionRun.sizeDefined = true; + } + + fontDescriptionRun.characterRun.characterIndex = cursorIndex; + fontDescriptionRun.characterRun.numberOfCharacters = maxSizeOfNewText; + } + // Insert at current cursor position. Vector& modifyText = mImpl->mLogicalModel->mText; @@ -2228,6 +2539,7 @@ void Controller::ClearFontData() void Controller::ClearStyleData() { mImpl->mLogicalModel->mColorRuns.Clear(); + mImpl->mLogicalModel->ClearFontDescriptionRuns(); } Controller::Controller( ControlInterface& controlInterface ) diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index 058719e..a9cc0df 100644 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -224,32 +224,32 @@ public: const std::string& GetDefaultFontStyle() const; /** - * @brief Sets the default font width. + * @brief Sets the default font weight. * - * @param[in] width The font width. + * @param[in] weight The font weight. */ - void SetDefaultFontWidth( FontWidth width ); + void SetDefaultFontWeight( FontWeight weight ); /** - * @brief Retrieves the default font width. + * @brief Retrieves the default font weight. * - * @return The default font width. + * @return The default font weight. */ - FontWidth GetDefaultFontWidth() const; + FontWeight GetDefaultFontWeight() const; /** - * @brief Sets the default font weight. + * @brief Sets the default font width. * - * @param[in] weight The font weight. + * @param[in] width The font width. */ - void SetDefaultFontWeight( FontWeight weight ); + void SetDefaultFontWidth( FontWidth width ); /** - * @brief Retrieves the default font weight. + * @brief Retrieves the default font width. * - * @return The default font weight. + * @return The default font width. */ - FontWeight GetDefaultFontWeight() const; + FontWidth GetDefaultFontWidth() const; /** * @brief Sets the default font slant. @@ -398,6 +398,90 @@ public: const Vector4& GetInputColor() const; /** + * @brief Sets the input text's font family name. + * + * @param[in] fontFamily The text's font family name. + */ + void SetInputFontFamily( const std::string& fontFamily ); + + /** + * @brief Retrieves the input text's font family name. + * + * @return The input text's font family name. + */ + const std::string& GetInputFontFamily() const; + + /** + * @brief Sets the input text's font style. + * + * @param[in] fontStyle The input text's font style. + */ + void SetInputFontStyle( const std::string& fontStyle ); + + /** + * @brief Retrieves the input text's font style. + * + * @return The input text's font style. + */ + const std::string& GetInputFontStyle() const; + + /** + * @brief Sets the input font's weight. + * + * @param[in] weight The input font's weight. + */ + void SetInputFontWeight( FontWeight weight ); + + /** + * @brief Retrieves the input font's weight. + * + * @return The input font's weight. + */ + FontWeight GetInputFontWeight() const; + + /** + * @brief Sets the input font's width. + * + * @param[in] width The input font's width. + */ + void SetInputFontWidth( FontWidth width ); + + /** + * @brief Retrieves the input font's width. + * + * @return The input font's width. + */ + FontWidth GetInputFontWidth() const; + + /** + * @brief Sets the input font's slant. + * + * @param[in] slant The input font's slant. + */ + void SetInputFontSlant( FontSlant slant ); + + /** + * @brief Retrieves the input font's slant. + * + * @return The input font's slant. + */ + FontSlant GetInputFontSlant() const; + + /** + * @brief Sets the input font's point size. + * + * @param[in] size The input font's point size. + */ + void SetInputFontPointSize( float size ); + + /** + * @brief Retrieves the input font's point size. + * + * @return The input font's point size. + */ + float GetInputFontPointSize() const; + + /** * @brief Called to enable/disable cursor blink. * * @note Only editable controls should calls this. diff --git a/dali-toolkit/internal/text/text-font-style.cpp b/dali-toolkit/internal/text/text-font-style.cpp new file mode 100644 index 0000000..681ffc7 --- /dev/null +++ b/dali-toolkit/internal/text/text-font-style.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2016 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. + * + */ + +// FILE HEADER +#include + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +namespace +{ +const std::string STYLE_KEY( "style" ); +const std::string WEIGHT_KEY( "weight" ); +const std::string WIDTH_KEY( "width" ); +const std::string SLANT_KEY( "slant" ); +const std::string EMPTY_STRING( "" ); + +#if defined(DEBUG_ENABLED) +Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS"); +#endif + +} // namespace + +/** + * @brief Creates a map with pairs 'key,value' with the font's style parameters. + * + * @param[in] node Data structure with the font's style parameters. + * @param[out] map A map with the font's style parameters. + * + */ +void CreateFontStyleMap( const TreeNode* const node, Property::Map& map ) +{ + switch( node->GetType() ) + { + case TreeNode::IS_NULL: + case TreeNode::OBJECT: + case TreeNode::ARRAY: // FALL THROUGH + { + break; + } + case TreeNode::STRING: + { + map.Insert( node->GetName(), Property::Value( node->GetString() ) ); + break; + } + case TreeNode::INTEGER: + case TreeNode::FLOAT: + case TreeNode::BOOLEAN: // FALL THROUGH + { + break; + } + } + + for( TreeNode::ConstIterator it = node->CBegin(), endIt = node->CEnd(); it != endIt; ++it ) + { + const TreeNode::KeyNodePair& pair = *it; + CreateFontStyleMap( &pair.second, map ); + } +} + +/** + * @brief Parses the font's style string. + * + * @param[in] style The font's style string. + * @param[out] map A map with the font's style parameters. + * + */ +void ParseFontStyleString( const std::string& style, Property::Map& map ) +{ + Toolkit::JsonParser parser = Toolkit::JsonParser::New(); + + if( parser.Parse( style ) ) + { + const TreeNode* const node = parser.GetRoot(); + + CreateFontStyleMap( node, map ); + } +} + +void SetFontStyleProperty( ControllerPtr controller, const Property::Value& value, FontStyle::Type type ) +{ + if( controller ) + { + const std::string style = value.Get< std::string >(); + DALI_LOG_INFO( gLogFilter, Debug::General, "Text Control %p FONT_STYLE %s\n", controller.Get(), style.c_str() ); + + switch( type ) + { + case FontStyle::DEFAULT: + { + // Stores the default font's style string to be recovered by the GetFontStyleProperty() function. + controller->SetDefaultFontStyle( style ); + break; + } + case FontStyle::INPUT: + { + // Stores the input font's style string to be recovered by the GetFontStyleProperty() function. + controller->SetInputFontStyle( style ); + break; + } + } + + // Parses and applies the style. + Property::Map map; + ParseFontStyleString( style, map ); + + if( !map.Empty() ) + { + /// Weight key + Property::Value* weightValue = map.Find( WEIGHT_KEY ); + + FontWeight weight = TextAbstraction::FontWeight::NORMAL; + const bool weightDefined = weightValue != NULL; + if( weightDefined ) + { + const std::string weightStr = weightValue->Get(); + + Scripting::GetEnumeration< FontWeight >( weightStr.c_str(), + FONT_WEIGHT_STRING_TABLE, + FONT_WEIGHT_STRING_TABLE_COUNT, + weight ); + } + + /// Width key + Property::Value* widthValue = map.Find( WIDTH_KEY ); + + FontWidth width = TextAbstraction::FontWidth::NORMAL; + const bool widthDefined = widthValue != NULL; + if( widthDefined ) + { + const std::string widthStr = widthValue->Get(); + + Scripting::GetEnumeration< FontWidth >( widthStr.c_str(), + FONT_WIDTH_STRING_TABLE, + FONT_WIDTH_STRING_TABLE_COUNT, + width ); + } + + /// Slant key + Property::Value* slantValue = map.Find( SLANT_KEY ); + + FontSlant slant = TextAbstraction::FontSlant::NORMAL; + const bool slantDefined = slantValue != NULL; + if( slantDefined ) + { + const std::string slantStr = slantValue->Get(); + + Scripting::GetEnumeration< FontSlant >( slantStr.c_str(), + FONT_SLANT_STRING_TABLE, + FONT_SLANT_STRING_TABLE_COUNT, + slant ); + } + + switch( type ) + { + case FontStyle::DEFAULT: + { + // Sets the default font's style values. + if( weightDefined && ( controller->GetDefaultFontWeight() != weight ) ) + { + controller->SetDefaultFontWeight( weight ); + } + + if( widthDefined && ( controller->GetDefaultFontWidth() != width ) ) + { + controller->SetDefaultFontWidth( width ); + } + + if( slantDefined && ( controller->GetDefaultFontSlant() != slant ) ) + { + controller->SetDefaultFontSlant( slant ); + } + break; + } + case FontStyle::INPUT: + { + // Sets the input font's style values. + if( weightDefined && ( controller->GetInputFontWeight() != weight ) ) + { + controller->SetInputFontWeight( weight ); + } + + if( widthDefined && ( controller->GetInputFontWidth() != width ) ) + { + controller->SetInputFontWidth( width ); + } + + if( slantDefined && ( controller->GetInputFontSlant() != slant ) ) + { + controller->SetInputFontSlant( slant ); + } + break; + } + } + } + } +} + +void GetFontStyleProperty( ControllerPtr controller, Property::Value& value, FontStyle::Type type ) +{ + if( controller ) + { + switch( type ) + { + case FontStyle::DEFAULT: + { + value = controller->GetDefaultFontStyle(); + break; + } + case FontStyle::INPUT: + { + value = controller->GetInputFontStyle(); + break; + } + } + } +} + +FontWeight StringToWeight( const char* const weightStr ) +{ + FontWeight weight = TextAbstraction::FontWeight::NORMAL; + Scripting::GetEnumeration( weightStr, + FONT_WEIGHT_STRING_TABLE, + FONT_WEIGHT_STRING_TABLE_COUNT, + weight ); + + return weight; +} + +FontWidth StringToWidth( const char* const widthStr ) +{ + FontWidth width = TextAbstraction::FontWidth::NORMAL; + Scripting::GetEnumeration( widthStr, + FONT_WIDTH_STRING_TABLE, + FONT_WIDTH_STRING_TABLE_COUNT, + width ); + + return width; +} + +FontSlant StringToSlant( const char* const slantStr ) +{ + FontSlant slant = TextAbstraction::FontSlant::NORMAL; + Scripting::GetEnumeration( slantStr, + FONT_SLANT_STRING_TABLE, + FONT_SLANT_STRING_TABLE_COUNT, + slant ); + + return slant; +} + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/controls/text-controls/text-font-style.h b/dali-toolkit/internal/text/text-font-style.h similarity index 79% rename from dali-toolkit/internal/controls/text-controls/text-font-style.h rename to dali-toolkit/internal/text/text-font-style.h index 68c230c..b87a8c9 100644 --- a/dali-toolkit/internal/controls/text-controls/text-font-style.h +++ b/dali-toolkit/internal/text/text-font-style.h @@ -2,7 +2,7 @@ #define __DALI_TOOLKIT_INTERNAL_TEXT_FONT_STYLE_H__ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -34,20 +34,6 @@ namespace Toolkit namespace Text { -const Scripting::StringEnum FONT_WIDTH_STRING_TABLE[] = -{ - { "ultraCondensed", TextAbstraction::FontWidth::ULTRA_CONDENSED }, - { "extraCondensed", TextAbstraction::FontWidth::EXTRA_CONDENSED }, - { "condensed", TextAbstraction::FontWidth::CONDENSED }, - { "semiCondensed", TextAbstraction::FontWidth::SEMI_CONDENSED }, - { "normal", TextAbstraction::FontWidth::NORMAL }, - { "semiExpanded", TextAbstraction::FontWidth::SEMI_EXPANDED }, - { "expanded", TextAbstraction::FontWidth::EXPANDED }, - { "extraExpanded", TextAbstraction::FontWidth::EXTRA_EXPANDED }, - { "ultraExpanded", TextAbstraction::FontWidth::ULTRA_EXPANDED }, -}; -const unsigned int FONT_WIDTH_STRING_TABLE_COUNT = sizeof( FONT_WIDTH_STRING_TABLE ) / sizeof( FONT_WIDTH_STRING_TABLE[0] ); - const Scripting::StringEnum FONT_WEIGHT_STRING_TABLE[] = { { "thin", TextAbstraction::FontWeight::THIN }, @@ -71,6 +57,20 @@ const Scripting::StringEnum FONT_WEIGHT_STRING_TABLE[] = }; const unsigned int FONT_WEIGHT_STRING_TABLE_COUNT = sizeof( FONT_WEIGHT_STRING_TABLE ) / sizeof( FONT_WEIGHT_STRING_TABLE[0] ); +const Scripting::StringEnum FONT_WIDTH_STRING_TABLE[] = +{ + { "ultraCondensed", TextAbstraction::FontWidth::ULTRA_CONDENSED }, + { "extraCondensed", TextAbstraction::FontWidth::EXTRA_CONDENSED }, + { "condensed", TextAbstraction::FontWidth::CONDENSED }, + { "semiCondensed", TextAbstraction::FontWidth::SEMI_CONDENSED }, + { "normal", TextAbstraction::FontWidth::NORMAL }, + { "semiExpanded", TextAbstraction::FontWidth::SEMI_EXPANDED }, + { "expanded", TextAbstraction::FontWidth::EXPANDED }, + { "extraExpanded", TextAbstraction::FontWidth::EXTRA_EXPANDED }, + { "ultraExpanded", TextAbstraction::FontWidth::ULTRA_EXPANDED }, +}; +const unsigned int FONT_WIDTH_STRING_TABLE_COUNT = sizeof( FONT_WIDTH_STRING_TABLE ) / sizeof( FONT_WIDTH_STRING_TABLE[0] ); + const Scripting::StringEnum FONT_SLANT_STRING_TABLE[] = { { "normal", TextAbstraction::FontSlant::NORMAL }, @@ -80,6 +80,15 @@ const Scripting::StringEnum FONT_SLANT_STRING_TABLE[] = }; const unsigned int FONT_SLANT_STRING_TABLE_COUNT = sizeof( FONT_SLANT_STRING_TABLE ) / sizeof( FONT_SLANT_STRING_TABLE[0] ); +namespace FontStyle +{ + enum Type + { + DEFAULT, ///< The default font's style. + INPUT ///< The input font's style. + }; +}; + /** * @brief Sets the font's style property. * @@ -87,7 +96,7 @@ const unsigned int FONT_SLANT_STRING_TABLE_COUNT = sizeof( FONT_SLANT_STRING_TAB * @param[in] value The value of the font's style. * */ -void SetFontStyleProperty( ControllerPtr controller, const Property::Value& value ); +void SetFontStyleProperty( ControllerPtr controller, const Property::Value& value, FontStyle::Type type ); /** * @brief Retrieves the font's style property. @@ -95,8 +104,34 @@ void SetFontStyleProperty( ControllerPtr controller, const Property::Value& valu * @param[in] controller The text's controller. * @param[out] value The value of the font's style. */ -void GetFontStyleProperty( ControllerPtr controller, Property::Value& value ); +void GetFontStyleProperty( ControllerPtr controller, Property::Value& value, FontStyle::Type type ); + +/** + * @brief Converts a weight string into @e FontWeight. + * + * @param[in] weightStr The weight string. Must end with '\0'. + * + * @return The @e FontWeight value corresponding to the string. + */ +FontWeight StringToWeight( const char* const weightStr ); +/** + * @brief Converts a width string into @e FontWidth. + * + * @param[in] widthStr The width string. Must end with '\0'. + * + * @return The @e FontWidth value corresponding to the string. + */ +FontWidth StringToWidth( const char* const widthStr ); + +/** + * @brief Converts a slant string into @e FontSlant. + * + * @param[in] slantStr The slant string. Must end with '\0'. + * + * @return The @e FontSlant value corresponding to the string. + */ +FontSlant StringToSlant( const char* const slantStr ); } // namespace Text } // namespace Toolkit diff --git a/dali-toolkit/public-api/controls/text-controls/text-field.h b/dali-toolkit/public-api/controls/text-controls/text-field.h index e222f99..f2205f5 100644 --- a/dali-toolkit/public-api/controls/text-controls/text-field.h +++ b/dali-toolkit/public-api/controls/text-controls/text-field.h @@ -101,7 +101,10 @@ public: DECORATION_BOUNDING_BOX, ///< name "decorationBoundingBox", The decorations (handles etc) will positioned within this area on-screen, type RECTANGLE INPUT_METHOD_SETTINGS, ///< name "inputMethodSettings", The settings to relating to the System's Input Method, Key and Value type MAP INPUT_COLOR, ///< name "inputColor", The color of the new input text, type VECTOR4 - ENABLE_MARKUP ///< name "enableMarkup", Whether the mark-up processing is enabled. type BOOLEAN + ENABLE_MARKUP, ///< name "enableMarkup", Whether the mark-up processing is enabled. type BOOLEAN + INPUT_FONT_FAMILY, ///< name "inputFontFamily", The font's family of the new input text, type STRING + INPUT_FONT_STYLE, ///< name "inputFontStyle", The font's style of the new input text, type STRING + INPUT_POINT_SIZE ///< name "inputPointSize", The font's size of the new input text in points, type FLOAT }; }; diff --git a/docs/content/shared-javascript-and-cpp-documentation/markup-style.md b/docs/content/shared-javascript-and-cpp-documentation/markup-style.md index 7c73868..dd40aa1 100644 --- a/docs/content/shared-javascript-and-cpp-documentation/markup-style.md +++ b/docs/content/shared-javascript-and-cpp-documentation/markup-style.md @@ -87,4 +87,28 @@ field.SetProperty( TextLabel::Property::TEXT, "Red TextRed Text"; // Color packed with the web color format (6 characters). ~~~ +## \ + +Sets the font values of the characters inside the tag. + +Supported attributes are: +- *family* The name of the font. +- *size* The size of the font in points. +- *weight* The weight of the font. +- *width* The width of the font +- *slant* The slant of the font. + +See the [Font Selection](@ref font-selection) to have a view of the possible values for the *weight*, *width* and *slant* attributes. + +~~~{.cpp} +// C++ +field.SetProperty( TextLabel::Property::TEXT, "Hello world" ); +~~~ + +~~~{.js} +// JavaScript + +field.text = "Hello world"; +~~~ + */ diff --git a/docs/content/shared-javascript-and-cpp-documentation/text-field.md b/docs/content/shared-javascript-and-cpp-documentation/text-field.md index dbe468f..c06c434 100644 --- a/docs/content/shared-javascript-and-cpp-documentation/text-field.md +++ b/docs/content/shared-javascript-and-cpp-documentation/text-field.md @@ -11,7 +11,7 @@ The Dali::Toolkit::TextField is a control which provides a single-line editable Before any text has been entered, the TextField can display some placeholder text. An alternative placeholder can be displayed when the TextField has keyboard focus. -For example a TextField used to enter a username could initially show "Unknown Name", and then show "Enter Name." when the cursor is shown. +For example a TextField used to enter a username could initially show "Unknown Name", and then show "Enter Name." when the cursor is shown. ~~~{.cpp} // C++ @@ -59,13 +59,16 @@ Mark-up tags can be used to change the style of the text. See the [Mark-up Style ### Input Style -The input style can be changed through the control properties. Current supported input style properties are: +The input style can be changed through the control properties. All subsequent characters added will be rendered with the new input style. -#### INPUT_COLOR +Note the input style may change if the cursor is updated by tapping in a new position. -Sets the input color. All subsequent characters added will be rendered with the input color. +Current supported input style properties are: -Note the input color may change if the cursor is updated by tapping in a new position. +- *INPUT_COLOR* Sets the input color. The property expects a Vector4 with the red, green, blue and alpha values clamped between 0 and 1. +- *INPUT_FONT_FAMILY* Sets the input font's family name. The property expects the name of the font. If the new text is not supported by the given font a suitable one will be set. +- *INPUT_FONT_STYLE* Sets the input font's style. The property expects a json formatted string with the font's style. See the [Font Selection](@ref font-selection) section for more details. +- *INPUT_POINT_SIZE* Sets the input font's size. The property expects a float with the font's size in points. See the [Font Selection](@ref font-selection) section for more details. ### Text Alignment @@ -167,6 +170,9 @@ field.placeholderTextColor = dali.COLOR_BLACK; inputMethodSettings | INPUT_METHOD_SETTINGS | MAP | O | X inputColor | INPUT_COLOR | VECTOR4 | O | X enableMarkup | ENABLE_MARKUP | BOOLEAN | O | X + inputFontFamily | INPUT_FONT_FAMILY | STRING | O | X + inputFontStyle | INPUT_FONT_STYLE | STRING | O | X + inputPointSize | INPUT_POINT_SIZE | FLOAT | O | X @class TextField