From: Paul Wisbey Date: Thu, 21 Apr 2016 14:59:26 +0000 (-0700) Subject: Merge "TextController - Update the text model." into devel/master X-Git-Tag: dali_1.1.31~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=9598e692217c5fb541d862a3957b3efd5fd5171d;hp=26cacf71e74fab984c12bc77485920f4573b97ec Merge "TextController - Update the text model." into devel/master --- diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index ab7cac6..758160f 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -91,6 +91,7 @@ toolkit_src_files = \ $(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/glyph-metrics-helper.cpp \ $(toolkit_src_dir)/text/logical-model-impl.cpp \ $(toolkit_src_dir)/text/markup-processor.cpp \ $(toolkit_src_dir)/text/markup-processor-color.cpp \ diff --git a/dali-toolkit/internal/text/glyph-metrics-helper.cpp b/dali-toolkit/internal/text/glyph-metrics-helper.cpp new file mode 100644 index 0000000..9c7c8ec --- /dev/null +++ b/dali-toolkit/internal/text/glyph-metrics-helper.cpp @@ -0,0 +1,83 @@ + +/* + * 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 + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +Length GetNumberOfGlyphsOfGroup( GlyphIndex glyphIndex, + GlyphIndex lastGlyphPlusOne, + const Length* const charactersPerGlyphBuffer ) +{ + Length numberOfGLyphsInGroup = 1u; + + for( GlyphIndex index = glyphIndex; index < lastGlyphPlusOne; ++index ) + { + if( 0u == *( charactersPerGlyphBuffer + index ) ) + { + ++numberOfGLyphsInGroup; + } + else + { + break; + } + } + + return numberOfGLyphsInGroup; +} + +void GetGlyphsMetrics( GlyphIndex glyphIndex, + Length numberOfGlyphs, + GlyphMetrics& glyphMetrics, + const GlyphInfo* const glyphsBuffer, + MetricsPtr& metrics ) +{ + const GlyphInfo& firstGlyph = *( glyphsBuffer + glyphIndex ); + + Text::FontMetrics fontMetrics; + metrics->GetFontMetrics( firstGlyph.fontId, fontMetrics ); + + glyphMetrics.fontId = firstGlyph.fontId; + glyphMetrics.fontHeight = fontMetrics.height; + glyphMetrics.width = firstGlyph.width; + glyphMetrics.advance = firstGlyph.advance; + glyphMetrics.ascender = fontMetrics.ascender; + glyphMetrics.xBearing = firstGlyph.xBearing; + + for( unsigned int i = 1u; i < numberOfGlyphs; ++i ) + { + const GlyphInfo& glyphInfo = *( glyphsBuffer + glyphIndex + i ); + + glyphMetrics.advance += glyphInfo.advance; + glyphMetrics.width += glyphInfo.width; + } +} + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/text/glyph-metrics-helper.h b/dali-toolkit/internal/text/glyph-metrics-helper.h new file mode 100644 index 0000000..2c2c848 --- /dev/null +++ b/dali-toolkit/internal/text/glyph-metrics-helper.h @@ -0,0 +1,93 @@ +#ifndef __DALI_TOOLKIT_TEXT_GLYPH_METRICS_HELPER_H__ +#define __DALI_TOOLKIT_TEXT_GLYPH_METRICS_HELPER_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. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +/** + * @brief Some characters can be shaped in more than one glyph. + * This struct is used to retrieve metrics from these group of glyphs. + */ +struct GlyphMetrics +{ + GlyphMetrics() + : fontId( 0u ), + fontHeight( 0.f ), + width( 0.f ), + advance( 0.f ), + ascender( 0.f ), + xBearing( 0.f ) + {} + + ~GlyphMetrics() + {} + + FontId fontId; ///< The font id of the glyphs. + float fontHeight; ///< The font's height of those glyphs. + float width; ///< The sum of all the widths of all the glyphs. + float advance; ///< The sum of all the advances of all the glyphs. + float ascender; ///< The font's ascender. + float xBearing; ///< The x bearing of the first glyph. +}; + +/** + * @brief Returns the number of glyphs of a group of glyphs. + * + * @param[in] glyphIndex The first glyph of the group. + * @param[in] lastGlyphPlusOne Index to one after the last glyph. + * @param[in] charactersPerGlyphBuffer The number of characters per glyph buffer. + * + * @return The number of glyphs of the group. + */ +Length GetNumberOfGlyphsOfGroup( GlyphIndex glyphIndex, + GlyphIndex lastGlyphPlusOne, + const Length* const charactersPerGlyphBuffer ); + +/** + * @brief Get some glyph's metrics of a group of glyphs formed as a result of shaping one character. + * + * @param[in] glyphIndex The index to the first glyph. + * @param[in] numberOfGlyphs The number of glyphs. + * @param[out] glyphMetrics Some glyph metrics (font height, advance, ascender and x bearing). + * @param[in] glyphsBuffer The glyphs buffer. + * @param[in] metrics Used to access metrics from FontClient. + */ +void GetGlyphsMetrics( GlyphIndex glyphIndex, + Length numberOfGlyphs, + GlyphMetrics& glyphMetrics, + const GlyphInfo* const glyphsBuffer, + MetricsPtr& metrics ); + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_TEXT_GLYPH_METRICS_HELPER_H__ diff --git a/dali-toolkit/internal/text/layouts/layout-engine.cpp b/dali-toolkit/internal/text/layouts/layout-engine.cpp index 0b9e39d..4182acd 100644 --- a/dali-toolkit/internal/text/layouts/layout-engine.cpp +++ b/dali-toolkit/internal/text/layouts/layout-engine.cpp @@ -24,8 +24,9 @@ #include // INTERNAL INCLUDES -#include #include +#include +#include namespace Dali { @@ -194,59 +195,81 @@ struct LayoutEngine::Impl LineLayout tmpLineLayout; const bool isMultiline = mLayout == MULTI_LINE_BOX; - const GlyphIndex lastGlyphIndex = parameters.totalNumberOfGlyphs - 1u; + + // The last glyph to be laid-out. + const GlyphIndex lastGlyphOfParagraphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs; // If the first glyph has a negative bearing its absolute value needs to be added to the line length. // In the case the line starts with a right to left character, if the width is longer than the advance, // the difference needs to be added to the line length. - const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + lineLayout.glyphIndex ); + + // Check whether the first glyph comes from a character that is shaped in multiple glyphs. + const Length numberOfGLyphsInGroup = GetNumberOfGlyphsOfGroup( lineLayout.glyphIndex, + lastGlyphOfParagraphPlusOne, + parameters.charactersPerGlyphBuffer ); + + GlyphMetrics glyphMetrics; + GetGlyphsMetrics( lineLayout.glyphIndex, + numberOfGLyphsInGroup, + glyphMetrics, + parameters.glyphsBuffer, + mMetrics ); // Set the direction of the first character of the line. lineLayout.characterIndex = *( parameters.glyphsToCharactersBuffer + lineLayout.glyphIndex ); const CharacterDirection firstCharacterDirection = ( NULL == parameters.characterDirectionBuffer ) ? false : *( parameters.characterDirectionBuffer + lineLayout.characterIndex ); CharacterDirection previousCharacterDirection = firstCharacterDirection; - const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance; + const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance; float tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f; - float tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f; + float tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f; tmpLineLayout.length += mCursorWidth; // Added to give some space to the cursor. // Calculate the line height if there is no characters. - FontId lastFontId = glyphInfo.fontId; + FontId lastFontId = glyphMetrics.fontId; UpdateLineHeight( lastFontId, tmpLineLayout ); bool oneWordLaidOut = false; - const GlyphIndex lastGlyphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs; for( GlyphIndex glyphIndex = lineLayout.glyphIndex; - glyphIndex < lastGlyphPlusOne; - ++glyphIndex ) + glyphIndex < lastGlyphOfParagraphPlusOne; ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, " glyph index : %d\n", glyphIndex ); - const bool isLastGlyph = glyphIndex == lastGlyphIndex; - // Get the glyph info. - const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + glyphIndex ); + // Check whether this glyph comes from a character that is shaped in multiple glyphs. + const Length numberOfGLyphsInGroup = GetNumberOfGlyphsOfGroup( glyphIndex, + lastGlyphOfParagraphPlusOne, + parameters.charactersPerGlyphBuffer ); + + GlyphMetrics glyphMetrics; + GetGlyphsMetrics( glyphIndex, + numberOfGLyphsInGroup, + glyphMetrics, + parameters.glyphsBuffer, + mMetrics ); + + const bool isLastGlyph = glyphIndex + numberOfGLyphsInGroup == parameters.totalNumberOfGlyphs; // Check if the font of the current glyph is the same of the previous one. // If it's different the ascender and descender need to be updated. - if( lastFontId != glyphInfo.fontId ) + if( lastFontId != glyphMetrics.fontId ) { - UpdateLineHeight( glyphInfo.fontId, tmpLineLayout ); - lastFontId = glyphInfo.fontId; + UpdateLineHeight( glyphMetrics.fontId, tmpLineLayout ); + lastFontId = glyphMetrics.fontId; } // Get the character indices for the current glyph. The last character index is needed // because there are glyphs formed by more than one character but their break info is // given only for the last character. - const Length charactersPerGlyph = *( parameters.charactersPerGlyphBuffer + glyphIndex ); + const Length charactersPerGlyph = *( parameters.charactersPerGlyphBuffer + glyphIndex + numberOfGLyphsInGroup - 1u ); + const bool hasCharacters = charactersPerGlyph > 0u; const CharacterIndex characterFirstIndex = *( parameters.glyphsToCharactersBuffer + glyphIndex ); - const CharacterIndex characterLastIndex = characterFirstIndex + ( ( 1u > charactersPerGlyph ) ? 0u : charactersPerGlyph - 1u ); + const CharacterIndex characterLastIndex = characterFirstIndex + ( hasCharacters ? charactersPerGlyph - 1u : 0u ); // Get the line break info for the current character. - const LineBreakInfo lineBreakInfo = *( parameters.lineBreakInfoBuffer + characterLastIndex ); + const LineBreakInfo lineBreakInfo = hasCharacters ? *( parameters.lineBreakInfoBuffer + characterLastIndex ) : TextAbstraction::LINE_NO_BREAK; // Get the word break info for the current character. const WordBreakInfo wordBreakInfo = *( parameters.wordBreakInfoBuffer + characterLastIndex ); @@ -255,7 +278,7 @@ struct LayoutEngine::Impl tmpLineLayout.numberOfCharacters += charactersPerGlyph; // Increase the number of glyphs. - tmpLineLayout.numberOfGlyphs++; + tmpLineLayout.numberOfGlyphs += numberOfGLyphsInGroup; // Check whether is a white space. const Character character = *( parameters.textBuffer + characterFirstIndex ); @@ -273,12 +296,12 @@ struct LayoutEngine::Impl if( isWhiteSpace ) { // Add the length to the length of white spaces at the end of the line. - tmpLineLayout.wsLengthEndOfLine += glyphInfo.advance; // The advance is used as the width is always zero for the white spaces. + tmpLineLayout.wsLengthEndOfLine += glyphMetrics.advance; // The advance is used as the width is always zero for the white spaces. } else { // Add as well any previous white space length. - tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine + glyphInfo.advance; + tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine + glyphMetrics.advance; // An extra space may be added to the line for the first and last glyph of the line. // If the bearing of the first glyph is negative, its positive value needs to be added. @@ -298,7 +321,7 @@ struct LayoutEngine::Impl // | Rll| // - tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f; + tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f; } else // LTR { @@ -311,7 +334,7 @@ struct LayoutEngine::Impl // |rrL | // - const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance; + const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance; tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f; } } @@ -324,7 +347,7 @@ struct LayoutEngine::Impl // --> // |lllR | - const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance; + const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance; tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f; } else // LTR @@ -332,7 +355,7 @@ struct LayoutEngine::Impl // <-- // | Lrrrr| - tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f; + tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f; } } else if( characterDirection == firstCharacterDirection ) @@ -343,7 +366,7 @@ struct LayoutEngine::Impl // |llllllrr| // |Rr | - tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f; + tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f; } else // LTR { @@ -351,7 +374,7 @@ struct LayoutEngine::Impl // |llllrrrr| // | llL| - const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance; + const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance; tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f; } } @@ -374,7 +397,7 @@ struct LayoutEngine::Impl if( tmpLineLayout.numberOfGlyphs > 0u ) { tmpLineLayout.numberOfCharacters -= charactersPerGlyph; - --tmpLineLayout.numberOfGlyphs; + tmpLineLayout.numberOfGlyphs -= numberOfGLyphsInGroup; tmpLineLayout.length = previousTmpLineLength; tmpExtraBearing = previousTmpExtraBearing; tmpExtraWidth = previousTmpExtraWidth; @@ -414,6 +437,7 @@ struct LayoutEngine::Impl DALI_LOG_INFO( gLogFilter, Debug::Verbose, " Must break\n" ); DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--GetLineLayoutForBox\n" ); + return; } @@ -431,6 +455,7 @@ struct LayoutEngine::Impl } previousCharacterDirection = characterDirection; + glyphIndex += numberOfGLyphsInGroup; } lineLayout.extraBearing = tmpExtraBearing; diff --git a/dali-toolkit/internal/text/metrics.h b/dali-toolkit/internal/text/metrics.h index 5e58f38..232360e 100644 --- a/dali-toolkit/internal/text/metrics.h +++ b/dali-toolkit/internal/text/metrics.h @@ -22,6 +22,9 @@ #include #include +// INTERNAL INCLUDES +#include + namespace Dali { diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 468ab0c..f64c266 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -38,28 +39,6 @@ namespace Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS"); #endif -/** - * @brief Some characters can be shaped in more than one glyph. - * This struct is used to retrieve metrics from these group of glyphs. - */ -struct GlyphMetrics -{ - GlyphMetrics() - : fontHeight( 0.f ), - advance( 0.f ), - ascender( 0.f ), - xBearing( 0.f ) - {} - - ~GlyphMetrics() - {} - - float fontHeight; ///< The font's height of that glyphs. - float advance; ///< The sum of all the advances of all the glyphs. - float ascender; ///< The font's ascender. - float xBearing; ///< The x bearing of the first glyph. -}; - } // namespace namespace Dali @@ -71,41 +50,6 @@ namespace Toolkit namespace Text { -/** - * @brief Get some glyph's metrics of a group of glyphs formed as a result of shaping one character. - * - * @param[in] glyphIndex The index to the first glyph. - * @param[in] numberOfGlyphs The number of glyphs. - * @param[out] glyphMetrics Some glyph metrics (font height, advance, ascender and x bearing). - * @param[in] visualModel The visual model. - * @param[in] metrics Used to access metrics from FontClient. - */ -void GetGlyphsMetrics( GlyphIndex glyphIndex, - Length numberOfGlyphs, - GlyphMetrics& glyphMetrics, - VisualModelPtr& visualModel, - MetricsPtr& metrics ) -{ - const GlyphInfo* glyphsBuffer = visualModel->mGlyphs.Begin(); - - const GlyphInfo& firstGlyph = *( glyphsBuffer + glyphIndex ); - - Text::FontMetrics fontMetrics; - metrics->GetFontMetrics( firstGlyph.fontId, fontMetrics ); - - glyphMetrics.fontHeight = fontMetrics.height; - glyphMetrics.advance = firstGlyph.advance; - glyphMetrics.ascender = fontMetrics.ascender; - glyphMetrics.xBearing = firstGlyph.xBearing; - - for( unsigned int i = 1u; i < numberOfGlyphs; ++i ) - { - const GlyphInfo& glyphInfo = *( glyphsBuffer + glyphIndex + i ); - - glyphMetrics.advance += glyphInfo.advance; - } -} - EventData::EventData( DecoratorPtr decorator ) : mDecorator( decorator ), mImfManager(), @@ -1980,6 +1924,9 @@ CharacterIndex Controller::Impl::GetClosestCursorIndex( float visualX, // Get the glyphs per character table. const Length* const glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin(); + // Get the glyph's info buffer. + const GlyphInfo* const glyphInfoBuffer = mVisualModel->mGlyphs.Begin(); + // If the vector is void, there is no right to left characters. const bool hasRightToLeftCharacters = NULL != visualToLogicalBuffer; @@ -2018,7 +1965,7 @@ CharacterIndex Controller::Impl::GetClosestCursorIndex( float visualX, GetGlyphsMetrics( firstLogicalGlyphIndex, numberOfGlyphs, glyphMetrics, - mVisualModel, + glyphInfoBuffer, mMetrics ); // Get the position of the first glyph. @@ -2197,6 +2144,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, const Length* const charactersPerGlyphBuffer = mVisualModel->mCharactersPerGlyph.Begin(); const CharacterIndex* const glyphsToCharactersBuffer = mVisualModel->mGlyphsToCharacters.Begin(); const Vector2* const glyphPositionsBuffer = mVisualModel->mGlyphPositions.Begin(); + const GlyphInfo* const glyphInfoBuffer = mVisualModel->mGlyphs.Begin(); // Convert the cursor position into the glyph position. const GlyphIndex primaryGlyphIndex = *( charactersToGlyphBuffer + index ); @@ -2208,7 +2156,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, GetGlyphsMetrics( primaryGlyphIndex, primaryNumberOfGlyphs, glyphMetrics, - mVisualModel, + glyphInfoBuffer, mMetrics ); // Whether to add the glyph's advance to the cursor position. @@ -2298,7 +2246,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, GetGlyphsMetrics( secondaryGlyphIndex, secondaryNumberOfGlyphs, glyphMetrics, - mVisualModel, + glyphInfoBuffer, mMetrics ); // Set the secondary cursor's position.