X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Fglyph-metrics-helper.cpp;h=c46fefd26a014fa49c4ce7597a11d3eeba99510e;hb=b33878720fce34aaa873feea5d4b83290b2db9b5;hp=9c7c8ec38431a64938d0a580b60c507861dc5c36;hpb=9598e692217c5fb541d862a3957b3efd5fd5171d;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 index 9c7c8ec..c46fefd 100644 --- 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,31 +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; - metrics->GetFontMetrics( firstGlyph.fontId, fontMetrics ); + if(0u != firstGlyph.fontId) + { + metrics->GetFontMetrics(firstGlyph.fontId, fontMetrics); + } + else if(0u != firstGlyph.index) + { + // It may be an embedded image. + fontMetrics.ascender = firstGlyph.height; + fontMetrics.descender = 0.f; + fontMetrics.height = fontMetrics.ascender; + } + + const bool isItalicFont = metrics->HasItalicStyle(firstGlyph.fontId); - glyphMetrics.fontId = firstGlyph.fontId; + glyphMetrics.fontId = firstGlyph.fontId; glyphMetrics.fontHeight = fontMetrics.height; - glyphMetrics.width = firstGlyph.width; - 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; - for( unsigned int i = 1u; i < numberOfGlyphs; ++i ) + if(1u < numberOfGlyphs) { - const GlyphInfo& glyphInfo = *( glyphsBuffer + glyphIndex + i ); + float maxWidthEdge = firstGlyph.xBearing + firstGlyph.width; + + for(unsigned int i = 1u; i < numberOfGlyphs; ++i) + { + const GlyphInfo& glyphInfo = *(glyphsBuffer + glyphIndex + i); - glyphMetrics.advance += glyphInfo.advance; - glyphMetrics.width += glyphInfo.width; + // update the initial xBearing if smaller. + glyphMetrics.xBearing = std::min(glyphMetrics.xBearing, glyphMetrics.advance + glyphInfo.xBearing); + + // 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 = 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