DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "verticalAlignment", STRING, VERTICAL_ALIGNMENT )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "textColor", VECTOR4, TEXT_COLOR )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderTextColor", VECTOR4, PLACEHOLDER_TEXT_COLOR )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputColor", VECTOR4, INPUT_COLOR )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadowOffset", VECTOR2, SHADOW_OFFSET )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadowColor", VECTOR4, SHADOW_COLOR )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "primaryCursorColor", VECTOR4, PRIMARY_CURSOR_COLOR )
if( impl.mController->GetTextColor() != textColor )
{
impl.mController->SetTextColor( textColor );
+ impl.mController->SetInputColor( textColor );
impl.mRenderer.Reset();
}
}
}
break;
}
+ case Toolkit::TextField::Property::INPUT_COLOR:
+ {
+ if( impl.mController )
+ {
+ const Vector4 inputColor = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a );
+
+ impl.mController->SetInputColor( inputColor );
+ }
+ break;
+ }
case Toolkit::TextField::Property::SHADOW_OFFSET:
{
if( impl.mController )
}
break;
}
+ case Toolkit::TextField::Property::INPUT_COLOR:
+ {
+ if( impl.mController )
+ {
+ value = impl.mController->GetInputColor();
+ }
+ break;
+ }
case Toolkit::TextField::Property::SHADOW_OFFSET:
{
if ( impl.mController )
$(toolkit_src_dir)/text/bidirectional-support.cpp \
$(toolkit_src_dir)/text/character-set-conversion.cpp \
$(toolkit_src_dir)/text/clipping/text-clipper.cpp \
+ $(toolkit_src_dir)/text/color-segmentation.cpp \
$(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-helper-functions.cpp \
$(toolkit_src_dir)/text/multi-language-support.cpp \
$(toolkit_src_dir)/text/segmentation.cpp \
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_COLOR_RUN_H__
+#define __DALI_TOOLKIT_TEXT_COLOR_RUN_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/vector4.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-run.h>
+#include <dali-toolkit/internal/text/glyph-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Run of characters with the same color.
+ */
+struct ColorRun
+{
+ CharacterRun characterRun; ///< The initial character index and the number of characters of the run.
+ Vector4 color; ///< The color of the characters.
+};
+
+struct ColorGlyphRun
+{
+ GlyphRun glyphRun; ///< The initial glyph index and the number of glyphs of the run.
+ Vector4 color; ///< The color of the glyphs.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_COLOR_RUN_H__
--- /dev/null
+/*
+ * 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 <dali-toolkit/internal/text/color-segmentation.h>
+
+// EXTERNAL INCLUDES
+
+// INTERNAL INCLUDES
+
+#include <iostream>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+void SetColorSegmentationInfo( const Vector<ColorRun>& characterColorRuns,
+ const Vector<GlyphIndex>& charactersToGlyph,
+ const Vector<Length>& glyphsPerCharacter,
+ Vector<ColorGlyphRun>& glyphColorRuns )
+{
+ const VectorBase::SizeType numberOfColorRuns = characterColorRuns.Count();
+
+ if( 0u == numberOfColorRuns )
+ {
+ // Nothing to do.
+ return;
+ }
+
+ // Resize the color runs for the glyphs.
+ glyphColorRuns.Resize( numberOfColorRuns );
+
+ // Get pointers to the buffers.
+ ColorGlyphRun* glyphColorRunsBuffer = glyphColorRuns.Begin();
+ const GlyphIndex* const charactersToGlyphBuffer = charactersToGlyph.Begin();
+ const Length* const glyphsPerCharacterBuffer = glyphsPerCharacter.Begin();
+
+ // Convert from characters to glyphs.
+ Length index = 0u;
+ for( Vector<ColorRun>::ConstIterator it = characterColorRuns.Begin(),
+ endIt = characterColorRuns.End();
+ it != endIt;
+ ++it, ++index )
+ {
+ const ColorRun& colorRun = *it;
+
+ if( 0u < colorRun.characterRun.numberOfCharacters )
+ {
+ // Get the next color glyph run.
+ ColorGlyphRun& colorGlyphRun = *( glyphColorRunsBuffer + index );
+ colorGlyphRun.color = colorRun.color;
+
+ // Convert the color run index from character to glyph.
+ colorGlyphRun.glyphRun.glyphIndex = *( charactersToGlyphBuffer + colorRun.characterRun.characterIndex );
+
+ // Get the index to the last character of the run.
+ const CharacterIndex lastIndex = colorRun.characterRun.characterIndex + colorRun.characterRun.numberOfCharacters - 1u;
+
+ // Calculate the number of glyphs.
+ colorGlyphRun.glyphRun.numberOfGlyphs = *( charactersToGlyphBuffer + lastIndex ) + *( glyphsPerCharacterBuffer + lastIndex ) - colorGlyphRun.glyphRun.glyphIndex;
+ }
+ }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_COLOR_SEGMENTATION_H__
+#define __DALI_TOOLKIT_TEXT_COLOR_SEGMENTATION_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/color-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+class LogicalModel;
+
+/**
+ * @brief Creates color glyph runs.
+ *
+ * @param[in] characterColorRuns The color runs in characters (set in the mark-up string).
+ * @param[in] charactersToGlyph Conversion table from characters to glyphs.
+ * @param[in] glyphsPerCharacter Table with the number of glyphs for each character.
+ * @param[out] glyphColorRuns The color runs in glyphs.
+ */
+void SetColorSegmentationInfo( const Vector<ColorRun>& characterColorRuns,
+ const Vector<GlyphIndex>& charactersToGlyph,
+ const Vector<Length>& glyphsPerCharacter,
+ Vector<ColorGlyphRun>& glyphColorRuns );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_COLOR_SEGMENTATION_H__
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_INPUT_STYLE_H__
+#define __DALI_TOOLKIT_TEXT_INPUT_STYLE_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/vector4.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * The input text's style.
+ */
+struct InputStyle
+{
+Vector4 textColor;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_INPUT_STYLE_H__
// CLASS HEADER
#include <dali-toolkit/internal/text/logical-model-impl.h>
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/input-style.h>
+#include <dali-toolkit/internal/text/text-style-run-container.h>
+
namespace Dali
{
return *( mVisualToLogicalMap.Begin() + visualCharacterIndex );
}
+void LogicalModel::UpdateTextStyleRuns( CharacterIndex index, int numberOfCharacters )
+{
+ const Length totalNumberOfCharacters = mText.Count();
+
+ // Process the color runs.
+ Vector<ColorRun> removedColorRuns;
+ UpdateCharacterRuns<ColorRun>( index,
+ numberOfCharacters,
+ totalNumberOfCharacters,
+ mColorRuns,
+ removedColorRuns );
+}
+
+void LogicalModel::RetrieveStyle( CharacterIndex index, InputStyle& style )
+{
+ unsigned int runIndex = 0u;
+ unsigned int lastRunIndex = 0u;
+ bool overriden = false;
+
+ // Set the text color.
+ for( Vector<ColorRun>::ConstIterator it = mColorRuns.Begin(),
+ endIt = mColorRuns.End();
+ it != endIt;
+ ++it, ++runIndex )
+ {
+ const ColorRun& colorRun = *it;
+
+ if( ( colorRun.characterRun.characterIndex <= index ) &&
+ ( index < colorRun.characterRun.characterIndex + colorRun.characterRun.numberOfCharacters ) )
+ {
+ lastRunIndex = runIndex;
+ overriden = true;
+ }
+ }
+
+ // Set the text's color if it's overriden.
+ if( overriden )
+ {
+ style.textColor = ( *( mColorRuns.Begin() + lastRunIndex ) ).color;
+ }
+
+ runIndex = 0u;
+ overriden = false;
+}
+
LogicalModel::~LogicalModel()
{
}
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/bidirectional-line-info-run.h>
#include <dali-toolkit/internal/text/bidirectional-paragraph-info-run.h>
+#include <dali-toolkit/internal/text/color-run.h>
#include <dali-toolkit/internal/text/font-run.h>
#include <dali-toolkit/internal/text/script-run.h>
class LogicalModel;
typedef IntrusivePtr<LogicalModel> LogicalModelPtr;
+struct InputStyle;
/**
* @brief A logical text model contains layout independent information.
*/
CharacterIndex GetLogicalCharacterIndex( CharacterIndex visualCharacterIndex ) const;
+ /**
+ * @brief Updates the text's style runs with the added or removed text.
+ *
+ * @param[in] index The character's index.
+ * @param[in] numberOfCharacters The number of characters added or removed. If the value is negative the characters are removed.
+ */
+ void UpdateTextStyleRuns( CharacterIndex index, int numberOfCharacters );
+
+ /**
+ * @brief Retrieves the text's style for the given character index.
+ *
+ * @param[in] index The character index.
+ * @param[out] style The text's style in the given style.
+ */
+ void RetrieveStyle( CharacterIndex index, InputStyle& style );
+
protected:
/**
Vector<Character> mText;
Vector<ScriptRun> mScriptRuns;
Vector<FontRun> mFontRuns;
+ Vector<ColorRun> mColorRuns;
Vector<LineBreakInfo> mLineBreakInfo;
Vector<WordBreakInfo> mWordBreakInfo;
Vector<BidirectionalParagraphInfoRun> mBidirectionalParagraphInfo;
--- /dev/null
+/*
+ * 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 <dali-toolkit/internal/text/markup-processor-color.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace
+{
+const std::string XHTML_VALUE_ATTRIBUTE("value");
+}
+
+void ProcessColorTag( const Tag& tag, ColorRun& colorRun )
+{
+ for( Vector<Attribute>::ConstIterator it = tag.attributes.Begin(),
+ endIt = tag.attributes.End();
+ it != endIt;
+ ++it )
+ {
+ const Attribute& attribute( *it );
+ if( TokenComparison( XHTML_VALUE_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) )
+ {
+ ColorStringToVector4( attribute.valueBuffer, attribute.valueLength, colorRun.color );
+ }
+ }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_COLOR_H__
+#define __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_COLOR_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct Tag;
+struct ColorRun;
+
+/**
+ * @brief Retrieves the color value from the tag and sets it to the color run.
+ *
+ * @param[in] tag The color tag and its attributes.
+ * @param[in,out] colorRun The color run.
+ */
+void ProcessColorTag( const Tag& tag, ColorRun& colorRun );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_COLOR_H__
// FILE HEADER
#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/constants.h>
+#include <stdlib.h>
+
namespace Dali
{
const char WHITE_SPACE = 0x20; // ASCII value of the white space.
const char LAST_UPPER_CASE = 0x5b; // ASCII value of the one after the last upper case character (Z).
const char TO_LOWER_CASE = 32; // Value to add to a upper case character to transform it into a lower case.
+
+const char WEB_COLOR_TOKEN( '#' );
+const char* const HEX_COLOR_TOKEN( "0x" );
+const char* const ALPHA_ONE( "FF" );
+
+const std::string BLACK_COLOR( "black" );
+const std::string WHITE_COLOR( "white" );
+const std::string RED_COLOR( "red" );
+const std::string GREEN_COLOR( "green" );
+const std::string BLUE_COLOR( "blue" );
+const std::string YELLOW_COLOR( "yellow" );
+const std::string MAGENTA_COLOR( "magenta" );
+const std::string CYAN_COLOR( "cyan" );
+const std::string TRANSPARENT_COLOR( "transparent" );
}
bool TokenComparison( const std::string& string1, const char* const stringBuffer2, Length length )
for( ; ( WHITE_SPACE >= *markupStringBuffer ) && ( markupStringBuffer < markupStringEndBuffer ); ++markupStringBuffer );
}
+unsigned int StringToHex( const char* const uintStr )
+{
+ return static_cast<unsigned int>( strtoul( uintStr, NULL, 16 ) );
+}
+
+void UintColorToVector4( unsigned int color, Vector4& retColor )
+{
+ retColor.a = static_cast<float>( ( color & 0xFF000000 ) >> 24u ) / 255.f;
+ retColor.r = static_cast<float>( ( color & 0x00FF0000 ) >> 16u ) / 255.f;
+ retColor.g = static_cast<float>( ( color & 0x0000FF00 ) >> 8u ) / 255.f;
+ retColor.b = static_cast<float>( color & 0x000000FF ) / 255.f;
+}
+
+void ColorStringToVector4( const char* const colorStr, Length length, Vector4& retColor )
+{
+ if( WEB_COLOR_TOKEN == *colorStr )
+ {
+ std::string webColor( colorStr + 1u, length - 1u );
+ if( 4u == length ) // 3 component web color #F00 (red)
+ {
+ webColor.insert( 2u, &( webColor[2] ), 1u );
+ webColor.insert( 1u, &( webColor[1] ), 1u );
+ webColor.insert( 0u, &( webColor[0] ), 1u );
+ webColor.insert( 0u, ALPHA_ONE );
+ }
+ else if( 7u == length ) // 6 component web color #FF0000 (red)
+ {
+ webColor.insert( 0u, ALPHA_ONE );
+ }
+
+ UintColorToVector4( StringToHex( webColor.c_str() ), retColor );
+ }
+ else if( TokenComparison( HEX_COLOR_TOKEN, colorStr, 2u ) )
+ {
+ UintColorToVector4( StringToHex( colorStr + 2u ), retColor );
+ }
+ else if( TokenComparison( BLACK_COLOR, colorStr, length ) )
+ {
+ retColor = Color::BLACK;
+ }
+ else if( TokenComparison( WHITE_COLOR, colorStr, length ) )
+ {
+ retColor = Color::WHITE;
+ }
+ else if( TokenComparison( RED_COLOR, colorStr, length ) )
+ {
+ retColor = Color::RED;
+ }
+ else if( TokenComparison( GREEN_COLOR, colorStr, length ) )
+ {
+ retColor = Color::GREEN;
+ }
+ else if( TokenComparison( BLUE_COLOR, colorStr, length ) )
+ {
+ retColor = Color::BLUE;
+ }
+ else if( TokenComparison( YELLOW_COLOR, colorStr, length ) )
+ {
+ retColor = Color::YELLOW;
+ }
+ else if( TokenComparison( MAGENTA_COLOR, colorStr, length ) )
+ {
+ retColor = Color::MAGENTA;
+ }
+ else if( TokenComparison( CYAN_COLOR, colorStr, length ) )
+ {
+ retColor = Color::CYAN;
+ }
+ else if( TokenComparison( TRANSPARENT_COLOR, colorStr, length ) )
+ {
+ retColor = Color::TRANSPARENT;
+ }
+}
+
} // namespace Text
} // namespace Toolkit
namespace Dali
{
+struct Vector4;
+
namespace Toolkit
{
void SkipWhiteSpace( const char*& markupStringBuffer,
const char* const markupStringEndBuffer );
+/**
+ * @brief Converts a string into an hexadecimal unsigned int.
+ *
+ * @param[in] uintStr An hexadecimal unsigned int packed inside a string.
+ *
+ * @return The hexadecimal value.
+ */
+unsigned int StringToHex( const char* const uintStr );
+
+/**
+ * @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.
+ * @param[out] retColor A Vector4 with the converted color.
+ */
+void UintColorToVector4( unsigned int color, Vector4& retColor );
+
+/**
+ * @brief Converts a color packed inside a string into an ARGB Vector4 color.
+ *
+ * The string color could be in hexadecimal ( 0xFF0000FF ), webcolor ( #0000FF or #00F ) or some constant values:
+ * black, white, red, green, blue, yellow, magenta, cyan, transparent.
+ *
+ * @param[in] colorStr A color packed inside a string.
+ * @param[in] length The length of the color string.
+ * @param[out] retColor A color packed inside a Vector4.
+ */
+void ColorStringToVector4( const char* const colorStr, Length length, Vector4& retColor );
+
} // namespace Text
} // namespace Toolkit
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/markup-processor-color.h>
#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
namespace Dali
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.
+
+/**
+ * @brief Struct used to retrieve the style runs from the mark-up string.
+ */
+struct StyleStack
+{
+ typedef VectorBase::SizeType RunIndex;
+
+ Vector<RunIndex> stack; ///< Use a vector as a style stack. Stores the indices pointing where the run is stored inside the logical model.
+ unsigned int topIndex; ///< Points the top of the stack.
+
+ StyleStack()
+ : stack(),
+ topIndex( 0u )
+ {
+ stack.Resize( DEFAULT_VECTOR_SIZE );
+ }
+
+ void Push( RunIndex index )
+ {
+ // Check if there is space inside the style stack.
+ const VectorBase::SizeType size = stack.Count();
+ if( topIndex >= size )
+ {
+ // Resize the style stack.
+ stack.Resize( 2u * size );
+ }
+
+ // Set the run index in the top of the stack.
+ *( stack.Begin() + topIndex ) = index;
+
+ // Reposition the pointer to the top of the stack.
+ ++topIndex;
+ }
+
+ RunIndex Pop()
+ {
+ // Pop the top of the stack.
+ --topIndex;
+ return *( stack.Begin() + topIndex );
+ }
+};
+
/**
* @brief Splits the tag string into the tag name and its attributes.
*
const Length markupStringSize = markupString.size();
markupProcessData.markupProcessedText.reserve( markupStringSize );
+ // Stores a struct with the index to the first character of the run, the type of run and its parameters.
+ StyleStack styleStack;
+
+ // Points the next free position in the vector of runs.
+ StyleStack::RunIndex colorRunIndex = 0u;
+
+ // Give an initial default value to the model's vectors.
+ markupProcessData.colorRuns.Reserve( DEFAULT_VECTOR_SIZE );
+
// Get the mark-up string buffer.
const char* markupStringBuffer = markupString.c_str();
const char* const markupStringEndBuffer = markupStringBuffer + markupStringSize;
if( !tag.isEndTag )
{
// Create a new color run.
+ ColorRun colorRun;
+ colorRun.characterRun.numberOfCharacters = 0u;
+
+ // Set the start character index.
+ colorRun.characterRun.characterIndex = characterIndex;
+
+ // Fill the run with the attributes.
+ ProcessColorTag( tag, colorRun );
+
+ // Push the color run in the logical model.
+ markupProcessData.colorRuns.PushBack( colorRun );
+
+ // Push the index of the run into the stack.
+ styleStack.Push( colorRunIndex );
+
+ // Point the next color run.
+ ++colorRunIndex;
}
else
{
// Pop the top of the stack and set the number of characters of the run.
+ ColorRun& colorRun = *( markupProcessData.colorRuns.Begin() + styleStack.Pop() );
+ colorRun.characterRun.numberOfCharacters = characterIndex - colorRun.characterRun.characterIndex;
}
} // <color></color>
else if( TokenComparison( XHTML_I_TAG, tag.buffer, tag.length ) )
}
// Resize the model's vectors.
+ if( 0u == colorRunIndex )
+ {
+ markupProcessData.colorRuns.Clear();
+ }
+ else
+ {
+ markupProcessData.colorRuns.Resize( colorRunIndex );
+ }
}
} // namespace Text
*/
// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
#include <string>
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/color-run.h>
+
namespace Dali
{
*/
struct MarkupProcessData
{
- MarkupProcessData()
- : markupProcessedText()
+ MarkupProcessData( Vector<ColorRun>& colorRuns )
+ : colorRuns( colorRuns ),
+ markupProcessedText()
{}
- std::string markupProcessedText;
+ Vector<ColorRun>& colorRuns;
+
+ std::string markupProcessedText;
};
/**
*
*/
-// CLASS HEADER
+// FILE HEADER
#include <dali-toolkit/internal/text/segmentation.h>
// EXTERNAL INCLUDES
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/bidirectional-support.h>
#include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/color-segmentation.h>
#include <dali-toolkit/internal/text/multi-language-support.h>
#include <dali-toolkit/internal/text/segmentation.h>
#include <dali-toolkit/internal/text/shaper.h>
mUpdateRightSelectionPosition( false ),
mScrollAfterUpdatePosition( false ),
mScrollAfterDelete( false ),
- mAllTextSelected( false )
+ mAllTextSelected( false ),
+ mUpdateInputStyle( false )
{
mImfManager = ImfManager::Get();
}
}
}
+ if( mEventData->mUpdateInputStyle )
+ {
+ // Set the default style first.
+ RetrieveDefaultInputStyle( mEventData->mInputStyle );
+
+ // Get the character index from the cursor index.
+ const CharacterIndex styleIndex = ( mEventData->mPrimaryCursorPosition > 0u ) ? mEventData->mPrimaryCursorPosition - 1u : 0u;
+
+ // Retrieve the style from the style runs stored in the logical model.
+ mLogicalModel->RetrieveStyle( styleIndex, mEventData->mInputStyle );
+
+ mEventData->mUpdateInputStyle = false;
+ }
+
mEventData->mEventQueue.clear();
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::ProcessInputEvents\n" );
}
}
+bool Controller::Impl::UpdateModelStyle( OperationsMask operationsRequired )
+{
+ bool updated = false;
+
+ if( COLOR & operationsRequired )
+ {
+ // Set the color runs in glyphs.
+ SetColorSegmentationInfo( mLogicalModel->mColorRuns,
+ mVisualModel->mCharactersToGlyph,
+ mVisualModel->mGlyphsPerCharacter,
+ mVisualModel->mColorRuns );
+
+ updated = true;
+ }
+
+ return updated;
+}
+
+void Controller::Impl::RetrieveDefaultInputStyle( InputStyle& inputStyle )
+{
+ // Set the default text's color.
+ inputStyle.textColor = mTextColor;
+}
+
void Controller::Impl::GetDefaultFonts( Vector<FontRun>& fonts, Length numberOfCharacters )
{
if( mFontDefaults )
}
mEventData->mUpdateCursorPosition = true;
+ mEventData->mUpdateInputStyle = true;
mEventData->mScrollAfterUpdatePosition = true;
}
mEventData->mUpdateCursorPosition = true;
mEventData->mScrollAfterUpdatePosition = true;
+ mEventData->mUpdateInputStyle = true;
// Notify the cursor position to the imf manager.
if( mEventData->mImfManager )
if( Event::GRAB_HANDLE_EVENT == event.type )
{
mEventData->mUpdateCursorPosition = true;
+ mEventData->mUpdateInputStyle = true;
if ( !IsClipboardEmpty() )
{
mEventData->mUpdateCursorPosition = mEventData->mPrimaryCursorPosition != handlePosition;
mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateCursorPosition;
mEventData->mPrimaryCursorPosition = handlePosition;
+ mEventData->mUpdateInputStyle = mEventData->mUpdateCursorPosition;
}
else if( leftSelectionHandleEvent || rightSelectionHandleEvent )
{
if( deleteAfterRetrieval ) // Only delete text if copied successfully
{
+ // Set as input style the style of the first deleted character.
+ mLogicalModel->RetrieveStyle( startOfSelectedText, mEventData->mInputStyle );
+
+ mLogicalModel->UpdateTextStyleRuns( startOfSelectedText, -static_cast<int>( lengthOfSelectedText ) );
+
// Delete text between handles
Vector<Character>& currentText = mLogicalModel->mText;
#include <dali/devel-api/text-abstraction/font-client.h>
// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/input-style.h>
#include <dali-toolkit/internal/text/layouts/layout-engine.h>
#include <dali-toolkit/internal/text/logical-model-impl.h>
#include <dali-toolkit/internal/text/text-controller.h>
*/
std::vector<Event> mEventQueue; ///< The queue of touch events etc.
+ InputStyle mInputStyle; ///< The style to be set to the new inputed text.
+
/**
* 0,0 means that the top-left corner of the layout matches the top-left corner of the UI control.
* Typically this will have a negative value with scrolling occurs.
bool mScrollAfterUpdatePosition : 1; ///< Whether to scroll after the cursor position is updated.
bool mScrollAfterDelete : 1; ///< Whether to scroll after delete characters.
bool mAllTextSelected : 1; ///< True if the selection handles are selecting all the text.
+ bool mUpdateInputStyle : 1; ///< Whether to update the input style after moving the cursor.
};
struct ModifyEvent
return !result; // // If NumberOfItems greater than 0, return false
}
+ /**
+ * @brief Updates the logical and visual models.
+ *
+ * When text or style changes the model is set with some operations pending.
+ * When i.e. the text's size or a relayout is required this method is called
+ * with a given @p operationsRequired parameter. The operations required are
+ * matched with the operations pending to perform the minimum number of operations.
+ *
+ * @param[in] operationsRequired The operations required.
+ */
void UpdateModel( OperationsMask operationsRequired );
+ /**
+ * @brief Updates the style runs in the visual model when the text's styles changes.
+ *
+ * @param[in] operationsRequired The operations required.
+ *
+ * @return @e true if the model has been modified.
+ */
+ bool UpdateModelStyle( OperationsMask operationsRequired );
+
+ /**
+ * @brief Retreieves the default style.
+ *
+ * @param[out] inputStyle The default style.
+ */
+ void RetrieveDefaultInputStyle( InputStyle& inputStyle );
+
/**
* @brief Retrieve the default fonts.
*
// Reset keyboard as text changed
mImpl->ResetImfManager();
- // Remove the previously set text
+ // Remove the previously set text and style.
ResetText();
+ // Remove the style.
+ ClearStyleData();
+
CharacterIndex lastCursorIndex = 0u;
if( mImpl->mEventData )
if( !text.empty() )
{
- MarkupProcessData markupProcessData;
+ MarkupProcessData markupProcessData( mImpl->mLogicalModel->mColorRuns );
Length textSize = 0u;
const uint8_t* utf8 = NULL;
if( ( cursorIndex + numberOfChars ) <= currentText.Count() )
{
+ // Update the input style and remove the text's style before removing the text.
+ if( mImpl->mEventData )
+ {
+ // Set first the default input style.
+ mImpl->RetrieveDefaultInputStyle( mImpl->mEventData->mInputStyle );
+
+ // Update the input style.
+ mImpl->mLogicalModel->RetrieveStyle( cursorIndex, mImpl->mEventData->mInputStyle );
+
+ // Remove the text's style before removing the text.
+ mImpl->mLogicalModel->UpdateTextStyleRuns( cursorIndex, -numberOfChars );
+ }
+
+ // Remove the characters.
Vector<Character>::Iterator first = currentText.Begin() + cursorIndex;
Vector<Character>::Iterator last = first + numberOfChars;
return mImpl->mVisualModel->GetUnderlineHeight();
}
+void Controller::SetInputColor( const Vector4& color )
+{
+ if( mImpl->mEventData )
+ {
+ mImpl->mEventData->mInputStyle.textColor = color;
+
+ if( EventData::SELECTING == mImpl->mEventData->mState )
+ {
+ const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition;
+
+ // Get start and end position of selection
+ const CharacterIndex startOfSelectedText = handlesCrossed ? mImpl->mEventData->mRightSelectionPosition : mImpl->mEventData->mLeftSelectionPosition;
+ const Length lengthOfSelectedText = ( handlesCrossed ? mImpl->mEventData->mLeftSelectionPosition : mImpl->mEventData->mRightSelectionPosition ) - startOfSelectedText;
+
+ // Add the color run.
+ const VectorBase::SizeType numberOfRuns = mImpl->mLogicalModel->mColorRuns.Count();
+ mImpl->mLogicalModel->mColorRuns.Resize( numberOfRuns + 1u );
+
+ ColorRun& colorRun = *( mImpl->mLogicalModel->mColorRuns.Begin() + numberOfRuns );
+ colorRun.color = color;
+ colorRun.characterRun.characterIndex = startOfSelectedText;
+ colorRun.characterRun.numberOfCharacters = lengthOfSelectedText;
+
+ // Request to relayout.
+ mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | COLOR );
+ mImpl->RequestRelayout();
+ }
+ }
+}
+
+const Vector4& Controller::GetInputColor() const
+{
+ if( mImpl->mEventData )
+ {
+ return mImpl->mEventData->mInputStyle.textColor;
+ }
+
+ // Return the default text's color if there is no EventData.
+ return mImpl->mTextColor;
+
+}
+
void Controller::SetEnableCursorBlink( bool enable )
{
DALI_ASSERT_DEBUG( NULL != mImpl->mEventData && "TextInput disabled" );
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "new size (previous size %f,%f)\n", mImpl->mVisualModel->mControlSize.width, mImpl->mVisualModel->mControlSize.height );
- // Operations that need to be done if the size changes.
+ // Layout operations that need to be done if the size changes.
mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
LAYOUT |
ALIGN |
mImpl->mVisualModel->mControlSize = size;
}
- // Make sure the model is up-to-date before layouting
+ // Whether there are modify events.
+ const bool isModifyEventsEmpty = 0u == mImpl->mModifyEvents.Count();
+
+ // Make sure the model is up-to-date before layouting.
ProcessModifyEvents();
mImpl->UpdateModel( mImpl->mOperationsPending );
+ // Style operations that need to be done if the text is modified.
+ if( !isModifyEventsEmpty )
+ {
+ mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
+ COLOR );
+ }
+
+ // Apply the style runs if text is modified.
+ bool updated = mImpl->UpdateModelStyle( mImpl->mOperationsPending );
+
+ // Layout the text.
Size layoutSize;
- bool updated = DoRelayout( mImpl->mVisualModel->mControlSize,
- mImpl->mOperationsPending,
- layoutSize );
+ updated = DoRelayout( mImpl->mVisualModel->mControlSize,
+ mImpl->mOperationsPending,
+ layoutSize ) || updated;
// Do not re-do any operation until something changes.
mImpl->mOperationsPending = NO_OPERATION;
// The cursor position.
CharacterIndex& cursorIndex = mImpl->mEventData->mPrimaryCursorPosition;
+ // Update the text's style.
+ if( mImpl->mEventData )
+ {
+ // Updates the text style runs.
+ mImpl->mLogicalModel->UpdateTextStyleRuns( cursorIndex, maxSizeOfNewText );
+
+ // Get the character index from the cursor index.
+ const CharacterIndex styleIndex = ( cursorIndex > 0u ) ? cursorIndex - 1u : 0u;
+
+ // Retrieve the text's style for the given index.
+ InputStyle style;
+ mImpl->mLogicalModel->RetrieveStyle( styleIndex, style );
+
+ // Whether to add a new text color run.
+ const bool addColorRun = style.textColor != mImpl->mEventData->mInputStyle.textColor;
+
+ // Add style runs.
+ if( addColorRun )
+ {
+ const VectorBase::SizeType numberOfRuns = mImpl->mLogicalModel->mColorRuns.Count();
+ mImpl->mLogicalModel->mColorRuns.Resize( numberOfRuns + 1u );
+
+ ColorRun& colorRun = *( mImpl->mLogicalModel->mColorRuns.Begin() + numberOfRuns );
+ colorRun.color = mImpl->mEventData->mInputStyle.textColor;
+ colorRun.characterRun.characterIndex = cursorIndex;
+ colorRun.characterRun.numberOfCharacters = maxSizeOfNewText;
+ }
+ }
+
// Insert at current cursor position.
Vector<Character>& modifyText = mImpl->mLogicalModel->mText;
mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
mImpl->mVisualModel->mGlyphPositions.Clear();
mImpl->mVisualModel->mLines.Clear();
+ mImpl->mVisualModel->mColorRuns.Clear();
mImpl->mVisualModel->ClearCaches();
}
mImpl->mVisualModel->ClearCaches();
}
+void Controller::ClearStyleData()
+{
+ mImpl->mLogicalModel->mColorRuns.Clear();
+}
+
Controller::Controller( ControlInterface& controlInterface )
: mImpl( NULL )
{
UPDATE_ACTUAL_SIZE = 0x0200,
REORDER = 0x0400,
ALIGN = 0x0800,
+ COLOR = 0x1000,
ALL_OPERATIONS = 0xFFFF
};
*/
float GetUnderlineHeight() const;
+ /**
+ * @brief Sets the input text's color.
+ *
+ * @param[in] color The input text's color.
+ */
+ void SetInputColor( const Vector4& color );
+
+ /**
+ * @brief Retrieves the input text's color.
+ *
+ * @return The input text's color.
+ */
+ const Vector4& GetInputColor() const;
+
/**
* @brief Called to enable/disable cursor blink.
*
*/
void ClearFontData();
+ /**
+ * @brief Helper to clear text's style data.
+ */
+ void ClearStyleData();
+
/**
* @brief Private constructor.
*/
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_STYLE_RUN_CONTAINER_H__
+#define __DALI_TOOLKIT_TEXT_STYLE_RUN_CONTAINER_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Updates the number of characters and the character index of the text's style runs.
+ *
+ * If the @p numberOfCharacters is a negative value, it means the number of characters that are removed starting from the @p index.
+ *
+ * It deletes runs if all their characters are removed.
+ *
+ * @param[in] index Index to the first character updated.
+ * @param[in] numberOfCharacters The number of characters to be updated.
+ * @param[in] totalNumberOfCharacters Total number of characters of the text.
+ * @param[in,out] runs The text's style runs.
+ * @param[out] removedRuns The text's style removed runs.
+ */
+template< typename T >
+void UpdateCharacterRuns( CharacterIndex index,
+ int numberOfCharacters,
+ Length totalNumberOfCharacters,
+ Vector<T>& runs,
+ Vector<T>& removedRuns )
+{
+ if( 0 > numberOfCharacters )
+ {
+ // Remove characters.
+ const Length numberOfRemovedCharacters = -numberOfCharacters;
+
+ if( ( 0u == index ) && ( numberOfRemovedCharacters == totalNumberOfCharacters ) )
+ {
+ // Set the removed runs.
+ removedRuns = runs;
+
+ // All characters are removed.
+ runs.Clear();
+
+ // Nothing else to do.
+ return;
+ }
+
+ const VectorBase::SizeType size = runs.Count();
+ // Temporary vector used to remove runs.
+ Vector<T> tempRuns;
+ // Reserve some space for the temporary vector.
+ tempRuns.Reserve( size );
+ removedRuns.Reserve( size );
+
+ // Whether any run has to be removed.
+ bool runsRemoved = false;
+
+ // Index to the last character added/removed.
+ const CharacterIndex lastIndex = index + numberOfRemovedCharacters - 1u;
+
+ // Update the style runs
+ for( typename Vector<T>::Iterator it = runs.Begin(),
+ endIt = runs.End();
+ it != endIt;
+ ++it )
+ {
+ T& run = *it;
+
+ const CharacterIndex lastRunIndex = run.characterRun.characterIndex + run.characterRun.numberOfCharacters - 1u;
+
+ if( lastRunIndex < index )
+ {
+ // The style run is not affected by the removed text.
+ tempRuns.PushBack( run );
+ continue;
+ }
+
+ if( ( index <= run.characterRun.characterIndex ) &&
+ ( lastIndex >= lastRunIndex ) )
+ {
+ // Add the removed run into the vector.
+ removedRuns.PushBack( run );
+
+ // All the characters are removed.
+ runsRemoved = true;
+ }
+ else
+ {
+ if( lastIndex < run.characterRun.characterIndex )
+ {
+ // Just move the character index.
+ run.characterRun.characterIndex -= numberOfRemovedCharacters;
+ }
+ else
+ {
+ if( run.characterRun.characterIndex < index )
+ {
+ // Remove characters starting from a character within the run.
+ run.characterRun.numberOfCharacters -= std::min( numberOfRemovedCharacters, 1u + lastRunIndex - index );
+ }
+ else
+ {
+ // Remove characters starting from a character located before the first index of the run.
+ run.characterRun.numberOfCharacters -= 1u + lastIndex - run.characterRun.characterIndex;
+ run.characterRun.characterIndex = index;
+ }
+ }
+
+ tempRuns.PushBack( run );
+ }
+ }
+
+ // Copy the temporary vector if there are runs removed.
+ if( runsRemoved )
+ {
+ runs = tempRuns;
+ }
+ }
+ else
+ {
+ // Add characters.
+
+ // Update the style runs
+ for( typename Vector<T>::Iterator it = runs.Begin(),
+ endIt = runs.End();
+ it != endIt;
+ ++it )
+ {
+ T& run = *it;
+
+ // Update the number of characters of the style run.
+
+ if( ( 0u == index ) && ( 0u == run.characterRun.characterIndex ) )
+ {
+ run.characterRun.numberOfCharacters += numberOfCharacters;
+ }
+ else if( index <= run.characterRun.characterIndex )
+ {
+ run.characterRun.characterIndex += numberOfCharacters;
+ }
+ else if( index <= run.characterRun.characterIndex + run.characterRun.numberOfCharacters )
+ {
+ run.characterRun.numberOfCharacters += numberOfCharacters;
+ }
+ }
+ }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_STYLE_RUN_CONTAINER_H__
glyphIndex,
numberOfLaidOutGlyphs );
+ // Set the colors.
+ const GlyphIndex lastLaidOutGlyphIndex = glyphIndex + numberOfLaidOutGlyphs;
+
+ for( Vector<ColorGlyphRun>::ConstIterator it = mImpl->mVisualModel->mColorRuns.Begin(),
+ endIt = mImpl->mVisualModel->mColorRuns.End();
+ it != endIt;
+ ++it )
+ {
+ const ColorGlyphRun& colorGlyphRun = *it;
+ const GlyphIndex lastGlyphIndex = colorGlyphRun.glyphRun.glyphIndex + colorGlyphRun.glyphRun.numberOfGlyphs;
+
+ if( ( colorGlyphRun.glyphRun.glyphIndex < lastLaidOutGlyphIndex ) &&
+ ( glyphIndex < lastGlyphIndex ) )
+ {
+ for( GlyphIndex index = glyphIndex < colorGlyphRun.glyphRun.glyphIndex ? colorGlyphRun.glyphRun.glyphIndex : glyphIndex,
+ endIndex = lastLaidOutGlyphIndex < lastGlyphIndex ? lastLaidOutGlyphIndex : lastGlyphIndex;
+ index < endIndex;
+ ++index )
+ {
+ *( glyphColors + index - glyphIndex ) = colorGlyphRun.color;
+ }
+ }
+ }
+
// Get the lines for the given range of glyphs.
// The lines contain the alignment offset which needs to be added to the glyph's position.
LineIndex firstLine = 0u;
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/line-run.h>
+#include <dali-toolkit/internal/text/color-run.h>
namespace Dali
{
Vector<Vector2> mGlyphPositions; ///< For each glyph, the position.
Vector<LineRun> mLines; ///< The laid out lines.
Vector<GlyphRun> mUnderlineRuns; ///< Runs of glyphs that are underlined.
+ Vector<ColorGlyphRun> mColorRuns; ///< Runs of glyphs with the same color.
Vector2 mControlSize; ///< The size of the UI control the decorator is adding it's decorations to.
Vector4 mTextColor; ///< The text color
VERTICAL_ALIGNMENT, ///< name "verticalAlignment", The line vertical alignment, type STRING, values "TOP", "CENTER", "BOTTOM"
TEXT_COLOR, ///< name "textColor", The text color, type VECTOR4
PLACEHOLDER_TEXT_COLOR, ///< name "placeholderTextColor", The placeholder-text color, type VECTOR4
+ INPUT_COLOR, ///< name "inputColor", The color of the new input text, type VECTOR4
SHADOW_OFFSET, ///< name "shadowOffset", The drop shadow offset 0 indicates no shadow, type VECTOR2
SHADOW_COLOR, ///< name "shadowColor", The color of a drop shadow, type VECTOR4
PRIMARY_CURSOR_COLOR, ///< name "primaryCursorColor", The color to apply to the primary cursor, type VECTOR4