X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Fglyph-metrics-helper.cpp;h=c46fefd26a014fa49c4ce7597a11d3eeba99510e;hb=77525ca172708d0973a54532bb4f26cacf8784e6;hp=ef9098c11faa5d2d11a6cced7a38923acfc2b779;hpb=d82494a77e405d5924cf1af3fe55b2d9b9577e3f;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/glyph-metrics-helper.cpp b/dali-toolkit/internal/text/glyph-metrics-helper.cpp old mode 100755 new mode 100644 index ef9098c..c46fefd --- a/dali-toolkit/internal/text/glyph-metrics-helper.cpp +++ b/dali-toolkit/internal/text/glyph-metrics-helper.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -19,24 +19,24 @@ // FILE HEADER #include +// INTERNAL INCLUDES +#include + namespace Dali { - namespace Toolkit { - namespace Text { - -Length GetNumberOfGlyphsOfGroup( GlyphIndex glyphIndex, - GlyphIndex lastGlyphPlusOne, - const Length* const charactersPerGlyphBuffer ) +Length GetNumberOfGlyphsOfGroup(GlyphIndex glyphIndex, + GlyphIndex lastGlyphPlusOne, + const Length* const charactersPerGlyphBuffer) { Length numberOfGLyphsInGroup = 1u; - for( GlyphIndex index = glyphIndex; index < lastGlyphPlusOne; ++index ) + for(GlyphIndex index = glyphIndex; index < lastGlyphPlusOne; ++index) { - if( 0u == *( charactersPerGlyphBuffer + index ) ) + if(0u == *(charactersPerGlyphBuffer + index)) { ++numberOfGLyphsInGroup; } @@ -49,51 +49,106 @@ Length GetNumberOfGlyphsOfGroup( GlyphIndex glyphIndex, return numberOfGLyphsInGroup; } -void GetGlyphsMetrics( GlyphIndex glyphIndex, - Length numberOfGlyphs, - GlyphMetrics& glyphMetrics, - const GlyphInfo* const glyphsBuffer, - MetricsPtr& metrics ) +void GetGlyphsMetrics(GlyphIndex glyphIndex, + Length numberOfGlyphs, + GlyphMetrics& glyphMetrics, + const GlyphInfo* const glyphsBuffer, + MetricsPtr& metrics, + float calculatedAdvance) { - const GlyphInfo& firstGlyph = *( glyphsBuffer + glyphIndex ); + const GlyphInfo& firstGlyph = *(glyphsBuffer + glyphIndex); Text::FontMetrics fontMetrics; - if( 0u != firstGlyph.fontId ) + if(0u != firstGlyph.fontId) { - metrics->GetFontMetrics( firstGlyph.fontId, fontMetrics ); + metrics->GetFontMetrics(firstGlyph.fontId, fontMetrics); } - else if( 0u != firstGlyph.index ) + else if(0u != firstGlyph.index) { // It may be an embedded image. - fontMetrics.ascender = firstGlyph.height; + fontMetrics.ascender = firstGlyph.height; fontMetrics.descender = 0.f; - fontMetrics.height = fontMetrics.ascender; + fontMetrics.height = fontMetrics.ascender; } - const bool isItalicFont = metrics->HasItalicStyle( firstGlyph.fontId ); + const bool isItalicFont = metrics->HasItalicStyle(firstGlyph.fontId); - glyphMetrics.fontId = firstGlyph.fontId; + glyphMetrics.fontId = firstGlyph.fontId; glyphMetrics.fontHeight = fontMetrics.height; - glyphMetrics.width = firstGlyph.width + ( ( firstGlyph.isItalicRequired && !isItalicFont ) ? static_cast( TextAbstraction::FontClient::DEFAULT_ITALIC_ANGLE * static_cast( firstGlyph.height ) ) : 0u ); - glyphMetrics.advance = firstGlyph.advance; - glyphMetrics.ascender = fontMetrics.ascender; - glyphMetrics.xBearing = firstGlyph.xBearing; + glyphMetrics.width = firstGlyph.width; + glyphMetrics.advance = calculatedAdvance; + glyphMetrics.ascender = fontMetrics.ascender; + glyphMetrics.xBearing = firstGlyph.xBearing; - if( 1u < numberOfGlyphs ) + if(1u < numberOfGlyphs) { - const float widthInit = firstGlyph.xBearing; + float maxWidthEdge = firstGlyph.xBearing + firstGlyph.width; - for( unsigned int i = 1u; i < numberOfGlyphs; ++i ) + for(unsigned int i = 1u; i < numberOfGlyphs; ++i) { - const GlyphInfo& glyphInfo = *( glyphsBuffer + glyphIndex + i ); + const GlyphInfo& glyphInfo = *(glyphsBuffer + glyphIndex + i); + + // update the initial xBearing if smaller. + glyphMetrics.xBearing = std::min(glyphMetrics.xBearing, glyphMetrics.advance + glyphInfo.xBearing); - glyphMetrics.width = glyphMetrics.advance + glyphInfo.xBearing + glyphInfo.width + ( ( firstGlyph.isItalicRequired && !isItalicFont ) ? static_cast( TextAbstraction::FontClient::DEFAULT_ITALIC_ANGLE * static_cast( firstGlyph.height ) ) : 0u ); - glyphMetrics.advance += glyphInfo.advance; + // update the max width edge if bigger. + const float currentMaxGlyphWidthEdge = glyphMetrics.advance + glyphInfo.xBearing + glyphInfo.width; + maxWidthEdge = std::max(maxWidthEdge, currentMaxGlyphWidthEdge); + glyphMetrics.advance += (glyphInfo.advance); } - glyphMetrics.width -= widthInit; + glyphMetrics.width = maxWidthEdge - glyphMetrics.xBearing; } + + glyphMetrics.width += (firstGlyph.isItalicRequired && !isItalicFont) ? TextAbstraction::FontClient::DEFAULT_ITALIC_ANGLE * firstGlyph.height : 0.f; +} + +void GetGlyphMetricsFromCharacterIndex(CharacterIndex index, + const VisualModelPtr& visualModel, + const LogicalModelPtr& logicalModel, + MetricsPtr& metrics, + GlyphMetrics& glyphMetrics, + GlyphIndex& glyphIndex, + Length& numberOfGlyphs) +{ + const GlyphIndex* const charactersToGlyphBuffer = visualModel->mCharactersToGlyph.Begin(); + const Length* const glyphsPerCharacterBuffer = visualModel->mGlyphsPerCharacter.Begin(); + const GlyphInfo* const glyphInfoBuffer = visualModel->mGlyphs.Begin(); + Vector& glyphToCharacterMap = visualModel->mGlyphsToCharacters; + const CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin(); + const float modelCharacterSpacing = visualModel->GetCharacterSpacing(); + + // Get the character-spacing runs. + const Vector& characterSpacingGlyphRuns = visualModel->GetCharacterSpacingGlyphRuns(); + + //Takes the character index, obtains the glyph index (and the number of Glyphs) from it and finally gets the glyph metrics. + glyphIndex = *(charactersToGlyphBuffer + index); + numberOfGlyphs = *(glyphsPerCharacterBuffer + index); + + float calculatedAdvance = 0.f; + + const float characterSpacing = GetGlyphCharacterSpacing(glyphIndex, characterSpacingGlyphRuns, modelCharacterSpacing); + calculatedAdvance = GetCalculatedAdvance(*(logicalModel->mText.Begin() + (*(glyphToCharacterMapBuffer + glyphIndex))), characterSpacing, (*(visualModel->mGlyphs.Begin() + glyphIndex)).advance); + + // Get the metrics for the group of glyphs. + GetGlyphsMetrics(glyphIndex, + numberOfGlyphs, + glyphMetrics, + glyphInfoBuffer, + metrics, + calculatedAdvance); +} + +float GetCalculatedAdvance(unsigned int character, float characterSpacing, float advance) +{ + //Gets the final advance value by adding the CharacterSpacing value to it + //In some cases the CharacterSpacing should not be added. Ex: when the glyph is a ZWSP (Zero Width Space) + return (TextAbstraction::IsZeroWidthNonJoiner(character) || TextAbstraction::IsZeroWidthJoiner(character) || + TextAbstraction::IsZeroWidthSpace(character) || TextAbstraction::IsNewParagraph(character) || + TextAbstraction::IsLeftToRightMark(character) || TextAbstraction::IsRightToLeftMark(character)) + ? advance + : advance + characterSpacing; } } // namespace Text