From e6119e0806fc7460e95d5569ff53fd1577214ae5 Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Fri, 6 Feb 2015 17:37:26 +0000 Subject: [PATCH 1/1] Methods to set/get font and script runs added to the text logical model. Change-Id: Icae1eccf8971d324143cc60a9c1b7ab47702f94e Signed-off-by: Victor Cebollada --- base/dali-toolkit/public-api/text/character-run.h | 48 ++++++ base/dali-toolkit/public-api/text/font-run.h | 49 ++++++ .../dali-toolkit/public-api/text/logical-model.cpp | 177 ++++++++++++++++++++- base/dali-toolkit/public-api/text/logical-model.h | 102 ++++++++++++ base/dali-toolkit/public-api/text/script-run.h | 48 ++++++ 5 files changed, 423 insertions(+), 1 deletion(-) create mode 100644 base/dali-toolkit/public-api/text/character-run.h create mode 100644 base/dali-toolkit/public-api/text/font-run.h create mode 100644 base/dali-toolkit/public-api/text/script-run.h diff --git a/base/dali-toolkit/public-api/text/character-run.h b/base/dali-toolkit/public-api/text/character-run.h new file mode 100644 index 0000000..b0d648e --- /dev/null +++ b/base/dali-toolkit/public-api/text/character-run.h @@ -0,0 +1,48 @@ +#ifndef __DALI_TOOLKIT_TEXT_CHARACTER_RUN_H__ +#define __DALI_TOOLKIT_TEXT_CHARACTER_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. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +/** + * @brief A run of consecutive characters. + */ +struct CharacterRun +{ + CharacterIndex characterIndex; ///< Index to the first character. + Length numberOfCharacters; ///< Number of characters in the run. +}; + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_TEXT_CHARACTER_RUN_H__ diff --git a/base/dali-toolkit/public-api/text/font-run.h b/base/dali-toolkit/public-api/text/font-run.h new file mode 100644 index 0000000..3a1d455 --- /dev/null +++ b/base/dali-toolkit/public-api/text/font-run.h @@ -0,0 +1,49 @@ +#ifndef __DALI_TOOLKIT_TEXT_FONT_RUN_H__ +#define __DALI_TOOLKIT_TEXT_FONT_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. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +/** + * @brief Run of characters with the same font. + */ +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 + +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_TEXT_FONT_RUN_H__ diff --git a/base/dali-toolkit/public-api/text/logical-model.cpp b/base/dali-toolkit/public-api/text/logical-model.cpp index 9008233..4547f99 100644 --- a/base/dali-toolkit/public-api/text/logical-model.cpp +++ b/base/dali-toolkit/public-api/text/logical-model.cpp @@ -18,8 +18,13 @@ // CLASS HEADER #include +// INTERNAL INCLUDES +#include +#include + // EXTERNAL INCLUDES -#include +#include +#include namespace Dali { @@ -33,6 +38,8 @@ namespace Text struct LogicalModel::Impl { Vector mText; + Vector mScriptRuns; + Vector mFontRuns; }; LogicalModelPtr LogicalModel::New() @@ -58,6 +65,174 @@ void LogicalModel::GetText( CharacterIndex characterIndex, Character* text, Leng memcpy( text, &modelText[characterIndex], numberOfCharacters*sizeof(Character) ); } +void LogicalModel::SetScripts( const ScriptRun* const scripts, + Length numberOfRuns ) +{ + Vector& scriptRuns = mImpl->mScriptRuns; + scriptRuns.Resize( numberOfRuns ); + memcpy( scriptRuns.Begin(), scripts, numberOfRuns * sizeof( ScriptRun ) ); +} + +Length LogicalModel::GetNumberOfScriptRuns( CharacterIndex characterIndex, + Length numberOfCharacters ) const +{ + if( ( 0u == characterIndex ) && ( mImpl->mText.Count() == numberOfCharacters ) ) + { + return mImpl->mScriptRuns.Count(); + } + + const CharacterIndex charcterEndIndex = characterIndex + numberOfCharacters; + Length numberOfScriptRuns = 0u; + bool firstIndexFound = false; + + for( Length index = 0u, length = mImpl->mScriptRuns.Count(); index < length; ++index ) + { + const ScriptRun* const scriptRun = mImpl->mScriptRuns.Begin() + index; + + if( !firstIndexFound && + ( characterIndex < scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters ) ) + { + // The character index is within this script run. + // Starts the counter of script runs. + firstIndexFound = true; + } + + if( firstIndexFound ) + { + ++numberOfScriptRuns; + if( scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters > charcterEndIndex ) + { + // This script run exceeds the given range. The number of scripts can be returned. + return numberOfScriptRuns; + } + } + } + + return numberOfScriptRuns; +} + +void LogicalModel::GetScriptRuns( ScriptRun* scriptRuns, + CharacterIndex characterIndex, + Length numberOfCharacters ) const +{ + // A better implementation can cache the first script run and the number of then when the GetNumberOfScriptRuns() is called. + + Length numberOfScriptRuns = GetNumberOfScriptRuns( characterIndex, + numberOfCharacters ); + + for( Length index = 0u, length = mImpl->mScriptRuns.Count(); index < length; ++index ) + { + const ScriptRun* const scriptRun = mImpl->mScriptRuns.Begin() + index; + + if( characterIndex < scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters ) + { + memcpy( scriptRuns, scriptRun, sizeof( ScriptRun ) * numberOfScriptRuns ); + return; + } + } +} + +Script LogicalModel::GetScript( CharacterIndex characterIndex ) const +{ + // If this operation is too slow, consider a binary search. + + for( Length index = 0u, length = mImpl->mScriptRuns.Count(); index < length; ++index ) + { + const ScriptRun* const scriptRun = mImpl->mScriptRuns.Begin() + index; + + if( ( scriptRun->characterRun.characterIndex <= characterIndex ) && + ( characterIndex < scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters ) ) + { + return scriptRun->script; + } + } + + return TextAbstraction::UNKNOWN; +} + +void LogicalModel::SetFonts( const FontRun* const fonts, + Length numberOfRuns ) +{ + Vector& fontRuns = mImpl->mFontRuns; + fontRuns.Resize( numberOfRuns ); + memcpy( fontRuns.Begin(), fonts, numberOfRuns * sizeof( FontRun ) ); +} + +Length LogicalModel::GetNumberOfFontRuns( CharacterIndex characterIndex, + Length numberOfCharacters ) const +{ + if( ( 0u == characterIndex ) && ( mImpl->mText.Count() == numberOfCharacters ) ) + { + return mImpl->mFontRuns.Count(); + } + + const CharacterIndex charcterEndIndex = characterIndex + numberOfCharacters; + Length numberOfFontRuns = 0u; + bool firstIndexFound = false; + + for( Length index = 0u, length = mImpl->mFontRuns.Count(); index < length; ++index ) + { + const FontRun* const fontRun = mImpl->mFontRuns.Begin() + index; + + if( !firstIndexFound && + ( characterIndex < fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters ) ) + { + // The character index is within this font run. + // Starts the counter of font runs. + firstIndexFound = true; + } + + if( firstIndexFound ) + { + ++numberOfFontRuns; + if( fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters > charcterEndIndex ) + { + // This font run exceeds the given range. The number of fonts can be returned. + return numberOfFontRuns; + } + } + } + + return numberOfFontRuns; +} + +void LogicalModel::GetFontRuns( FontRun* fontRuns, + CharacterIndex characterIndex, + Length numberOfCharacters ) const +{ + // A better implementation can cache the first font run and the number of then when the GetNumberOfFontRuns() is called. + + Length numberOfFontRuns = GetNumberOfFontRuns( characterIndex, + numberOfCharacters ); + + for( Length index = 0u, length = mImpl->mFontRuns.Count(); index < length; ++index ) + { + const FontRun* const fontRun = mImpl->mFontRuns.Begin() + index; + + if( characterIndex < fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters ) + { + memcpy( fontRuns, fontRun, sizeof( FontRun ) * numberOfFontRuns ); + return; + } + } +} + +FontId LogicalModel::GetFont( CharacterIndex characterIndex ) const +{ + for( Length index = 0u, length = mImpl->mFontRuns.Count(); index < length; ++index ) + { + const FontRun* const fontRun = mImpl->mFontRuns.Begin() + index; + + if( ( fontRun->characterRun.characterIndex <= characterIndex ) && + ( characterIndex < fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters ) ) + { + return fontRun->fontId; + } + } + + return 0u; +} + LogicalModel::~LogicalModel() { delete mImpl; diff --git a/base/dali-toolkit/public-api/text/logical-model.h b/base/dali-toolkit/public-api/text/logical-model.h index f62e6b2..d8f6617 100644 --- a/base/dali-toolkit/public-api/text/logical-model.h +++ b/base/dali-toolkit/public-api/text/logical-model.h @@ -33,8 +33,10 @@ namespace Toolkit namespace Text { +struct FontRun; class LogicalModel; typedef IntrusivePtr LogicalModelPtr; +struct ScriptRun; /** * @brief A logical text model contains layout independent information. @@ -83,6 +85,106 @@ public: Character* text, Length numberOfCharacters ) const; + // Language support interface. + + /** + * Sets the script runs. + * + * Replaces any scripts previously set. + * + * A run is a group of consecutive characters. A script run contains the script for a run. + * + * @param[in] scripts Pointer to a buffer with all the script runs. + * @param[in] numberOfRuns The number of script runs. + */ + void SetScripts( const ScriptRun* const scripts, + Length numberOfRuns ); + + /** + * Retrieves the number of script runs for the given range of characters. + * + * A run is a group of consecutive characters. A script run contains the script for a run. + * + * @param[in] characterIndex Index to the first character. + * @param[in] numberOfCharacters The number of characters. + * + * @return The number of script runs. + */ + Length GetNumberOfScriptRuns( CharacterIndex characterIndex, + Length numberOfCharacters ) const; + + /** + * Retrieves the script runs for the given range of characters. + * + * The @p scriptRuns buffer needs to be big enough to copy the number of script runs. + * Call GetNumberOfScriptRuns() to retrieve the number of script runs. + * + * @param[out] scriptRuns Pointer to a buffer where the script runs are copied. + * @param[in] characterIndex Index to the first character. + * @param[in] numberOfCharacters The number of characters. + */ + void GetScriptRuns( ScriptRun* scriptRuns, + CharacterIndex characterIndex, + Length numberOfCharacters ) const; + + /** + * Retrieves the script for the given character index. + * + * @param[in] characterIndex Index to the character. + * + * @return The character's script. + */ + Script GetScript( CharacterIndex characterIndex ) const; + + /** + * Sets the font runs. + * + * Replaces any fonts previously set. + * + * A run is a group of consecutive characters. A font run contains the font id for a run. + * + * @param[in] fonts Pointer to a buffer with all the font runs. + * @param[in] numberOfRuns The number of font runs. + */ + void SetFonts( const FontRun* const fonts, + Length numberOfRuns ); + + /** + * Retrieves the number of font runs for the given range of characters. + * + * A run is a group of consecutive characters. A font run contains the font id for a run. + * + * @param[in] characterIndex Index to the first character. + * @param[in] numberOfCharacters The number of characters. + * + * @return The number of font runs. + */ + Length GetNumberOfFontRuns( CharacterIndex characterIndex, + Length numberOfCharacters ) const; + + /** + * Retrieves the font runs for the given range of characters. + * + * The @p fontRuns buffer needs to be big enough to copy the number of font runs. + * Call GetNumberOfFontRuns() to retrieve the number of font runs. + * + * @param[out] fontRuns Pointer to a buffer where the font runs are copied. + * @param[in] characterIndex Index to the first character. + * @param[in] numberOfCharacters The number of characters. + */ + void GetFontRuns( FontRun* fontRuns, + CharacterIndex characterIndex, + Length numberOfCharacters ) const; + + /** + * Retrieves the font id for the given character index. + * + * @param[in] characterIndex Index to the first character. + * + * @return The font id. + */ + FontId GetFont( CharacterIndex characterIndex ) const; + protected: /** diff --git a/base/dali-toolkit/public-api/text/script-run.h b/base/dali-toolkit/public-api/text/script-run.h new file mode 100644 index 0000000..c5dd698 --- /dev/null +++ b/base/dali-toolkit/public-api/text/script-run.h @@ -0,0 +1,48 @@ +#ifndef __DALI_TOOLKIT_TEXT_SCRIPT_RUN_H__ +#define __DALI_TOOLKIT_TEXT_SCRIPT_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. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +/** + * @brief Run of characters with the same script. + */ +struct ScriptRun +{ + CharacterRun characterRun; ///< The initial character index and the number of characters of the run. + Script script; ///< Script of the run. +}; + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_TEXT_SCRIPT_RUN_H__ -- 2.7.4