*/
#include <unistd.h>
+#include <toolkit-event-thread-callback.h>
#include <dali-toolkit-test-suite-utils.h>
#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
#include <dali-toolkit/internal/visuals/wireframe/wireframe-visual.h>
propertyMap5.Insert( Toolkit::Visual::Property::TYPE, Visual::SVG );
propertyMap5.Insert( ImageVisual::Property::URL, TEST_SVG_FILE_NAME );
Visual::Base svgVisual = factory.CreateVisual( propertyMap5 );
+
+ DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
DALI_TEST_CHECK( svgVisual );
TestDebugVisual( svgVisual, Visual::SVG, Vector2(100.f, 100.f) );
// svg visual
Visual::Base svgVisual = factory.CreateVisual( TEST_SVG_FILE_NAME, ImageDimensions() );
svgVisual.SetTransformAndSize(DefaultTransform(), controlSize );
+
+ DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
svgVisual.GetNaturalSize(naturalSize);
// TEST_SVG_FILE:
// <svg width="100" height="100">
// svg visual with a size
Visual::Base svgVisual2 = factory.CreateVisual( TEST_SVG_FILE_NAME, ImageDimensions(200, 200) );
+ svgVisual.SetTransformAndSize(DefaultTransform(), controlSize );
+ DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
svgVisual2.GetNaturalSize(naturalSize);
DALI_TEST_EQUALS( naturalSize, Vector2(100.f, 100.f), TEST_LOCATION ); // Natural size should still be 100, 100
END_TEST;
}
+
+int UtcDaliSvgVisualDownloadRemoteFile(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "Download svg file from remote" );
+
+ VisualFactory factory = VisualFactory::Get(); // svg visual
+ Visual::Base svgVisual1 = factory.CreateVisual( "http://bar.org/foobar.svg", ImageDimensions() );
+ DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+ DALI_TEST_CHECK( svgVisual1 );
+
+ Visual::Base svgVisual2 = factory.CreateVisual( "http://bar.org/wrong_name.svg", ImageDimensions() );
+ DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+ DALI_TEST_CHECK( svgVisual2 );
+ END_TEST;
+}
+
// CLASS HEADER
#include "svg-rasterize-thread.h"
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/thread-settings.h>
+#include <dali/devel-api/adaptor-framework/file-loader.h>
+#include <dali/integration-api/debug.h>
+
// INTERNAL INCLUDES
#include <dali-toolkit/third-party/nanosvg/nanosvgrast.h>
#include <dali-toolkit/internal/visuals/svg/svg-visual.h>
-#include <dali/devel-api/adaptor-framework/thread-settings.h>
namespace Dali
{
namespace Internal
{
-RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, unsigned int width, unsigned int height )
+namespace
+{
+const char * const UNITS("px");
+}
+
+RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, const VisualUrl& url, float dpi, unsigned int width, unsigned int height)
: mSvgVisual( svgRenderer ),
mParsedSvg( parsedSvg ),
+ mUrl( url ),
+ mDpi( dpi ),
mWidth( width ),
mHeight( height )
{
}
+void RasterizingTask::Load()
+{
+ if( mParsedSvg != NULL)
+ {
+ return;
+ }
+
+ if( !mUrl.IsLocalResource() )
+ {
+ Dali::Vector<uint8_t> remoteBuffer;
+
+ if( !Dali::FileLoader::DownloadFileSynchronously( mUrl.GetUrl(), remoteBuffer ))
+ {
+ DALI_LOG_ERROR("Failed to download file!\n");
+ return;
+ }
+
+ mParsedSvg = nsvgParse( reinterpret_cast<char*>(remoteBuffer.begin()), UNITS, mDpi );
+ }
+}
+
void RasterizingTask::Rasterize( NSVGrasterizer* rasterizer )
{
- if( mWidth > 0u && mHeight > 0u )
+ if( mParsedSvg != NULL && mWidth > 0u && mHeight > 0u )
{
- float scaleX = static_cast<float>( mWidth ) / mParsedSvg->width;
- float scaleY = static_cast<float>( mHeight ) / mParsedSvg->height;
+ float scaleX = static_cast<float>( mWidth ) / mParsedSvg->width;
+ float scaleY = static_cast<float>( mHeight ) / mParsedSvg->height;
float scale = scaleX < scaleY ? scaleX : scaleY;
unsigned int bufferStride = mWidth*Pixel::GetBytesPerPixel( Pixel::RGBA8888 );
unsigned int bufferSize = bufferStride * mHeight;
}
}
+NSVGimage* RasterizingTask::GetParsedImage() const
+{
+ return mParsedSvg;
+}
+
SvgVisual* RasterizingTask::GetSvgVisual() const
{
return mSvgVisual.Get();
SetThreadName( "SVGThread" );
while( RasterizingTaskPtr task = NextTaskToProcess() )
{
+ task->Load( );
task->Rasterize( mRasterizer );
AddCompletedTask( task );
}
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/ref-object.h>
#include <dali/public-api/rendering/texture-set.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
struct NSVGimage;
struct NSVGrasterizer;
* @param[in] parsedSvg The parsed svg for rasterizing.
* Note, after the task is added to the worker thread, the worker thread takes over the ownership.
* When the image is to be deleted, delete it in the worker thread by calling SvgRasterizeThread::DeleteImage( parsedSvg ).
+ * @param[in] url The URL to svg resource to use.
* @param[in] width The rasterization width.
* @param[in] height The rasterization height.
*/
- RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, unsigned int width, unsigned int height );
+ RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, const VisualUrl& url, float dpi, unsigned int width, unsigned int height );
/**
* Do the rasterization with the given rasterizer.
*/
PixelData GetPixelData() const;
-private:
+ /**
+ * Get the parsed data.
+ * @return parsed image data.
+ */
+ NSVGimage* GetParsedImage() const;
+
+ /**
+ * Load svg file
+ */
+ void Load();
+private:
// Undefined
RasterizingTask( const RasterizingTask& task );
RasterizingTask& operator=( const RasterizingTask& task );
private:
- SvgVisualPtr mSvgVisual;
- PixelData mPixelData;
+ SvgVisualPtr mSvgVisual;
NSVGimage* mParsedSvg;
+ VisualUrl mUrl;
+ PixelData mPixelData;
+ float mDpi;
unsigned int mWidth;
unsigned int mHeight;
};
-
/**
* The worker thread for SVG rasterization.
*/
// CLASS HEADER
#include "svg-visual.h"
-// EXTERNAL INCLUDES
-#include <dali/public-api/images/buffer-image.h>
-#include <dali/public-api/common/stage.h>
-#include <dali/public-api/math/vector4.h>
-#include <dali/devel-api/images/texture-set-image.h>
-#include <dali/integration-api/debug.h>
-#include <dali/devel-api/adaptor-framework/file-loader.h>
-
// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/visuals/image-visual-properties.h>
-#include <dali-toolkit/public-api/visuals/visual-properties.h>
#include <dali-toolkit/third-party/nanosvg/nanosvg.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-factory-cache.h>
#include <dali-toolkit/internal/visuals/visual-string-constants.h>
#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
#include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
+#include <dali/devel-api/adaptor-framework/file-loader.h>
-namespace
-{
-const char * const UNITS("px");
-
-// property name
-const char * const IMAGE_ATLASING( "atlasing" );
-
-const Dali::Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
-}
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/stage.h>
namespace Dali
{
namespace Internal
{
+namespace
+{
+// property name
+const char * const UNITS("px");
+
+const char * const IMAGE_ATLASING( "atlasing" );
+
+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 ) );
+ SvgVisualPtr svgVisual( new SvgVisual( factoryCache, shaderFactory, imageUrl ) );
svgVisual->ParseFromUrl( imageUrl );
svgVisual->SetProperties( properties );
SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
{
- SvgVisualPtr svgVisual( new SvgVisual( factoryCache, shaderFactory ) );
+ SvgVisualPtr svgVisual( new SvgVisual( factoryCache, shaderFactory, imageUrl ) );
svgVisual->ParseFromUrl( imageUrl );
return svgVisual;
}
-SvgVisual::SvgVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory )
+SvgVisual::SvgVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
: Visual::Base( factoryCache, Visual::FittingMode::FILL ),
mImageVisualShaderFactory( shaderFactory ),
mAtlasRect( FULL_TEXTURE_RECT ),
- mImageUrl( ),
+ mImageUrl( imageUrl ),
mParsedImage( NULL ),
mPlacementActor(),
mVisualSize(Vector2::ZERO),
}
}
-void SvgVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
-{
- // Do nothing
-}
-
void SvgVisual::ParseFromUrl( const VisualUrl& imageUrl )
{
mImageUrl = imageUrl;
}
}
+void SvgVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
+{
+ // Do nothing
+}
+
void SvgVisual::AddRasterizationTask( const Vector2& size )
{
- if( mImpl->mRenderer && mParsedImage )
+ if( mImpl->mRenderer )
{
unsigned int width = static_cast<unsigned int>(size.width);
unsigned int height = static_cast<unsigned int>( size.height );
- RasterizingTaskPtr newTask = new RasterizingTask( this, mParsedImage, width, height );
+ Vector2 dpi = Stage::GetCurrent().GetDpi();
+ float meanDpi = ( dpi.height + dpi.width ) * 0.5f;
+
+ RasterizingTaskPtr newTask = new RasterizingTask( this, mParsedImage, mImageUrl, meanDpi, width, height );
mFactoryCache.GetSVGRasterizationThread()->AddTask( newTask );
}
}
-void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData )
+void SvgVisual::ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterizedPixelData )
{
- if( IsOnStage() )
+ if( mParsedImage == NULL)
+ {
+ mParsedImage = parsedSvg;
+ }
+
+ if( mParsedImage && IsOnStage() )
{
TextureSet currentTextureSet = mImpl->mRenderer.GetTextures();
if( mImpl->mFlags |= Impl::IS_ATLASING_APPLIED )
{
Vector2 visualSize = mImpl->mTransform.GetVisualSize( mImpl->mControlSize );
- if( mParsedImage && IsOnStage() )
+ if( IsOnStage() )
{
if( visualSize != mVisualSize )
{
*
* @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
* @param[in] shaderFactory The ImageVisualShaderFactory object
+ * @param[in] imageUrl The URL to svg resource to use
*/
- SvgVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory );
+ SvgVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl );
/**
* @brief A reference counted object may only be deleted by calling Unreference().
/**
* @bried Apply the rasterized image to the visual.
*
+ * @param[in] parsedSvg The data of parsed image.
* @param[in] rasterizedPixelData The pixel buffer with the rasterized pixels
*/
- void ApplyRasterizedImage( PixelData rasterizedPixelData );
+ void ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterizedPixelData );
private:
-
/**
- * @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 );
/**
* @bried Rasterize the svg with the given size, and add it to the visual.
*/
void DoSetProperty( Property::Index index, const Property::Value& value );
-
// Undefined
SvgVisual( const SvgVisual& svgRenderer );
{
while( RasterizingTaskPtr task = mSvgRasterizeThread->NextCompletedTask() )
{
- task->GetSvgVisual()->ApplyRasterizedImage( task->GetPixelData() );
+ task->GetSvgVisual()->ApplyRasterizedImage( task->GetParsedImage(), task->GetPixelData() );
}
}