From 95faa4c96dcfcc76207eace1d6a00ba0aef714f0 Mon Sep 17 00:00:00 2001 From: "minho.sun" Date: Thu, 26 Jul 2018 17:20:42 +0900 Subject: [PATCH] Support software styling When DALi fails to find font which support correct style, apply software styling to glyph. DALi will support bold / italic by software. Change-Id: Icaacd70c3721fe0c1f56b7782f3a6510fc6bfb59 Signed-off-by: minho.sun --- .../utc-Dali-Text-Shaping.cpp | 161 ++++++++++++++++++++- .../toolkit-text-abstraction.cpp | 6 +- .../src/dali-toolkit/utc-Dali-TextLabel.cpp | 2 +- dali-toolkit/internal/text/font-run.h | 9 +- .../internal/text/multi-language-support-impl.cpp | 23 ++- .../text/rendering/atlas/text-atlas-renderer.cpp | 2 + .../internal/text/rendering/text-typesetter.cpp | 2 + dali-toolkit/internal/text/shaper.cpp | 9 +- 8 files changed, 205 insertions(+), 9 deletions(-) diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Shaping.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Shaping.cpp index e4464fd..0b7ca02 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Shaping.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Shaping.cpp @@ -55,6 +55,8 @@ struct GlyphInfoData float yBearing; ///< The distance from the baseline to the topmost border of the glyph float advance; ///< The distance to move the cursor for this glyph float scaleFactor; ///< The scaling applied (fixed-size fonts only) + bool softwareItalic; ///< Whether glyph needs software support to draw italic style + bool softwareBold; ///< Whether glyph needs software support to draw bold style }; bool IsEqualGlyph ( const GlyphInfoData& glyphData, const GlyphInfo& glyph ) @@ -91,6 +93,14 @@ bool IsEqualGlyph ( const GlyphInfoData& glyphData, const GlyphInfo& glyph ) { return false; } + if( glyphData.softwareItalic != glyph.softwareItalic ) + { + return false; + } + if( glyphData.softwareBold != glyph.softwareBold ) + { + return false; + } return true; } @@ -107,6 +117,7 @@ struct ShapeInfoData Length* charactersPerGlyph; ///< The characters per glyph. uint32_t expectedNumberOfNewParagraphGlyphs; ///< The expected number of glyphs. GlyphIndex* newParagraphGlyphs; ///< Indices to the new paragraphs glyphs. + Vector fontDescriptions; ///< Fonts which is used for text. }; bool ShapeInfoTest( const ShapeInfoData& data ) @@ -122,7 +133,7 @@ bool ShapeInfoTest( const ShapeInfoData& data ) const LayoutOptions options; CreateTextModel( data.text, textArea, - fontDescriptions, + data.fontDescriptions, options, layoutSize, logicalModel, @@ -532,3 +543,151 @@ int UtcDaliTextShape(void) tet_result(TET_PASS); END_TEST; } + +int UtcDaliTextSoftwareStyling(void) +{ + tet_infoline(" UtcDaliTextSoftwareStyling"); + + struct GlyphInfoData glyphs01[] = + { + { 2u, 14750u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, true, true }, + { 2u, 9802u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, true, true }, + { 2u, 12811u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, true, true }, + }; + struct GlyphInfoData glyphs02[] = + { + { 2u, 14750u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, false, false }, + { 2u, 9802u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, false, true }, + { 2u, 12811u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, true, false }, + }; + + CharacterIndex characterIndices[] = { 0u, 1u, 2u }; + Length charactersPerGlyph[] = { 1u, 1u, 1u }; + + Vector fontDescriptions01; + Vector fontDescriptions02; + + FontDescriptionRun fontDescriptionRun01 = + { + { + 0u, + 3u + }, + NULL, + 0u, + TextAbstraction::FontWeight::BOLD, + TextAbstraction::FontWidth::NONE, + TextAbstraction::FontSlant::ITALIC, + TextAbstraction::FontClient::DEFAULT_POINT_SIZE, + false, + true, + false, + true, + false + }; + fontDescriptions01.PushBack(fontDescriptionRun01); + + FontDescriptionRun fontDescriptionRun02 = + { + { + 0u, + 1u + }, + NULL, + 0u, + TextAbstraction::FontWeight::NONE, + TextAbstraction::FontWidth::NONE, + TextAbstraction::FontSlant::NONE, + TextAbstraction::FontClient::DEFAULT_POINT_SIZE, + false, + false, + false, + false, + false + }; + FontDescriptionRun fontDescriptionRun03 = + { + { + 1u, + 1u + }, + NULL, + 0u, + TextAbstraction::FontWeight::BOLD, + TextAbstraction::FontWidth::NONE, + TextAbstraction::FontSlant::NONE, + TextAbstraction::FontClient::DEFAULT_POINT_SIZE, + false, + true, + false, + false, + false + }; + FontDescriptionRun fontDescriptionRun04 = + { + { + 2u, + 1u + }, + NULL, + 0u, + TextAbstraction::FontWeight::NONE, + TextAbstraction::FontWidth::NONE, + TextAbstraction::FontSlant::ITALIC, + TextAbstraction::FontClient::DEFAULT_POINT_SIZE, + false, + false, + false, + true, + false + }; + + fontDescriptions02.PushBack(fontDescriptionRun02); + fontDescriptions02.PushBack(fontDescriptionRun03); + fontDescriptions02.PushBack(fontDescriptionRun04); + + + struct ShapeInfoData data[] = + { + { + "Chiness script. Characters have same font description", + "未取得", + 0u, + 3u, + 3u, + glyphs01, + characterIndices, + charactersPerGlyph, + 0u, + NULL, + fontDescriptions01 + }, + { + "Chiness script. Each character has different font description.", + "未取得", + 0u, + 3u, + 3u, + glyphs02, + characterIndices, + charactersPerGlyph, + 0u, + NULL, + fontDescriptions02 + } + }; + + const unsigned int numberOfTests = 2u; + + for( unsigned int index = 0u; index < numberOfTests; ++index ) + { + ToolkitTestApplication application; + if( !ShapeInfoTest( data[index] ) ) + { + tet_result(TET_FAIL); + } + } + + tet_result(TET_PASS); + END_TEST; +} \ No newline at end of file diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-abstraction.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-abstraction.cpp index 5cc9401..75312ef 100755 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-abstraction.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-abstraction.cpp @@ -152,7 +152,7 @@ public: void GetFontMetrics( FontId fontId, FontMetrics& metrics ){} GlyphIndex GetGlyphIndex( FontId fontId, Character charcode ){return 0;} bool GetGlyphMetrics( GlyphInfo* array, uint32_t size, bool horizontal ){return true;} - void CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth ){} + void CreateBitmap( FontId fontId, GlyphIndex glyphIndex, bool softwareItailc, bool softwareBold, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth ){} PixelData CreateBitmap( FontId fontId, GlyphIndex glyphIndex, int outlineWidth ){return PixelData();} void CreateVectorBlob( FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight ) @@ -472,9 +472,9 @@ bool FontClient::GetGlyphMetrics( GlyphInfo* array, uint32_t size, GlyphType typ return GetImplementation(*this).GetGlyphMetrics( array, size, horizontal ); } -void FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth ) +void FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, bool softwareItailc, bool softwareBold, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth ) { - GetImplementation(*this).CreateBitmap( fontId, glyphIndex, data, outlineWidth ); + GetImplementation(*this).CreateBitmap( fontId, glyphIndex, softwareItailc, softwareBold, data, outlineWidth ); } PixelData FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, int outlineWidth ) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp index d5019bd..b134179 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp @@ -1319,4 +1319,4 @@ int UtcDaliToolkitTextlabelVerticalLineAlignment(void) DALI_TEST_EQUALS( label.GetProperty< int >( DevelTextLabel::Property::VERTICAL_LINE_ALIGNMENT ), static_cast< int >( Toolkit::DevelText::VerticalLineAlignment::BOTTOM ), TEST_LOCATION ); END_TEST; -} +} \ No newline at end of file diff --git a/dali-toolkit/internal/text/font-run.h b/dali-toolkit/internal/text/font-run.h index 6027ef7..a787558 100644 --- a/dali-toolkit/internal/text/font-run.h +++ b/dali-toolkit/internal/text/font-run.h @@ -18,6 +18,9 @@ * */ +// EXTERNAL INCLUDES +#include + // INTERNAL INCLUDES #include @@ -35,8 +38,10 @@ namespace Text */ struct FontRun { - CharacterRun characterRun; ///< The initial character index and the number of characters of the run. - FontId fontId; ///< Font id of the run. + CharacterRun characterRun; ///< The initial character index and the number of characters of the run. + FontId fontId; ///< Font id of the run. + bool softwareItalic:1; ///< Whether font needs software support to draw italic style + bool softwareBold:1; ///< Whether font needs software support to draw bold style }; } // namespace Text diff --git a/dali-toolkit/internal/text/multi-language-support-impl.cpp b/dali-toolkit/internal/text/multi-language-support-impl.cpp index 7570e04..6ca96ad 100644 --- a/dali-toolkit/internal/text/multi-language-support-impl.cpp +++ b/dali-toolkit/internal/text/multi-language-support-impl.cpp @@ -440,12 +440,18 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, FontId previousFontId = 0u; bool isPreviousEmojiScript = false; + // Description of fallback font which is selected at current iteration. + TextAbstraction::FontDescription selectedFontDescription; + CharacterIndex lastCharacter = startIndex + numberOfCharacters; for( Length index = startIndex; index < lastCharacter; ++index ) { // Get the current character. const Character character = *( textBuffer + index ); + bool needSoftwareBoldening = false; + bool needSoftwareItalic = false; + // new description for current character TextAbstraction::FontDescription currentFontDescription; TextAbstraction::PointSize26Dot6 currentFontPointSize = defaultFontPointSize; bool isDefaultFont = true; @@ -689,9 +695,22 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, } #endif + if( fontId != currentFontRun.fontId ) + { + fontClient.GetDescription(fontId,selectedFontDescription); + } + + // Developer sets bold to character but selected font cannot support it + needSoftwareBoldening = ( currentFontDescription.weight >= TextAbstraction::FontWeight::BOLD ) && ( selectedFontDescription.weight < TextAbstraction::FontWeight::BOLD ); + + // Developer sets italic to character but selected font cannot support it + needSoftwareItalic = ( currentFontDescription.slant == TextAbstraction::FontSlant::ITALIC ) && ( selectedFontDescription.slant < TextAbstraction::FontSlant::ITALIC ); + // The font is now validated. if( ( fontId != currentFontRun.fontId ) || - isNewParagraphCharacter ) + isNewParagraphCharacter || + // If font id is same as previous but style is diffrent, initialize new one + ( ( fontId == currentFontRun.fontId ) && ( ( needSoftwareBoldening != currentFontRun.softwareBold ) || ( needSoftwareItalic != currentFontRun.softwareItalic ) ) ) ) { // Current run needs to be stored and a new one initialized. @@ -706,6 +725,8 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, currentFontRun.characterRun.characterIndex = currentFontRun.characterRun.characterIndex + currentFontRun.characterRun.numberOfCharacters; currentFontRun.characterRun.numberOfCharacters = 0u; currentFontRun.fontId = fontId; + currentFontRun.softwareItalic = needSoftwareItalic; + currentFontRun.softwareBold = needSoftwareBoldening; } // Add one more character to the run. diff --git a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp index c6d1f80..2fa2c8b 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -257,6 +257,8 @@ struct AtlasRenderer::Impl mFontClient.CreateBitmap( glyph.fontId, glyph.index, + glyph.softwareItalic, + glyph.softwareBold, glyphBufferData, outline ); diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp index c5fa932..0e149d7 100755 --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -672,6 +672,8 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth { fontClient.CreateBitmap( glyphInfo->fontId, glyphInfo->index, + glyphInfo->softwareItalic, + glyphInfo->softwareBold, glyphData.glyphBitmap, outlineWidth ); } diff --git a/dali-toolkit/internal/text/shaper.cpp b/dali-toolkit/internal/text/shaper.cpp index cd0b1d7..624c443 100644 --- a/dali-toolkit/internal/text/shaper.cpp +++ b/dali-toolkit/internal/text/shaper.cpp @@ -137,6 +137,8 @@ void ShapeText( const Vector& text, currentFontId = fontRun.fontId; currentScript = scriptRun.script; + bool softwareItalic = fontRun.softwareItalic; + bool softwareBold = fontRun.softwareBold; // Get the min index to the last character of both runs. CharacterIndex currentIndex = min( fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters, @@ -170,7 +172,12 @@ void ShapeText( const Vector& text, // Retrieve the glyphs and the glyph to character conversion map. Vector tmpGlyphs; Vector tmpGlyphToCharacterMap; - tmpGlyphs.Resize( numberOfGlyphs ); + + GlyphInfo glyphInfo; + glyphInfo.softwareItalic = softwareItalic; + glyphInfo.softwareBold = softwareBold; + + tmpGlyphs.Resize( numberOfGlyphs, glyphInfo ); tmpGlyphToCharacterMap.Resize( numberOfGlyphs ); shaping.GetGlyphs( tmpGlyphs.Begin(), tmpGlyphToCharacterMap.Begin() ); -- 2.7.4