Scaling feature for fixed-size fonts 63/46663/10
authorPaul Wisbey <p.wisbey@samsung.com>
Mon, 24 Aug 2015 13:59:50 +0000 (14:59 +0100)
committerPaul Wisbey <p.wisbey@samsung.com>
Wed, 26 Aug 2015 16:21:02 +0000 (09:21 -0700)
Change-Id: If882e9ceee65e657b47fe5e54534975f684d20b8

dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/text/layouts/layout-engine.cpp
dali-toolkit/internal/text/layouts/layout-engine.h
dali-toolkit/internal/text/metrics.h [new file with mode: 0644]
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp

index d633e9b..10d87a7 100644 (file)
@@ -234,7 +234,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         if( impl.mController )
         {
           const float pointSize = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_STYLE %f\n", impl.mController.Get(), pointSize );
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
 
           if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
           {
index 5ee4992..9062b07 100644 (file)
@@ -105,7 +105,6 @@ struct LayoutEngine::Impl
     mCursorWidth( CURSOR_WIDTH ),
     mEllipsisEnabled( false )
   {
-    mFontClient = TextAbstraction::FontClient::Get();
   }
 
   /**
@@ -117,7 +116,7 @@ struct LayoutEngine::Impl
   void UpdateLineHeight( FontId fontId, LineLayout& lineLayout )
   {
     Text::FontMetrics fontMetrics;
-    mFontClient.GetFontMetrics( fontId, fontMetrics );
+    mMetrics->GetFontMetrics( fontId, fontMetrics );
 
     // Sets the maximum ascender.
     if( fontMetrics.ascender > lineLayout.ascender )
@@ -634,7 +633,7 @@ struct LayoutEngine::Impl
           const GlyphInfo& glyphInfo = *( layoutParameters.glyphsBuffer + layoutParameters.totalNumberOfGlyphs - 1u );
 
           Text::FontMetrics fontMetrics;
-          mFontClient.GetFontMetrics( glyphInfo.fontId, fontMetrics );
+          mMetrics->GetFontMetrics( glyphInfo.fontId, fontMetrics );
 
           LineRun lineRun;
           lineRun.glyphRun.glyphIndex = 0u;
@@ -821,7 +820,7 @@ struct LayoutEngine::Impl
   LayoutEngine::VerticalAlignment mVerticalAlignment;
   float mCursorWidth;
 
-  TextAbstraction::FontClient mFontClient;
+  IntrusivePtr<Metrics> mMetrics;
 
   bool mEllipsisEnabled:1;
 };
@@ -837,6 +836,11 @@ LayoutEngine::~LayoutEngine()
   delete mImpl;
 }
 
+void LayoutEngine::SetMetrics( MetricsPtr& metrics )
+{
+  mImpl->mMetrics = metrics;
+}
+
 void LayoutEngine::SetLayout( Layout layout )
 {
   mImpl->mLayout = layout;
index d0f1ab6..f866f3e 100644 (file)
@@ -24,6 +24,7 @@
 
 // INTERNAL INCLUDE
 #include <dali-toolkit/internal/text/line-run.h>
+#include <dali-toolkit/internal/text/metrics.h>
 
 namespace Dali
 {
@@ -74,6 +75,13 @@ public:
   ~LayoutEngine();
 
   /**
+   * @brief Provide the wrapper around FontClient used to get metrics
+   *
+   * @param[in] metrics Used to get metrics
+   */
+  void SetMetrics( MetricsPtr& metrics );
+
+  /**
    * @brief Choose the required layout.
    *
    * @param[in] layout The required layout.
diff --git a/dali-toolkit/internal/text/metrics.h b/dali-toolkit/internal/text/metrics.h
new file mode 100644 (file)
index 0000000..147ae79
--- /dev/null
@@ -0,0 +1,134 @@
+#ifndef __DALI_TOOLKIT_TEXT_METRICS_H__
+#define __DALI_TOOLKIT_TEXT_METRICS_H__
+
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/devel-api/text-abstraction/font-client.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+class Metrics;
+typedef IntrusivePtr<Metrics> MetricsPtr;
+
+/**
+ * @brief A wrapper around FontClient used to get metrics & potentially down-scaled Emoji metrics.
+ */
+class Metrics : public RefObject
+{
+public:
+
+  /**
+   * Create a new Metrics object
+   */
+  static Metrics* New( TextAbstraction::FontClient& fontClient )
+  {
+    return new Metrics( fontClient );
+  }
+
+  /**
+   * @brief Set the maximum Emoji size.
+   *
+   * @param[in] emojiSize Emoticons will be scaled to fit this size in pixels.
+   */
+  void SetMaxEmojiSize( int emojiSize )
+  {
+    mEmojiSize = emojiSize;
+  }
+
+  /**
+   * @brief Get the maximum Emoji size.
+   *
+   * @return The maximum Emoji size.
+   */
+  int GetMaxEmojiSize() const
+  {
+    return mEmojiSize;
+  }
+
+  /**
+   * @brief Query the metrics for a font.
+   *
+   * @param[in] fontId The ID of the font for the required glyph.
+   * @param[out] metrics The font metrics.
+   */
+  void GetFontMetrics( FontId fontId, FontMetrics& metrics )
+  {
+    mFontClient.GetFontMetrics( fontId, metrics, mEmojiSize ); // inline for performance
+  }
+
+  /**
+   * @brief Retrieve the metrics for a series of glyphs.
+   *
+   * @param[in,out] array An array of glyph-info structures with initialized FontId & GlyphIndex values.
+   * It may contain the advance and an offset set into the bearing from the shaping tool.
+   * On return, the glyph's size value will be initialized. The bearing value will be updated by adding the font's glyph bearing to the one set by the shaping tool.
+   * @param[in] size The size of the array.
+   * @return True if all of the requested metrics were found.
+   */
+  bool GetGlyphMetrics( GlyphInfo* array, uint32_t size )
+  {
+    return mFontClient.GetGlyphMetrics( array, size, true, mEmojiSize ); // inline for performance
+  }
+
+protected:
+
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~Metrics() {}
+
+private:
+
+  /**
+   * Constructor.
+   */
+  Metrics( TextAbstraction::FontClient& fontClient )
+  : mFontClient( fontClient ),
+    mEmojiSize( 0 )
+  {
+  }
+
+  // Undefined
+  Metrics(const Metrics&);
+
+  // Undefined
+  Metrics& operator=(const Metrics& rhs);
+
+private:
+
+  TextAbstraction::FontClient mFontClient;
+
+  int mEmojiSize;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_METRICS_H__
index a4fc1d8..026b4d6 100644 (file)
@@ -331,6 +331,16 @@ struct AtlasRenderer::Impl : public ConnectionTracker
         textCacheEntry.mIndex = glyph.index;
         newTextCache.PushBack( textCacheEntry );
 
+        // Adjust the vertices if the fixed-size font should be down-scaled
+        if( glyph.scaleFactor > 0 )
+        {
+          for( unsigned int i=0; i<newMesh.mVertices.Count(); ++i )
+          {
+            newMesh.mVertices[i].mPosition.x = position.x + ( ( newMesh.mVertices[i].mPosition.x - position.x ) * glyph.scaleFactor );
+            newMesh.mVertices[i].mPosition.y = position.y + ( ( newMesh.mVertices[i].mPosition.y - position.y ) * glyph.scaleFactor );
+          }
+        }
+
         // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
         StitchTextMesh( meshContainer,
                         newMesh,
index 5e64f87..f90d014 100644 (file)
@@ -78,20 +78,20 @@ namespace Text
  * @param[in] numberOfGlyphs The number of glyphs.
  * @param[out] glyphMetrics Some glyph metrics (font height, advance, ascender and x bearing).
  * @param[in] visualModel The visual model.
- * @param[in] fontClient The font client.
+ * @param[in] metrics Used to access metrics from FontClient.
  */
 void GetGlyphsMetrics( GlyphIndex glyphIndex,
                        Length numberOfGlyphs,
                        GlyphMetrics& glyphMetrics,
-                       VisualModelPtr visualModel,
-                       TextAbstraction::FontClient& fontClient )
+                       VisualModelPtr& visualModel,
+                       MetricsPtr& metrics )
 {
   const GlyphInfo* glyphsBuffer = visualModel->mGlyphs.Begin();
 
   const GlyphInfo& firstGlyph = *( glyphsBuffer + glyphIndex );
 
   Text::FontMetrics fontMetrics;
-  fontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics );
+  metrics->GetFontMetrics( firstGlyph.fontId, fontMetrics );
 
   glyphMetrics.fontHeight = fontMetrics.height;
   glyphMetrics.advance = firstGlyph.advance;
@@ -423,7 +423,7 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired )
   if( GET_GLYPH_METRICS & operations )
   {
     GlyphInfo* glyphsBuffer = glyphs.Begin();
-    mFontClient.GetGlyphMetrics( glyphsBuffer, numberOfGlyphs );
+    mMetrics->GetGlyphMetrics( glyphsBuffer, numberOfGlyphs );
 
     // Update the width and advance of all new paragraph characters.
     for( Vector<GlyphIndex>::ConstIterator it = newParagraphGlyphs.Begin(), endIt = newParagraphGlyphs.End(); it != endIt; ++it )
@@ -487,7 +487,7 @@ float Controller::Impl::GetDefaultFontLineHeight()
   }
 
   Text::FontMetrics fontMetrics;
-  mFontClient.GetFontMetrics( defaultFontId, fontMetrics );
+  mMetrics->GetFontMetrics( defaultFontId, fontMetrics );
 
   return( fontMetrics.ascender - fontMetrics.descender );
 }
@@ -1462,7 +1462,7 @@ CharacterIndex Controller::Impl::GetClosestCursorIndex( float visualX,
                       numberOfGlyphs,
                       glyphMetrics,
                       mVisualModel,
-                      mFontClient );
+                      mMetrics );
 
     const Vector2& position = *( positionsBuffer + glyphLogicalOrderIndex );
 
@@ -1601,7 +1601,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
                     primaryNumberOfGlyphs,
                     glyphMetrics,
                     mVisualModel,
-                    mFontClient );
+                    mMetrics );
 
   // Whether to add the glyph's advance to the cursor position.
   // i.e if the paragraph is left to right and the logical cursor is zero, the position is the position of the first glyph and the advance is not added,
@@ -1691,7 +1691,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
                       secondaryNumberOfGlyphs,
                       glyphMetrics,
                       mVisualModel,
-                      mFontClient );
+                      mMetrics );
 
     // Set the secondary cursor's position.
     cursorInfo.secondaryPosition.x = -glyphMetrics.xBearing + secondaryPosition.x + ( isCurrentRightToLeft ? 0.f : glyphMetrics.advance );
@@ -1777,7 +1777,7 @@ void Controller::Impl::UpdateCursorPosition()
     }
 
     Text::FontMetrics fontMetrics;
-    mFontClient.GetFontMetrics( defaultFontId, fontMetrics );
+    mMetrics->GetFontMetrics( defaultFontId, fontMetrics );
 
     lineHeight = fontMetrics.ascender - fontMetrics.descender;
 
index 3073611..5054e8b 100644 (file)
@@ -207,6 +207,7 @@ struct Controller::Impl
     mFontClient(),
     mClipboard(),
     mView(),
+    mMetrics(),
     mLayoutEngine(),
     mModifyEvents(),
     mTextColor( Color::BLACK ),
@@ -223,6 +224,10 @@ struct Controller::Impl
 
     mView.SetVisualModel( mVisualModel );
 
+    // Use this to access FontClient i.e. to get down-scaled Emoji metrics.
+    mMetrics = Metrics::New( mFontClient );
+    mLayoutEngine.SetMetrics( mMetrics );
+
     // Set the text properties to default
     mVisualModel->SetUnderlineEnabled( false );
     mVisualModel->SetUnderlineHeight( 0.0f );
@@ -468,8 +473,9 @@ struct Controller::Impl
   FontDefaults* mFontDefaults;             ///< Avoid allocating this when the user does not specify a font.
   EventData* mEventData;                   ///< Avoid allocating everything for text input until EnableTextInput().
   TextAbstraction::FontClient mFontClient; ///< Handle to the font client.
-  Clipboard mClipboard;                   ///< Handle to the system clipboard
+  Clipboard mClipboard;                    ///< Handle to the system clipboard
   View mView;                              ///< The view interface to the rendering back-end.
+  MetricsPtr mMetrics;                     ///< A wrapper around FontClient used to get metrics & potentially down-scaled Emoji metrics.
   LayoutEngine mLayoutEngine;              ///< The layout engine.
   std::vector<ModifyEvent> mModifyEvents;  ///< Temporary stores the text set until the next relayout.
   Vector4 mTextColor;                      ///< The regular text color
index e3b29bd..86f0090 100644 (file)
@@ -38,6 +38,7 @@ namespace
 #endif
 
 const float MAX_FLOAT = std::numeric_limits<float>::max();
+const unsigned int POINTS_PER_INCH = 72;
 
 const std::string EMPTY_STRING("");
 
@@ -287,6 +288,15 @@ void Controller::SetDefaultPointSize( float pointSize )
 
   mImpl->mFontDefaults->mDefaultPointSize = pointSize;
 
+  unsigned int horizontalDpi( 0u );
+  unsigned int verticalDpi( 0u );
+  mImpl->mFontClient.GetDpi( horizontalDpi, verticalDpi );
+
+  // Adjust the metrics if the fixed-size font should be down-scaled
+  int maxEmojiSize( pointSize/POINTS_PER_INCH * verticalDpi );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultPointSize %p setting MaxEmojiSize %d\n", this, maxEmojiSize );
+  mImpl->mMetrics->SetMaxEmojiSize( maxEmojiSize );
+
   // Clear the font-specific data
   ClearFontData();