X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=text%2Fdali%2Finternal%2Ftext-abstraction%2Fshaping-impl.cpp;h=24c542c66623080464435dd3da033e73e2b28afe;hb=refs%2Ftags%2Faccepted%2Ftizen%2F4.0%2Funified%2F20180212.141253;hp=32591e080326d83c41c0d5aed9ae4a4e954256b3;hpb=38cd65e446e7799fefc910d3758f9b5b7f5ce08f;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/text/dali/internal/text-abstraction/shaping-impl.cpp b/text/dali/internal/text-abstraction/shaping-impl.cpp index 32591e0..24c542c 100644 --- a/text/dali/internal/text-abstraction/shaping-impl.cpp +++ b/text/dali/internal/text-abstraction/shaping-impl.cpp @@ -20,8 +20,8 @@ // INTERNAL INCLUDES #include -#include -#include +#include +#include #include // EXTERNAL INCLUDES @@ -29,6 +29,7 @@ #include #include +#include namespace Dali { @@ -39,31 +40,75 @@ namespace TextAbstraction namespace Internal { -const unsigned int HIGH_QUALITY_PIXEL_SIZE = 200u; // Pixel size sent to FreeType2 FT_Set_Char_Size() for high quality glyphs. const char* DEFAULT_LANGUAGE = "en"; const unsigned int DEFAULT_LANGUAGE_LENGTH = 2u; -const float TO_PIXELS = 64.f; +const float FROM_266 = 1.0f / 64.0f; const hb_script_t SCRIPT_TO_HARFBUZZ[] = { + HB_SCRIPT_COMMON, + + HB_SCRIPT_COMMON, // ASCII_DIGITS + HB_SCRIPT_COMMON, // ASCII_PS + + HB_SCRIPT_COMMON, // C1_CONTROLS + HB_SCRIPT_COMMON, // C1_PS + HB_SCRIPT_COMMON, // C1_MATH + HB_SCRIPT_COMMON, // SML_P + HB_SCRIPT_COMMON, // PHONETIC_U + HB_SCRIPT_COMMON, // PHONETIC_SS + HB_SCRIPT_COMMON, // NUMERIC_SS + HB_SCRIPT_COMMON, // LETTER_LIKE + HB_SCRIPT_COMMON, // NUMBER_FORMS + HB_SCRIPT_COMMON, // FRACTIONS_NF + HB_SCRIPT_COMMON, // NON_LATIN_LED + HB_SCRIPT_COMMON, // HWFW_S + + HB_SCRIPT_CYRILLIC, + HB_SCRIPT_GREEK, HB_SCRIPT_LATIN, + HB_SCRIPT_ARABIC, - HB_SCRIPT_DEVANAGARI, + HB_SCRIPT_HEBREW, + + HB_SCRIPT_ARMENIAN, + HB_SCRIPT_GEORGIAN, + + HB_SCRIPT_HAN, + HB_SCRIPT_HANGUL, + HB_SCRIPT_HIRAGANA, + HB_SCRIPT_KATAKANA, + HB_SCRIPT_BOPOMOFO, + HB_SCRIPT_BENGALI, - HB_SCRIPT_GURMUKHI, + HB_SCRIPT_MYANMAR, + HB_SCRIPT_DEVANAGARI, HB_SCRIPT_GUJARATI, - HB_SCRIPT_ORIYA, - HB_SCRIPT_TAMIL, - HB_SCRIPT_TELUGU, + HB_SCRIPT_GURMUKHI, HB_SCRIPT_KANNADA, HB_SCRIPT_MALAYALAM, + HB_SCRIPT_ORIYA, HB_SCRIPT_SINHALA, - HB_SCRIPT_HAN, - HB_SCRIPT_HANGUL, - HB_SCRIPT_KHMER, + HB_SCRIPT_TAMIL, + HB_SCRIPT_TELUGU, + HB_SCRIPT_LAO, HB_SCRIPT_THAI, - HB_SCRIPT_MYANMAR, + HB_SCRIPT_KHMER, + HB_SCRIPT_JAVANESE, + HB_SCRIPT_SUNDANESE, + + HB_SCRIPT_ETHIOPIC, + HB_SCRIPT_OL_CHIKI, + HB_SCRIPT_TAGALOG, + HB_SCRIPT_MEETEI_MAYEK, + + HB_SCRIPT_UNKNOWN, // EMOJI + HB_SCRIPT_UNKNOWN, // SYMBOLS1 + HB_SCRIPT_UNKNOWN, // SYMBOLS2 + HB_SCRIPT_UNKNOWN, // SYMBOLS3 + HB_SCRIPT_UNKNOWN, // SYMBOLS4 + HB_SCRIPT_UNKNOWN, // SYMBOLS5 HB_SCRIPT_UNKNOWN }; @@ -101,8 +146,16 @@ struct Shaping::Plugin mIndices.Clear(); mAdvance.Clear(); mCharacterMap.Clear(); + mOffset.Clear(); mFontId = fontId; + // Reserve some space to avoid reallocations. + const Length numberOfGlyphs = static_cast( 1.3f * static_cast( numberOfCharacters ) ); + mIndices.Reserve( numberOfGlyphs ); + mAdvance.Reserve( numberOfGlyphs ); + mCharacterMap.Reserve( numberOfGlyphs ); + mOffset.Reserve( 2u * numberOfGlyphs ); + TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); // Get the font's path file name from the font Id. @@ -118,7 +171,15 @@ struct Shaping::Plugin return 0u; } - FT_Set_Pixel_Sizes( face, HIGH_QUALITY_PIXEL_SIZE, HIGH_QUALITY_PIXEL_SIZE ); + unsigned int horizontalDpi = 0u; + unsigned int verticalDpi = 0u; + fontClient.GetDpi( horizontalDpi, verticalDpi ); + + FT_Set_Char_Size( face, + 0u, + fontClient.GetPointSize( fontId ), + horizontalDpi, + verticalDpi ); /* Get our harfbuzz font struct */ hb_font_t* harfBuzzFont; @@ -134,9 +195,13 @@ struct Shaping::Plugin hb_buffer_set_script( harfBuzzBuffer, SCRIPT_TO_HARFBUZZ[ script ] ); /* see hb-unicode.h */ - hb_buffer_set_language( harfBuzzBuffer, - hb_language_from_string( DEFAULT_LANGUAGE, - DEFAULT_LANGUAGE_LENGTH ) ); + + char* currentLocale = setlocale(LC_MESSAGES,NULL); + + std::istringstream stringStream( currentLocale ); + std::string localeString; + std::getline(stringStream, localeString, '_'); + hb_buffer_set_language( harfBuzzBuffer, hb_language_from_string( localeString.c_str(), localeString.size() ) ); /* Layout the text */ hb_buffer_add_utf32( harfBuzzBuffer, text, numberOfCharacters, 0u, numberOfCharacters ); @@ -147,17 +212,62 @@ struct Shaping::Plugin unsigned int glyphCount; hb_glyph_info_t* glyphInfo = hb_buffer_get_glyph_infos( harfBuzzBuffer, &glyphCount ); hb_glyph_position_t *glyphPositions = hb_buffer_get_glyph_positions( harfBuzzBuffer, &glyphCount ); - - const Length lastGlyphIndex = glyphCount - 1u; - for( Length i = 0u; i < glyphCount; ++i ) + const GlyphIndex lastGlyphIndex = glyphCount - 1u; + for( GlyphIndex i = 0u; i < glyphCount; ) { - // If the direction is right to left, Harfbuzz retrieves the glyphs in the visual order. - // The glyphs are needed in the logical order to layout the text in lines. - const Length index = rtlDirection ? ( lastGlyphIndex - i ) : i; - - mIndices.PushBack( glyphInfo[index].codepoint ); - mAdvance.PushBack( glyphPositions[index].x_advance / TO_PIXELS ); - mCharacterMap.PushBack( glyphInfo[index].cluster ); + if( rtlDirection ) + { + // If the direction is right to left, Harfbuzz retrieves the glyphs in the visual order. + // The glyphs are needed in the logical order to layout the text in lines. + // Do not change the order of the glyphs if they belong to the same cluster. + GlyphIndex rtlIndex = lastGlyphIndex - i; + + unsigned int cluster = glyphInfo[rtlIndex].cluster; + unsigned int previousCluster = cluster; + Length numberOfGlyphsInCluster = 0u; + + while( ( cluster == previousCluster ) ) + { + ++numberOfGlyphsInCluster; + previousCluster = cluster; + + if( rtlIndex > 0u ) + { + --rtlIndex; + + cluster = glyphInfo[rtlIndex].cluster; + } + else + { + break; + } + } + + rtlIndex = lastGlyphIndex - ( i + ( numberOfGlyphsInCluster - 1u ) ); + + for( GlyphIndex j = 0u; j < numberOfGlyphsInCluster; ++j ) + { + const GlyphIndex index = rtlIndex + j; + + mIndices.PushBack( glyphInfo[index].codepoint ); + mAdvance.PushBack( floor( glyphPositions[index].x_advance * FROM_266 ) ); + mCharacterMap.PushBack( glyphInfo[index].cluster ); + mOffset.PushBack( floor( glyphPositions[index].x_offset * FROM_266 ) ); + mOffset.PushBack( floor( glyphPositions[index].y_offset * FROM_266 ) ); + } + + i += numberOfGlyphsInCluster; + } + else + { + mIndices.PushBack( glyphInfo[i].codepoint ); + mAdvance.PushBack( floor( glyphPositions[i].x_advance * FROM_266 ) ); + mCharacterMap.PushBack( glyphInfo[i].cluster ); + mOffset.PushBack( floor( glyphPositions[i].x_offset * FROM_266 ) ); + mOffset.PushBack( floor( glyphPositions[i].y_offset * FROM_266 ) ); + + ++i; + } } /* Cleanup */ @@ -173,9 +283,10 @@ struct Shaping::Plugin { Vector::ConstIterator indicesIt = mIndices.Begin(); Vector::ConstIterator advanceIt = mAdvance.Begin(); + Vector::ConstIterator offsetIt = mOffset.Begin(); Vector::ConstIterator characterMapIt = mCharacterMap.Begin(); - for( Length index = 0u, size = mIndices.Count(); index < size; ++index ) + for( GlyphIndex index = 0u, size = mIndices.Count(); index < size; ++index ) { GlyphInfo& glyph = *( glyphInfo + index ); CharacterIndex& glyphToCharacter = *( glyphToCharacterMap + index ); @@ -184,6 +295,10 @@ struct Shaping::Plugin glyph.index = *( indicesIt + index ); glyph.advance = *( advanceIt + index ); + const GlyphIndex offsetIndex = 2u * index; + glyph.xBearing = *( offsetIt + offsetIndex ); + glyph.yBearing = *( offsetIt + offsetIndex + 1u ); + glyphToCharacter = *( characterMapIt + index ); } } @@ -192,6 +307,7 @@ struct Shaping::Plugin Vector mIndices; Vector mAdvance; + Vector mOffset; Vector mCharacterMap; FontId mFontId; };