Moved SingletonService into dali-core
[platform/core/uifw/dali-adaptor.git] / dali / internal / text / text-abstraction / shaping-impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index f72475f..b785c02
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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,7 +19,6 @@
 #include <dali/internal/text/text-abstraction/shaping-impl.h>
 
 // INTERNAL INCLUDES
-#include <dali/internal/system/common/singleton-service-impl.h>
 #include <dali/devel-api/text-abstraction/font-client.h>
 #include <dali/devel-api/text-abstraction/glyph-info.h>
 #include <dali/integration-api/debug.h>
 // EXTERNAL INCLUDES
 #include <harfbuzz/hb.h>
 #include <harfbuzz/hb-ft.h>
+#include <dali/devel-api/common/singleton-service.h>
+
+namespace
+{
+
+#if defined(DEBUG_ENABLED)
+Dali::Integration::Log::Filter* gLogFilter = Dali::Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_FONT_CLIENT");
+#endif
+
+}
 
 namespace Dali
 {
@@ -136,119 +145,160 @@ struct Shaping::Plugin
     mOffset.Clear();
     mFontId = fontId;
 
-    // Reserve some space to avoid reallocations.
-    const Length numberOfGlyphs = static_cast<Length>( 1.3f * static_cast<float>( numberOfCharacters ) );
-    mIndices.Reserve( numberOfGlyphs );
-    mAdvance.Reserve( numberOfGlyphs );
-    mCharacterMap.Reserve( numberOfGlyphs );
-    mOffset.Reserve( 2u * numberOfGlyphs );
-
     TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
     TextAbstraction::Internal::FontClient& fontClientImpl = TextAbstraction::GetImplementation( fontClient );
 
-    // Create a FreeType font's face.
-    FT_Face face;
+    const FontDescription::Type type = fontClientImpl.GetFontType( fontId );
 
-    face = fontClientImpl.GetFreetypeFace( fontId );
-    if( nullptr == face )
+    switch( type )
     {
-      // Nothing to do if the face is null.
-      return 0u;
-    }
+      case FontDescription::FACE_FONT:
+      {
+        // Reserve some space to avoid reallocations.
+        const Length numberOfGlyphs = static_cast<Length>( 1.3f * static_cast<float>( numberOfCharacters ) );
+        mIndices.Reserve( numberOfGlyphs );
+        mAdvance.Reserve( numberOfGlyphs );
+        mCharacterMap.Reserve( numberOfGlyphs );
+        mOffset.Reserve( 2u * numberOfGlyphs );
+
+        // Retrieve a FreeType font's face.
+        FT_Face face = fontClientImpl.GetFreetypeFace( fontId );
+        if( nullptr == face )
+        {
+          // Nothing to do if the face is null.
+          return 0u;
+        }
 
-    /* Get our harfbuzz font struct */
-    hb_font_t* harfBuzzFont;
-    harfBuzzFont = hb_ft_font_create( face, NULL );
+        unsigned int horizontalDpi = 0u;
+        unsigned int verticalDpi = 0u;
+        fontClient.GetDpi( horizontalDpi, verticalDpi );
 
-    /* Create a buffer for harfbuzz to use */
-    hb_buffer_t* harfBuzzBuffer = hb_buffer_create();
+        FT_Set_Char_Size( face,
+                          0u,
+                          fontClient.GetPointSize( fontId ),
+                          horizontalDpi,
+                          verticalDpi );
 
-    const bool rtlDirection = IsRightToLeftScript( script );
-    hb_buffer_set_direction( harfBuzzBuffer,
-                             rtlDirection ? HB_DIRECTION_RTL : HB_DIRECTION_LTR ); /* or LTR */
+        /* Get our harfbuzz font struct */
+        hb_font_t* harfBuzzFont;
+        harfBuzzFont = hb_ft_font_create( face, NULL );
 
-    hb_buffer_set_script( harfBuzzBuffer,
-                          SCRIPT_TO_HARFBUZZ[ script ] ); /* see hb-unicode.h */
+        /* Create a buffer for harfbuzz to use */
+        hb_buffer_t* harfBuzzBuffer = hb_buffer_create();
 
+        const bool rtlDirection = IsRightToLeftScript( script );
+        hb_buffer_set_direction( harfBuzzBuffer,
+                                 rtlDirection ? HB_DIRECTION_RTL : HB_DIRECTION_LTR ); /* or LTR */
 
-    char* currentLocale = setlocale(LC_MESSAGES,NULL);
+        hb_buffer_set_script( harfBuzzBuffer,
+                              SCRIPT_TO_HARFBUZZ[ script ] ); /* see hb-unicode.h */
 
-    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 );
+        char* currentLocale = setlocale(LC_MESSAGES,NULL);
 
-    hb_shape( harfBuzzFont, harfBuzzBuffer, NULL, 0u );
+        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() ) );
 
-    /* Get glyph data */
-    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 GlyphIndex lastGlyphIndex = glyphCount - 1u;
-    for( GlyphIndex i = 0u; i < glyphCount; )
-    {
-      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;
+        /* Layout the text */
+        hb_buffer_add_utf32( harfBuzzBuffer, text, numberOfCharacters, 0u, numberOfCharacters );
 
-        unsigned int cluster = glyphInfo[rtlIndex].cluster;
-        unsigned int previousCluster = cluster;
-        Length numberOfGlyphsInCluster = 0u;
+        hb_shape( harfBuzzFont, harfBuzzBuffer, NULL, 0u );
 
-        while( ( cluster == previousCluster ) )
-        {
-          ++numberOfGlyphsInCluster;
-          previousCluster = cluster;
+        /* Get glyph data */
+        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 GlyphIndex lastGlyphIndex = glyphCount - 1u;
 
-          if( rtlIndex > 0u )
+        for( GlyphIndex i = 0u; i < glyphCount; )
+        {
+          if( rtlDirection )
           {
-            --rtlIndex;
-
-            cluster = glyphInfo[rtlIndex].cluster;
+            // 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
           {
-            break;
+            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;
           }
         }
 
-        rtlIndex = lastGlyphIndex - ( i + ( numberOfGlyphsInCluster - 1u ) );
-
-        for( GlyphIndex j = 0u; j < numberOfGlyphsInCluster; ++j )
+        /* Cleanup */
+        hb_buffer_destroy( harfBuzzBuffer );
+        hb_font_destroy( harfBuzzFont );
+        break;
+      }
+      case FontDescription::BITMAP_FONT:
+      {
+        // Reserve some space to avoid reallocations.
+        // The advance and offset tables can be initialized with zeros as it's not needed to get metrics from the bitmaps here.
+        mIndices.Resize( numberOfCharacters );
+        mAdvance.Resize( numberOfCharacters, 0u );
+        mCharacterMap.Reserve( numberOfCharacters );
+        mOffset.Resize( 2u * numberOfCharacters, 0.f );
+
+        // The utf32 character can be used as the glyph's index.
+        std::copy( text, text + numberOfCharacters, mIndices.Begin() );
+
+        // The glyph to character map is 1 to 1.
+        for( unsigned int index = 0u; index < numberOfCharacters; ++index )
         {
-          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 ) );
+          mCharacterMap.PushBack( index );
         }
-
-        i += numberOfGlyphsInCluster;
+        break;
       }
-      else
+      default:
       {
-        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;
+        DALI_LOG_INFO(gLogFilter, Debug::General, "  Invalid type of font\n");
       }
     }
 
-    /* Cleanup */
-    hb_buffer_destroy( harfBuzzBuffer );
-    hb_font_destroy( harfBuzzFont );
-
     return mIndices.Count();
   }