SvgVisual: Using VectorImageRenderer 73/240173/36
authorJunsuChoi <jsuya.choi@samsung.com>
Tue, 28 Jul 2020 06:32:37 +0000 (15:32 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Tue, 22 Sep 2020 01:48:42 +0000 (10:48 +0900)
Make SvgVisual use VectorImageRenderer which is using ThorVG.
You can use nanosvg or thorVG by NO_THORVG macro define.

[Note]
If you want to use THORVG, remove below from ./build/tizen/CMakeLists.txt
...
ADD_DEFINITIONS( "-DNO_THORVG" )
...

Change-Id: Ia9bf5c799084e841ff567245a8ff4688824277ee

automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp [new file with mode: 0644]
build/tizen/CMakeLists.txt
dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp
dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.h
dali-toolkit/internal/visuals/visual-factory-cache.cpp

index bbb53b3..851ca00 100755 (executable)
@@ -55,6 +55,7 @@ LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-timer.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-tts-player.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-timer.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-tts-player.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
+   ../dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder.cpp
    ../dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder.cpp
    ../dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp
index d7b4a5b..d889c6f 100755 (executable)
@@ -95,6 +95,7 @@ LIST(APPEND TC_SOURCES
   dali-toolkit-test-utils/toolkit-tts-player.cpp
   dali-toolkit-test-utils/toolkit-native-image-source.cpp
   dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
   dali-toolkit-test-utils/toolkit-tts-player.cpp
   dali-toolkit-test-utils/toolkit-native-image-source.cpp
   dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
+  dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp
   dali-toolkit-test-utils/toolkit-video-player.cpp
   dali-toolkit-test-utils/toolkit-web-engine.cpp
   dali-toolkit-test-utils/toolkit-window.cpp
   dali-toolkit-test-utils/toolkit-video-player.cpp
   dali-toolkit-test-utils/toolkit-web-engine.cpp
   dali-toolkit-test-utils/toolkit-window.cpp
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp
new file mode 100644 (file)
index 0000000..3513410
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2020 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.
+ *
+ */
+
+#include <dali/devel-api/adaptor-framework/vector-image-renderer.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/rendering/renderer.h>
+#include <toolkit-application.h>
+#include <toolkit-event-thread-callback.h>
+#include <memory>
+#include <sys/stat.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+class VectorImageRenderer: public Dali::BaseObject
+{
+public:
+
+  VectorImageRenderer()
+  : mUrl(),
+    mRenderer(),
+    mWidth( 0 ),
+    mHeight( 0 )
+  {
+  }
+
+  ~VectorImageRenderer()
+  {
+  }
+
+  bool Render( float scale )
+  {
+     return true;
+  }
+
+  void SetBuffer( Dali::Devel::PixelBuffer &buffer )
+  {
+  }
+
+  bool Load( const std::string& url )
+  {
+    struct stat sb;
+    if ( stat(url.c_str(), &sb) == 0 )
+    {
+      return true;
+    }
+
+    return false;
+  }
+
+  bool Load( const char *data, uint32_t size )
+  {
+    return true;
+  }
+
+  void GetDefaultSize( uint32_t& width, uint32_t& height ) const
+  {
+    width = 100;
+    height = 100;
+  }
+
+public:
+
+  std::string mUrl;
+  Dali::Renderer mRenderer;
+  uint32_t mWidth;
+  uint32_t mHeight;
+};
+
+inline VectorImageRenderer& GetImplementation( Dali::VectorImageRenderer& renderer )
+{
+  DALI_ASSERT_ALWAYS( renderer && "VectorImageRenderer handle is empty." );
+  BaseObject& handle = renderer.GetBaseObject();
+  return static_cast< Internal::Adaptor::VectorImageRenderer& >( handle );
+}
+
+inline const VectorImageRenderer& GetImplementation( const Dali::VectorImageRenderer& renderer )
+{
+  DALI_ASSERT_ALWAYS( renderer && "VectorImageRenderer handle is empty." );
+  const BaseObject& handle = renderer.GetBaseObject();
+  return static_cast< const Internal::Adaptor::VectorImageRenderer& >( handle );
+}
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+
+/********************************************************************************/
+/*********************************  PUBLIC CLASS  *******************************/
+/********************************************************************************/
+
+VectorImageRenderer VectorImageRenderer::New()
+{
+  Internal::Adaptor::VectorImageRenderer* imageRenderer = new Internal::Adaptor::VectorImageRenderer();
+
+  return VectorImageRenderer( imageRenderer );
+}
+
+VectorImageRenderer::VectorImageRenderer()
+{
+}
+
+VectorImageRenderer::~VectorImageRenderer()
+{
+}
+
+VectorImageRenderer::VectorImageRenderer( Internal::Adaptor::VectorImageRenderer* internal )
+: BaseHandle( internal )
+{
+}
+
+void VectorImageRenderer::SetBuffer( Dali::Devel::PixelBuffer &buffer )
+{
+  Internal::Adaptor::GetImplementation( *this ).SetBuffer( buffer );
+}
+
+bool VectorImageRenderer::Render( float scale )
+{
+  return Internal::Adaptor::GetImplementation( *this ).Render( scale );
+}
+
+bool VectorImageRenderer::Load( const std::string& url )
+{
+  return Internal::Adaptor::GetImplementation( *this ).Load( url );
+}
+
+bool VectorImageRenderer::Load( const char *data, uint32_t size )
+{
+  return Internal::Adaptor::GetImplementation( *this ).Load( data, size );
+}
+
+void VectorImageRenderer::GetDefaultSize( uint32_t& width, uint32_t& height ) const
+{
+  Internal::Adaptor::GetImplementation( *this ).GetDefaultSize( width, height );
+}
+
+} // namespace Dali
index d122fd5..21b7c0f 100644 (file)
@@ -154,6 +154,9 @@ IF( ENABLE_TRACE )
   ADD_DEFINITIONS("-DTRACE_ENABLED")
 ENDIF()
 
   ADD_DEFINITIONS("-DTRACE_ENABLED")
 ENDIF()
 
+# Remove below when thorvg is ready
+ADD_DEFINITIONS( "-DNO_THORVG" )
+
 # Set paths
 SET( toolkit_images_dir  ${ROOT_SRC_DIR}/dali-toolkit/styles/images-common )
 SET( toolkit_sounds_dir  ${ROOT_SRC_DIR}/dali-toolkit/sounds )
 # Set paths
 SET( toolkit_images_dir  ${ROOT_SRC_DIR}/dali-toolkit/styles/images-common )
 SET( toolkit_sounds_dir  ${ROOT_SRC_DIR}/dali-toolkit/sounds )
index f0dc4a4..151eda8 100644 (file)
@@ -24,7 +24,9 @@
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
+#ifdef NO_THORVG
 #include <dali-toolkit/third-party/nanosvg/nanosvgrast.h>
 #include <dali-toolkit/third-party/nanosvg/nanosvgrast.h>
+#endif /* NO_THORVG */
 #include <dali-toolkit/internal/visuals/svg/svg-visual.h>
 
 namespace Dali
 #include <dali-toolkit/internal/visuals/svg/svg-visual.h>
 
 namespace Dali
@@ -41,6 +43,7 @@ namespace
 const char * const UNITS("px");
 }
 
 const char * const UNITS("px");
 }
 
+#ifdef NO_THORVG
 RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, const VisualUrl& url, float dpi, unsigned int width, unsigned int height)
 : mSvgVisual( svgRenderer ),
   mParsedSvg( parsedSvg ),
 RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, const VisualUrl& url, float dpi, unsigned int width, unsigned int height)
 : mSvgVisual( svgRenderer ),
   mParsedSvg( parsedSvg ),
@@ -51,14 +54,30 @@ RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg,
 {
   mRasterizer = nsvgCreateRasterizer();
 }
 {
   mRasterizer = nsvgCreateRasterizer();
 }
+#else /* NO_THORVG */
+RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height, bool loaded)
+: mSvgVisual( svgRenderer ),
+  mVectorRenderer( vectorRenderer ),
+  mUrl( url ),
+  mDpi( dpi ),
+  mWidth( width ),
+  mHeight( height ),
+  mLoaded( loaded )
+{
+
+}
+#endif /* NO_THORVG */
 
 RasterizingTask::~RasterizingTask()
 {
 
 RasterizingTask::~RasterizingTask()
 {
+#ifdef NO_THORVG
   nsvgDeleteRasterizer( mRasterizer );
   nsvgDeleteRasterizer( mRasterizer );
+#endif /* NO_THORVG */
 }
 
 void RasterizingTask::Load()
 {
 }
 
 void RasterizingTask::Load()
 {
+#ifdef NO_THORVG
   if( mParsedSvg != NULL)
   {
     return;
   if( mParsedSvg != NULL)
   {
     return;
@@ -77,10 +96,33 @@ void RasterizingTask::Load()
     remoteBuffer.PushBack( '\0' );
     mParsedSvg = nsvgParse( reinterpret_cast<char*>(remoteBuffer.begin()), UNITS, mDpi );
   }
     remoteBuffer.PushBack( '\0' );
     mParsedSvg = nsvgParse( reinterpret_cast<char*>(remoteBuffer.begin()), UNITS, mDpi );
   }
+#else /* NO_THORVG */
+  if( !mLoaded &&  !mUrl.IsLocalResource() )
+  {
+    Dali::Vector<uint8_t> remoteBuffer;
+
+    if( !Dali::FileLoader::DownloadFileSynchronously( mUrl.GetUrl(), remoteBuffer ))
+    {
+      DALI_LOG_ERROR("Failed to download file!\n");
+      return;
+    }
+
+    remoteBuffer.PushBack( '\0' );
+    char *data = reinterpret_cast<char*>(remoteBuffer.begin());
+    if ( !mVectorRenderer.Load( data, remoteBuffer.Size()))
+    {
+      DALI_LOG_ERROR( "Failed to load data!\n" );
+      return;
+    }
+
+    mLoaded = true;
+  }
+#endif /* NO_THORVG */
 }
 
 void RasterizingTask::Rasterize( )
 {
 }
 
 void RasterizingTask::Rasterize( )
 {
+#ifdef NO_THORVG
   if( mParsedSvg != NULL && mWidth > 0u && mHeight > 0u )
   {
     float scaleX = static_cast<float>( mWidth ) /  mParsedSvg->width;
   if( mParsedSvg != NULL && mWidth > 0u && mHeight > 0u )
   {
     float scaleX = static_cast<float>( mWidth ) /  mParsedSvg->width;
@@ -96,12 +138,54 @@ void RasterizingTask::Rasterize( )
 
     mPixelData = Dali::PixelData::New( buffer, bufferSize, mWidth, mHeight, Pixel::RGBA8888, Dali::PixelData::DELETE_ARRAY );
   }
 
     mPixelData = Dali::PixelData::New( buffer, bufferSize, mWidth, mHeight, Pixel::RGBA8888, Dali::PixelData::DELETE_ARRAY );
   }
+#else /* NO_THORVG */
+  if ( mWidth <= 0u || mHeight <= 0u )
+  {
+    DALI_LOG_ERROR( "Size is zero!\n" );
+    return;
+  }
+
+  Devel::PixelBuffer pixelBuffer = Devel::PixelBuffer::New( mWidth, mHeight, Dali::Pixel::RGBA8888 );
+  mVectorRenderer.SetBuffer( pixelBuffer );
+  {
+    uint32_t defaultWidth, defaultHeight;
+    mVectorRenderer.GetDefaultSize( defaultWidth, defaultHeight );
+
+    float scaleX = static_cast<float>( mWidth ) / static_cast<float>( defaultWidth );
+    float scaleY = static_cast<float>( mHeight ) / static_cast<float>( defaultHeight );
+    float scale = scaleX < scaleY ? scaleX : scaleY;
+
+    if ( !mVectorRenderer.Render( scale ) )
+    {
+      DALI_LOG_ERROR( "SVG Render Fail!\n" );
+      return;
+    }
+
+    mPixelData = Devel::PixelBuffer::Convert( pixelBuffer );
+    if ( !mPixelData )
+    {
+      DALI_LOG_ERROR( "Pixel Data is null\n" );
+    }
+  }
+#endif /* NO_THORVG */
 }
 
 }
 
+#ifdef NO_THORVG
 NSVGimage* RasterizingTask::GetParsedImage() const
 {
   return mParsedSvg;
 }
 NSVGimage* RasterizingTask::GetParsedImage() const
 {
   return mParsedSvg;
 }
+#else /* NO_THORVG */
+VectorImageRenderer RasterizingTask::GetVectorRenderer() const
+{
+  return mVectorRenderer;
+}
+
+bool RasterizingTask::IsLoaded() const
+{
+  return mLoaded;
+}
+#endif /* NO_THORVG */
 
 SvgVisual* RasterizingTask::GetSvgVisual() const
 {
 
 SvgVisual* RasterizingTask::GetSvgVisual() const
 {
@@ -203,6 +287,7 @@ void SvgRasterizeThread::RemoveTask( SvgVisual* visual )
   }
 }
 
   }
 }
 
+#ifdef NO_THORVG
 void SvgRasterizeThread::DeleteImage( NSVGimage* parsedSvg )
 {
   // Lock while adding image to the delete queue
 void SvgRasterizeThread::DeleteImage( NSVGimage* parsedSvg )
 {
   // Lock while adding image to the delete queue
@@ -217,6 +302,22 @@ void SvgRasterizeThread::DeleteImage( NSVGimage* parsedSvg )
     mDeleteSvg.PushBack( parsedSvg );
   }
 }
     mDeleteSvg.PushBack( parsedSvg );
   }
 }
+#else /* NO_THORVG */
+void SvgRasterizeThread::DeleteImage( VectorImageRenderer vectorRenderer )
+{
+  // Lock while adding image to the delete queue
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+
+  if( mIsThreadWaiting ) // no rasterization is ongoing, save to delete
+  {
+    // TODO: what?
+  }
+  else // wait to delete until current rasterization completed.
+  {
+    mDeleteSvg.PushBack( &vectorRenderer );
+  }
+}
+#endif /* NO_THORVG */
 
 RasterizingTaskPtr SvgRasterizeThread::NextTaskToProcess()
 {
 
 RasterizingTaskPtr SvgRasterizeThread::NextTaskToProcess()
 {
@@ -226,12 +327,14 @@ RasterizingTaskPtr SvgRasterizeThread::NextTaskToProcess()
   // Delete the image here to make sure that it is not used in the nsvgRasterize()
   if( !mDeleteSvg.Empty() )
   {
   // Delete the image here to make sure that it is not used in the nsvgRasterize()
   if( !mDeleteSvg.Empty() )
   {
+#ifdef NO_THORVG
     for( Vector< NSVGimage* >::Iterator it = mDeleteSvg.Begin(), endIt = mDeleteSvg.End();
         it != endIt;
         ++it )
     {
       nsvgDelete( *it );
     }
     for( Vector< NSVGimage* >::Iterator it = mDeleteSvg.Begin(), endIt = mDeleteSvg.End();
         it != endIt;
         ++it )
     {
       nsvgDelete( *it );
     }
+#endif /* NO_THORVG */
     mDeleteSvg.Clear();
   }
 
     mDeleteSvg.Clear();
   }
 
index 11fa03f..5c8b323 100644 (file)
 #include <dali/public-api/rendering/texture-set.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
 
 #include <dali/public-api/rendering/texture-set.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
 
+#ifdef NO_THORVG
 struct NSVGimage;
 struct NSVGrasterizer;
 struct NSVGimage;
 struct NSVGrasterizer;
+#else /* NO_THORVG */
+#include <string.h>
+#include <dali/devel-api/adaptor-framework/vector-image-renderer.h>
+#endif /* NO_THORVG */
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -58,6 +63,7 @@ typedef IntrusivePtr< RasterizingTask > RasterizingTaskPtr;
 class RasterizingTask : public RefObject
 {
 public:
 class RasterizingTask : public RefObject
 {
 public:
+#ifdef NO_THORVG
   /**
    * Constructor
    *
   /**
    * Constructor
    *
@@ -70,6 +76,17 @@ public:
    * @param[in] height The rasterization height.
    */
   RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, const VisualUrl& url, float dpi, unsigned int width, unsigned int height );
    * @param[in] height The rasterization height.
    */
   RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, const VisualUrl& url, float dpi, unsigned int width, unsigned int height );
+#else /* NO_THORVG */
+  /**
+   * Constructor
+   * @param[in] svgRenderer The renderer which the rasterized image to be applied.
+   * @param[in] url The URL to svg resource to use.
+   * @param[in] width The rasterization width.
+   * @param[in] height The rasterization height.
+   * @param[in] loaded The svg resource is loaded or not.
+   */
+  RasterizingTask( SvgVisual* svgRenderer, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height, bool loaded );
+#endif /* NO_THORVG */
 
   /**
    * Destructor.
 
   /**
    * Destructor.
@@ -92,11 +109,31 @@ public:
    */
   PixelData GetPixelData() const;
 
    */
   PixelData GetPixelData() const;
 
+#ifdef NO_THORVG
   /**
    * Get the parsed data.
    * @return parsed image data.
    */
   NSVGimage* GetParsedImage() const;
   /**
    * Get the parsed data.
    * @return parsed image data.
    */
   NSVGimage* GetParsedImage() const;
+  /**
+   * Get default size of svg
+   *
+   * @param[out] width The default width of svg
+   * @param[out] height The default height of svg
+   */
+  void GetDefaultSize( uint32_t& width, uint32_t& height ) const;
+#else /* NO_THORVG */
+  /**
+   * Get the VectorRenderer.
+   * @return VectorRenderer.
+   */
+  VectorImageRenderer GetVectorRenderer() const;
+  /**
+   * Whether the resource is loaded.
+   * @return True if the resource is loaded.
+   */
+  bool IsLoaded() const;
+#endif /* NO_THORVG */
 
   /**
    * Load svg file
 
   /**
    * Load svg file
@@ -112,13 +149,21 @@ private:
 
 private:
   SvgVisualPtr    mSvgVisual;
 
 private:
   SvgVisualPtr    mSvgVisual;
+#ifdef NO_THORVG
   NSVGimage*      mParsedSvg;
   NSVGimage*      mParsedSvg;
+#else /* NO_THORVG */
+  VectorImageRenderer mVectorRenderer;
+#endif /* NO_THORVG */
   VisualUrl       mUrl;
   PixelData       mPixelData;
   float           mDpi;
   unsigned int    mWidth;
   unsigned int    mHeight;
   VisualUrl       mUrl;
   PixelData       mPixelData;
   float           mDpi;
   unsigned int    mWidth;
   unsigned int    mHeight;
+#ifdef NO_THORVG
   NSVGrasterizer* mRasterizer;
   NSVGrasterizer* mRasterizer;
+#else /* NO_THORVG */
+  bool            mLoaded;
+#endif /* NO_THORVG */
 };
 
 /**
 };
 
 /**
@@ -163,14 +208,25 @@ public:
    */
   void RemoveTask( SvgVisual* visual );
 
    */
   void RemoveTask( SvgVisual* visual );
 
+#ifdef NO_THORVG
   /**
    * Delete the parsed SVG image, called by main thread.
    *
   /**
    * Delete the parsed SVG image, called by main thread.
    *
-   * The parsed svg should be delelted in worker thread, as the main thread does not know whether a rasterization of this svg is ongoing.
+   * The parsed svg should be deleted in worker thread, as the main thread does not know whether a rasterization of this svg is ongoing.
    *
    * @param[in] parsedImage The image to be deleted
    */
   void DeleteImage( NSVGimage* parsedSvg );
    *
    * @param[in] parsedImage The image to be deleted
    */
   void DeleteImage( NSVGimage* parsedSvg );
+#else /* NO_THORVG */
+  /**
+   * Delete the parsed SVG image, called by main thread.
+   *
+   * The parsed svg should be deleted in worker thread, as the main thread does not know whether a rasterization of this svg is ongoing.
+   *
+   * @param[in] VectorImage The image to be deleted
+   */
+  void DeleteImage( VectorImageRenderer vectorImage );
+#endif /* NO_THORVG */
 
 private:
 
 
 private:
 
@@ -214,7 +270,11 @@ private:
 
   std::vector<RasterizingTaskPtr>  mRasterizeTasks;     //The queue of the tasks waiting to rasterize the SVG image
   std::vector <RasterizingTaskPtr> mCompletedTasks;     //The queue of the tasks with the SVG rasterization completed
 
   std::vector<RasterizingTaskPtr>  mRasterizeTasks;     //The queue of the tasks waiting to rasterize the SVG image
   std::vector <RasterizingTaskPtr> mCompletedTasks;     //The queue of the tasks with the SVG rasterization completed
+#ifdef NO_THORVG
   Vector<NSVGimage*>               mDeleteSvg;          //The images that the event thread requested to delete
   Vector<NSVGimage*>               mDeleteSvg;          //The images that the event thread requested to delete
+#else /* NO_THORVG */
+  Vector <VectorImageRenderer*>      mDeleteSvg;          //The images that the event thread requested to delete
+#endif /* NO_THORVG */
 
   ConditionalWait            mConditionalWait;
   Dali::Mutex                mMutex;
 
   ConditionalWait            mConditionalWait;
   Dali::Mutex                mMutex;
index a9989c0..0e005b3 100644 (file)
 #include "svg-visual.h"
 
 // INTERNAL INCLUDES
 #include "svg-visual.h"
 
 // INTERNAL INCLUDES
+#ifdef NO_THORVG
 #include <dali-toolkit/third-party/nanosvg/nanosvg.h>
 #include <dali-toolkit/third-party/nanosvg/nanosvgrast.h>
 #include <dali-toolkit/third-party/nanosvg/nanosvg.h>
 #include <dali-toolkit/third-party/nanosvg/nanosvgrast.h>
+#endif /* NO_THORVG */
 #include <dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
 #include <dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -54,8 +56,13 @@ const Dali::Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties )
 {
   SvgVisualPtr svgVisual( new SvgVisual( factoryCache, shaderFactory, imageUrl ) );
 SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties )
 {
   SvgVisualPtr svgVisual( new SvgVisual( factoryCache, shaderFactory, imageUrl ) );
+#ifdef NO_THORVG
   svgVisual->ParseFromUrl( imageUrl );
   svgVisual->SetProperties( properties );
   svgVisual->ParseFromUrl( imageUrl );
   svgVisual->SetProperties( properties );
+#else /* NO_THORVG */
+  svgVisual->Load();
+  svgVisual->SetProperties( properties );
+#endif /* NO_THORVG */
 
   return svgVisual;
 }
 
   return svgVisual;
 }
@@ -63,7 +70,11 @@ SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShader
 SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
 {
   SvgVisualPtr svgVisual( new SvgVisual( factoryCache, shaderFactory, imageUrl ) );
 SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
 {
   SvgVisualPtr svgVisual( new SvgVisual( factoryCache, shaderFactory, imageUrl ) );
+#ifdef NO_THORVG
   svgVisual->ParseFromUrl( imageUrl );
   svgVisual->ParseFromUrl( imageUrl );
+#else /* NO_THORVG */
+  svgVisual->Load();
+#endif /* NO_THORVG */
 
   return svgVisual;
 }
 
   return svgVisual;
 }
@@ -73,7 +84,15 @@ SvgVisual::SvgVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory
   mImageVisualShaderFactory( shaderFactory ),
   mAtlasRect( FULL_TEXTURE_RECT ),
   mImageUrl( imageUrl ),
   mImageVisualShaderFactory( shaderFactory ),
   mAtlasRect( FULL_TEXTURE_RECT ),
   mImageUrl( imageUrl ),
+#ifdef NO_THORVG
   mParsedImage( NULL ),
   mParsedImage( NULL ),
+#else
+  mVectorRenderer( VectorImageRenderer::New() ),
+  mDefaultWidth( 0 ),
+  mDefaultHeight( 0 ),
+  mLoaded( false ),
+  mLocalResource( true ),
+#endif /* NO_THORVG */
   mPlacementActor(),
   mVisualSize(Vector2::ZERO),
   mAttemptAtlasing( false )
   mPlacementActor(),
   mVisualSize(Vector2::ZERO),
   mAttemptAtlasing( false )
@@ -84,10 +103,12 @@ SvgVisual::SvgVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory
 
 SvgVisual::~SvgVisual()
 {
 
 SvgVisual::~SvgVisual()
 {
+#ifdef NO_THORVG
   if( mParsedImage )
   {
     nsvgDelete( mParsedImage );
   }
   if( mParsedImage )
   {
     nsvgDelete( mParsedImage );
   }
+#endif /* NO_THORVG */
 }
 
 void SvgVisual::DoSetProperties( const Property::Map& propertyMap )
 }
 
 void SvgVisual::DoSetProperties( const Property::Map& propertyMap )
@@ -190,11 +211,19 @@ void SvgVisual::DoSetOffScene( Actor& actor )
 
 void SvgVisual::GetNaturalSize( Vector2& naturalSize )
 {
 
 void SvgVisual::GetNaturalSize( Vector2& naturalSize )
 {
+#ifdef NO_THORVG
   if( mParsedImage )
   {
     naturalSize.x = mParsedImage->width;
     naturalSize.y = mParsedImage->height;
   }
   if( mParsedImage )
   {
     naturalSize.x = mParsedImage->width;
     naturalSize.y = mParsedImage->height;
   }
+#else /* NO_THORVG */
+  if ( mLoaded )
+  {
+    naturalSize.x = mDefaultWidth;
+    naturalSize.y = mDefaultHeight;
+  }
+#endif /* NO_THORVG */
   else
   {
     naturalSize = Vector2::ZERO;
   else
   {
     naturalSize = Vector2::ZERO;
@@ -218,6 +247,7 @@ void SvgVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
   // Do nothing
 }
 
   // Do nothing
 }
 
+#ifdef NO_THORVG
 void SvgVisual::ParseFromUrl( const VisualUrl& imageUrl )
 {
   mImageUrl = imageUrl;
 void SvgVisual::ParseFromUrl( const VisualUrl& imageUrl )
 {
   mImageUrl = imageUrl;
@@ -233,6 +263,33 @@ void SvgVisual::ParseFromUrl( const VisualUrl& imageUrl )
     }
   }
 }
     }
   }
 }
+#else /* NO_THORVG */
+void SvgVisual::Load()
+{
+  if( mLoaded || !mLocalResource )
+  {
+    return;
+  }
+
+  mLocalResource = mImageUrl.IsLocalResource();
+
+  if( !mLocalResource )
+  {
+    // load remote resource on svg rasterize thread.
+    return;
+  }
+
+  if( !mVectorRenderer.Load( mImageUrl.GetUrl() ) )
+  {
+    DALI_LOG_ERROR( "Failed to load file!\n" );
+    return;
+  }
+
+  mVectorRenderer.GetDefaultSize(mDefaultWidth, mDefaultHeight);
+  mLoaded = true;
+}
+#endif /* NO_THORVG */
+
 
 void SvgVisual::AddRasterizationTask( const Vector2& size )
 {
 
 void SvgVisual::AddRasterizationTask( const Vector2& size )
 {
@@ -244,11 +301,21 @@ void SvgVisual::AddRasterizationTask( const Vector2& size )
     Vector2 dpi = Stage::GetCurrent().GetDpi();
     float meanDpi = ( dpi.height + dpi.width ) * 0.5f;
 
     Vector2 dpi = Stage::GetCurrent().GetDpi();
     float meanDpi = ( dpi.height + dpi.width ) * 0.5f;
 
+#ifdef NO_THORVG
     RasterizingTaskPtr newTask = new RasterizingTask( this, mParsedImage, mImageUrl, meanDpi, width, height );
     RasterizingTaskPtr newTask = new RasterizingTask( this, mParsedImage, mImageUrl, meanDpi, width, height );
+#else /* NO_THORVG */
+    RasterizingTaskPtr newTask = new RasterizingTask( this, mVectorRenderer, mImageUrl, meanDpi, width, height, mLoaded );
+#endif /* NO_THORVG */
     if ( IsSynchronousLoadingRequired() )
     {
     if ( IsSynchronousLoadingRequired() )
     {
+#ifdef NO_THORVG
       newTask->Rasterize();
       ApplyRasterizedImage( newTask->GetParsedImage(), newTask->GetPixelData() );
       newTask->Rasterize();
       ApplyRasterizedImage( newTask->GetParsedImage(), newTask->GetPixelData() );
+#else /* NO_THORVG */
+      newTask->Load();
+      newTask->Rasterize();
+      ApplyRasterizedImage( newTask->GetVectorRenderer(), newTask->GetPixelData(), newTask->IsLoaded() );
+#endif /* NO_THORVG */
     }
     else
     {
     }
     else
     {
@@ -257,6 +324,7 @@ void SvgVisual::AddRasterizationTask( const Vector2& size )
   }
 }
 
   }
 }
 
+#ifdef NO_THORVG
 void SvgVisual::ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterizedPixelData )
 {
   if( mParsedImage == NULL)
 void SvgVisual::ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterizedPixelData )
 {
   if( mParsedImage == NULL)
@@ -265,6 +333,13 @@ void SvgVisual::ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterized
   }
 
   if( mParsedImage && IsOnScene() )
   }
 
   if( mParsedImage && IsOnScene() )
+#else /* NO_THORVG */
+void SvgVisual::ApplyRasterizedImage( VectorImageRenderer vectorRenderer, PixelData rasterizedPixelData, bool isLoaded )
+{
+  mLoaded = isLoaded;
+
+  if( isLoaded && rasterizedPixelData && IsOnScene() )
+#endif /* NO_THORVG */
   {
     TextureSet currentTextureSet = mImpl->mRenderer.GetTextures();
     if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED )
   {
     TextureSet currentTextureSet = mImpl->mRenderer.GetTextures();
     if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED )
@@ -328,7 +403,11 @@ void SvgVisual::ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterized
    // Svg loaded and ready to display
    ResourceReady( Toolkit::Visual::ResourceStatus::READY );
   }
    // Svg loaded and ready to display
    ResourceReady( Toolkit::Visual::ResourceStatus::READY );
   }
+#ifdef NO_THORVG
   else if( !mParsedImage )
   else if( !mParsedImage )
+#else /* NO_THORVG */
+  else if( !isLoaded || !rasterizedPixelData )
+#endif /* NO_THORVG */
   {
     ResourceReady( Toolkit::Visual::ResourceStatus::FAILED );
   }
   {
     ResourceReady( Toolkit::Visual::ResourceStatus::FAILED );
   }
index e18d5cf..0f1dc95 100644 (file)
@@ -26,7 +26,9 @@
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
 
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
 
+#ifdef NO_THORVG
 struct NSVGimage;
 struct NSVGimage;
+#endif /* NO_THORVG */
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -142,6 +144,7 @@ protected:
 
 public:
 
 
 public:
 
+#ifdef NO_THORVG
   /**
    * @bried Apply the rasterized image to the visual.
    *
   /**
    * @bried Apply the rasterized image to the visual.
    *
@@ -149,14 +152,31 @@ public:
    * @param[in] rasterizedPixelData The pixel buffer with the rasterized pixels
    */
   void ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterizedPixelData );
    * @param[in] rasterizedPixelData The pixel buffer with the rasterized pixels
    */
   void ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterizedPixelData );
+#else /* NO_THORVG */
+  /**
+   * @bried Apply the rasterized image to the visual.
+   *
+   * @param[in] vectorImage The data of vector image.
+   * @param[in] rasterizedPixelData The pixel buffer with the rasterized pixels
+   * @param[in] bool Whether the resource is loaded
+   */
+  void ApplyRasterizedImage( VectorImageRenderer vectorImage, PixelData rasterizedPixelData, bool isLoaded );
+#endif /* NO_THORVG */
 
 private:
 
 private:
+#ifdef NO_THORVG
   /**
     * @brief Parses the SVG Image from the set URL.
     *
     * @param[in] imageUrl The URL of the image to parse the SVG from.
     */
    void ParseFromUrl( const VisualUrl& imageUrl );
   /**
     * @brief Parses the SVG Image from the set URL.
     *
     * @param[in] imageUrl The URL of the image to parse the SVG from.
     */
    void ParseFromUrl( const VisualUrl& imageUrl );
+#else /* NO_THORVG */
+  /**
+    * @brief Load the SVG Image from the set URL.
+    */
+   void Load();
+#endif /* NO_THORVG */
 
   /**
    * @bried Rasterize the svg with the given size, and add it to the visual.
 
   /**
    * @bried Rasterize the svg with the given size, and add it to the visual.
@@ -182,7 +202,15 @@ private:
   ImageVisualShaderFactory& mImageVisualShaderFactory;
   Vector4                   mAtlasRect;
   VisualUrl                 mImageUrl;
   ImageVisualShaderFactory& mImageVisualShaderFactory;
   Vector4                   mAtlasRect;
   VisualUrl                 mImageUrl;
+#ifdef NO_THORVG
   NSVGimage*                mParsedImage;
   NSVGimage*                mParsedImage;
+#else /* NO_THORVG */
+  VectorImageRenderer       mVectorRenderer;
+  uint32_t                  mDefaultWidth;
+  uint32_t                  mDefaultHeight;
+  bool                      mLoaded;
+  bool                      mLocalResource;
+#endif /* NO_THORVG */
   WeakHandle<Actor>         mPlacementActor;
   Vector2                   mVisualSize;
   bool                      mAttemptAtlasing;  ///< If true will attempt atlasing, otherwise create unique texture
   WeakHandle<Actor>         mPlacementActor;
   Vector2                   mVisualSize;
   bool                      mAttemptAtlasing;  ///< If true will attempt atlasing, otherwise create unique texture
index 218ba4f..ad5bcb3 100644 (file)
@@ -144,7 +144,11 @@ void VisualFactoryCache::ApplyRasterizedSVGToSampler()
 {
   while( RasterizingTaskPtr task = mSvgRasterizeThread->NextCompletedTask() )
   {
 {
   while( RasterizingTaskPtr task = mSvgRasterizeThread->NextCompletedTask() )
   {
+#ifdef NO_THORVG
     task->GetSvgVisual()->ApplyRasterizedImage( task->GetParsedImage(), task->GetPixelData() );
     task->GetSvgVisual()->ApplyRasterizedImage( task->GetParsedImage(), task->GetPixelData() );
+#else /* NO_THORVG */
+    task->GetSvgVisual()->ApplyRasterizedImage( task->GetVectorRenderer(), task->GetPixelData(), task->IsLoaded() );
+#endif /* NO_THORVG */
   }
 }
 
   }
 }