Support to use NpatchImage in broken Image.
Application can use custom broken image from this patch.
when they set 3 type of broken image(small,normal,large),
dali show the proper broken image considering size.
Change-Id: I7e2be85d4715d07356fd2782be2d011931fde5c2
return GetImpl(styleManager).GetConfigurations();
}
+void SetBrokenImageUrl(StyleManager styleManager, DevelStyleManager::BrokenImageType brokenImageType, const std::string& brokenImageUrl)
+{
+ return GetImpl(styleManager).SetBrokenImageUrl(Internal::StyleManager::BrokenImageType(brokenImageType), brokenImageUrl);
+}
+
+std::string GetBrokenImageUrl(StyleManager styleManager, DevelStyleManager::BrokenImageType brokenImageType)
+{
+ return GetImpl(styleManager).GetBrokenImageUrl(Internal::StyleManager::BrokenImageType(brokenImageType));
+}
+
} // namespace DevelStyleManager
} // namespace Toolkit
namespace DevelStyleManager
{
/**
+ * @brief The Type of BrokenImage
+ */
+enum BrokenImageType
+{
+ SMALL,
+ NORMAL,
+ LARGE
+};
+
+/**
* @brief Gets all currently defined configurations.
*
* @pre The Builder has been initialized.
**/
DALI_TOOLKIT_API const Property::Map GetConfigurations(StyleManager styleManager);
+/**
+ * @brief Sets an image to be used when a visual has failed to correctly render
+ * @param[in] styleManager The instance of StyleManager
+ * @param[in] brokenImageType The type of broken image
+ * @param[in] brokenImageUrl The broken image url
+ */
+DALI_TOOLKIT_API void SetBrokenImageUrl(StyleManager styleManager, DevelStyleManager::BrokenImageType brokenImageType, const std::string& brokenImageUrl);
+
+/**
+ * @brief Gets an image to be used when a visual has failed to correctly render
+ * @param[in] styleManager The instance of StyleManager
+ * @param[in] brokenImageType BrokenImage type
+ */
+DALI_TOOLKIT_API std::string GetBrokenImageUrl(StyleManager styleManager, DevelStyleManager::BrokenImageType brokenImageType);
+
} // namespace DevelStyleManager
} // namespace Toolkit
const char* DEFAULT_TOOLKIT_PACKAGE_PATH = "/toolkit/";
+static constexpr int32_t COUNT_BROKEN_IMAGE_MAX = 3;
+
#if defined(DEBUG_ENABLED)
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_STYLE");
#endif
// Sound & haptic style
mFeedbackStyle = new FeedbackStyle();
+
+ // Initialize BrokenImages
+ mBrokenImageUrls.assign(COUNT_BROKEN_IMAGE_MAX, "");
}
StyleManager::~StyleManager()
return result;
}
+void StyleManager::SetBrokenImageUrl(BrokenImageType brokenImageType, const std::string& brokenImageUrl)
+{
+ mBrokenImageUrls[brokenImageType] = brokenImageUrl;
+ EmitStyleChangeSignals(StyleChange::THEME_CHANGE);
+}
+
+std::string StyleManager::GetBrokenImageUrl(BrokenImageType brokenImageType)
+{
+ return mBrokenImageUrls[brokenImageType];
+}
+
bool StyleManager::LoadFile(const std::string& filename, std::string& stringOut)
{
DALI_ASSERT_DEBUG(0 != filename.length());
{
public:
/**
+ * @brief The Type of BrokenImage
+ */
+ enum BrokenImageType
+ {
+ SMALL,
+ NORMAL,
+ LARGE
+ };
+
+public:
+ /**
* Singleton access
*
* @return The StyleManager object
const Property::Map GetConfigurations();
/**
+ * @copydoc Toolkit::DevelStyleManager::SetBrokenImageUrl
+ */
+ void SetBrokenImageUrl(BrokenImageType brokenImageType, const std::string& brokenImageUrl);
+
+ /**
+ * @copydoc Toolkit::DevelStyleManager::GetBrokenImageUrl
+ */
+ std::string GetBrokenImageUrl(BrokenImageType brokenImageType);
+
+ /**
* @brief Apply the theme style to a control.
*
* @param[in] control The control to apply style.
Toolkit::Internal::FeedbackStyle* mFeedbackStyle; ///< Feedback style
+ std::vector<std::string> mBrokenImageUrls; ///< For brokenImage
+
// Signals
Toolkit::StyleManager::StyleChangedSignalType mControlStyleChangeSignal; ///< Emitted when the style( theme/font ) changes for the controls to style themselves
Toolkit::StyleManager::StyleChangedSignalType mStyleChangedSignal; ///< Emitted after the controls have been styled
DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "ResourceReady(ResourceStatus::FAILED)\n");
ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
- TextureSet textureSet = TextureSet::New();
- Texture brokenImage = mFactoryCache.GetBrokenVisualImage();
- textureSet.SetTexture(0u, brokenImage);
+ Actor actor = mPlacementActor.GetHandle();
+ Vector2 imageSize = Vector2::ZERO;
+ if(actor)
+ {
+ imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+ }
+ mFactoryCache.GetBrokenImageRenderer(mImpl->mRenderer, imageSize);
+ TextureSet textureSet = mImpl->mRenderer.GetTextures();
if(mFrameDelayTimer)
{
if(mLoadFailed)
{
- TextureSet textureSet = TextureSet::New();
- mImpl->mRenderer.SetTextures(textureSet);
-
- Texture brokenImage = mFactoryCache.GetBrokenVisualImage();
- textureSet.SetTexture(0u, brokenImage);
-
+ Vector2 imageSize = Vector2::ZERO;
+ imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+ mFactoryCache.GetBrokenImageRenderer(mImpl->mRenderer, imageSize);
actor.AddRenderer(mImpl->mRenderer);
-
ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
}
else
}
else
{
- Texture brokenImage = mFactoryCache.GetBrokenVisualImage();
-
+ Actor actor = mPlacementActor.GetHandle();
+ Vector2 imageSize = Vector2::ZERO;
+ if(actor)
+ {
+ imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+ }
+ mFactoryCache.GetBrokenImageRenderer(mImpl->mRenderer, imageSize);
+ Texture brokenImage = mImpl->mRenderer.GetTextures().GetTexture(0);
naturalSize.x = brokenImage.GetWidth();
naturalSize.y = brokenImage.GetWidth();
}
}
else if(mLoadState == TextureManager::LoadState::LOAD_FAILED)
{
- Texture brokenImage = mFactoryCache.GetBrokenVisualImage();
-
- mTextures = TextureSet::New();
- mTextures.SetTexture(0u, brokenImage);
- mImpl->mRenderer.SetTextures(mTextures);
-
+ Vector2 imageSize = Vector2::ZERO;
+ if(actor)
+ {
+ imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+ }
+ mFactoryCache.GetBrokenImageRenderer(mImpl->mRenderer, imageSize);
actor.AddRenderer(mImpl->mRenderer);
mPlacementActor.Reset();
EnablePreMultipliedAlpha(preMultiplied);
Actor actor = mPlacementActor.GetHandle();
- if(actor)
+ if(!loadingSuccess)
{
- actor.AddRenderer(mImpl->mRenderer);
- // reset the weak handle so that the renderer only get added to actor once
- mPlacementActor.Reset();
+ Vector2 imageSize = Vector2::ZERO;
+ if(actor)
+ {
+ imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+ }
+ mFactoryCache.GetBrokenImageRenderer(mImpl->mRenderer, imageSize);
+ textureSet = mImpl->mRenderer.GetTextures();
}
-
- if(!loadingSuccess)
+ else
{
- Texture brokenImage = mFactoryCache.GetBrokenVisualImage();
-
- textureSet = TextureSet::New();
- textureSet.SetTexture(0u, brokenImage);
+ Sampler sampler = Sampler::New();
+ sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+ textureSet.SetSampler(0u, sampler);
mImpl->mRenderer.SetTextures(textureSet);
}
- Sampler sampler = Sampler::New();
- sampler.SetWrapMode(mWrapModeU, mWrapModeV);
- textureSet.SetSampler(0u, sampler);
- mImpl->mRenderer.SetTextures(textureSet);
+ if(actor)
+ {
+ actor.AddRenderer(mImpl->mRenderer);
+ // reset the weak handle so that the renderer only get added to actor once
+ mPlacementActor.Reset();
+ }
}
// Storing TextureSet needed when renderer staged.
newData->AddObserver(textureObserver);
mCache.PushBack(newData);
-
return newData->GetId(); // valid ids start from 1u
}
}
preMultiplyOnLoad = (preMultiplyOnLoading == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD) ? true : false;
data->SetLoadedNPatchData(pixelBuffer, preMultiplyOnLoad);
}
-
return data->GetId();
}
DALI_LOG_ERROR("The N patch image '%s' is not a valid N patch image\n", mImageUrl.GetUrl().c_str());
textureSet = TextureSet::New();
- Texture croppedImage = mFactoryCache.GetBrokenVisualImage();
+ Actor actor = mPlacementActor.GetHandle();
+ Vector2 imageSize = Vector2::ZERO;
+ if(actor)
+ {
+ imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+ }
+ mFactoryCache.GetBrokenImageRenderer(mImpl->mRenderer, imageSize);
+ Texture croppedImage = mImpl->mRenderer.GetTextures().GetTexture(0);
textureSet.SetTexture(0u, croppedImage);
mImpl->mRenderer.RegisterProperty("uFixed[0]", Vector2::ZERO);
mImpl->mRenderer.RegisterProperty("uFixed[1]", Vector2::ZERO);
if(mLoadFailed)
{
- Texture brokenImage = mFactoryCache.GetBrokenVisualImage();
- textureSet.SetTexture(0u, brokenImage);
-
+ Vector2 imageSize = Vector2::ZERO;
+ imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+ mFactoryCache.GetBrokenImageRenderer(mImpl->mRenderer, imageSize);
actor.AddRenderer(mImpl->mRenderer);
ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
Actor actor = mPlacementActor.GetHandle();
if(actor)
{
- TextureSet textureSet = mImpl->mRenderer.GetTextures();
-
- Texture brokenImage = mFactoryCache.GetBrokenVisualImage();
- textureSet.SetTexture(0u, brokenImage);
-
+ Vector2 imageSize = Vector2::ZERO;
+ imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+ mFactoryCache.GetBrokenImageRenderer(mImpl->mRenderer, imageSize);
actor.AddRenderer(mImpl->mRenderer);
}
#include <dali-toolkit/internal/visuals/color/color-visual.h>
#include <dali-toolkit/internal/visuals/image-atlas-manager.h>
#include <dali-toolkit/internal/visuals/svg/svg-visual.h>
+#include <dali/integration-api/debug.h>
+#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
namespace Dali
{
{
namespace Internal
{
+namespace
+{
+
+static constexpr int32_t COUNT_BROKEN_IMAGE_MAX = 3;
+
+/**
+ * @brief Creates the geometry formed from the vertices and indices
+ *
+ * @param[in] vertices The vertices to generate the geometry from
+ * @param[in] indices The indices to generate the geometry from
+ * @return The geometry formed from the vertices and indices
+ */
+Geometry GenerateGeometry(const Vector<Vector2>& vertices, const Vector<unsigned short>& indices)
+{
+ Property::Map vertexFormat;
+ vertexFormat["aPosition"] = Property::VECTOR2;
+ VertexBuffer vertexBuffer = VertexBuffer::New(vertexFormat);
+ if(vertices.Size() > 0)
+ {
+ vertexBuffer.SetData(&vertices[0], vertices.Size());
+ }
+
+ // Create the geometry object
+ Geometry geometry = Geometry::New();
+ geometry.AddVertexBuffer(vertexBuffer);
+ if(indices.Size() > 0)
+ {
+ geometry.SetIndexBuffer(&indices[0], indices.Size());
+ }
+
+ return geometry;
+}
+
+/**
+ * @brief Adds the indices to form a quad composed off two triangles where the indices are organised in a grid
+ *
+ * @param[out] indices The indices to add to
+ * @param[in] rowIdx The row index to start the quad
+ * @param[in] nextRowIdx The index to the next row
+ */
+void AddQuadIndices(Vector<unsigned short>& indices, unsigned int rowIdx, unsigned int nextRowIdx)
+{
+ indices.PushBack(rowIdx);
+ indices.PushBack(nextRowIdx + 1);
+ indices.PushBack(rowIdx + 1);
+
+ indices.PushBack(rowIdx);
+ indices.PushBack(nextRowIdx);
+ indices.PushBack(nextRowIdx + 1);
+}
+
+void AddVertex(Vector<Vector2>& vertices, unsigned int x, unsigned int y)
+{
+ vertices.PushBack(Vector2(x, y));
+}
+
+} //unnamed namespace
+
VisualFactoryCache::VisualFactoryCache(bool preMultiplyOnLoad)
: mSvgRasterizeThread(NULL),
mVectorAnimationManager(),
- mBrokenImageUrl(""),
- mPreMultiplyOnLoad(preMultiplyOnLoad)
+ mPreMultiplyOnLoad(preMultiplyOnLoad),
+ mBrokenImageInfoContainer(),
+ mUseCustomBrokenImage(false)
{
+ mBrokenImageInfoContainer.assign(COUNT_BROKEN_IMAGE_MAX, BrokenImageInfo());
}
VisualFactoryCache::~VisualFactoryCache()
if(!mAtlasManager)
{
mAtlasManager = new ImageAtlasManager();
- mAtlasManager->SetBrokenImage(mBrokenImageUrl);
+ mAtlasManager->SetBrokenImage(mBrokenImageInfoContainer[BrokenImageType::SMALL].url);
}
return mAtlasManager;
return geometry;
}
-Texture VisualFactoryCache::GetBrokenVisualImage()
+Texture VisualFactoryCache::GetBrokenVisualImage(BrokenImageType brokenImageType)
{
- if(!mBrokenImageTexture && mBrokenImageUrl.size())
+ if(!(mBrokenImageInfoContainer[brokenImageType].texture) && !mBrokenImageInfoContainer[brokenImageType].url.empty())
{
- PixelData data;
- Devel::PixelBuffer pixelBuffer = LoadImageFromFile(mBrokenImageUrl);
+ PixelData pixelData;
+ Devel::PixelBuffer pixelBuffer = LoadImageFromFile(mBrokenImageInfoContainer[brokenImageType].url);
if(pixelBuffer)
{
- data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
- mBrokenImageTexture = Texture::New(Dali::TextureType::TEXTURE_2D, data.GetPixelFormat(), data.GetWidth(), data.GetHeight());
- mBrokenImageTexture.Upload(data);
+ pixelData = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
+ mBrokenImageInfoContainer[brokenImageType].texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight());
+ mBrokenImageInfoContainer[brokenImageType].texture.Upload(pixelData);
+ mBrokenImageInfoContainer[brokenImageType].width = pixelData.GetWidth();
+ mBrokenImageInfoContainer[brokenImageType].height = pixelData.GetHeight();
}
}
- return mBrokenImageTexture;
+ return mBrokenImageInfoContainer[brokenImageType].texture;
}
void VisualFactoryCache::SetPreMultiplyOnLoad(bool preMultiply)
return mPreMultiplyOnLoad;
}
-void VisualFactoryCache::SetBrokenImageUrl(const std::string& brokenImageUrl)
+void VisualFactoryCache::EnableCustomBrokenImage(bool enabled)
+{
+ mUseCustomBrokenImage = enabled;
+}
+
+void VisualFactoryCache::SetBrokenImageUrl(BrokenImageType brokenImageType, const std::string& brokenImageUrl)
{
- mBrokenImageUrl = brokenImageUrl;
+ const NPatchData* data;
+ mBrokenImageInfoContainer[brokenImageType].url = brokenImageUrl;
if(!mAtlasManager)
{
mAtlasManager = new ImageAtlasManager();
}
- mAtlasManager->SetBrokenImage(mBrokenImageUrl);
+ mAtlasManager->SetBrokenImage(mBrokenImageInfoContainer[brokenImageType].url);
+
+ // Update BrokenImageType
+ if(!mBrokenImageInfoContainer[brokenImageType].url.empty())
+ {
+ Rect<int> border;
+ VisualUrl visualUrl(mBrokenImageInfoContainer[brokenImageType].url);
+ mBrokenImageInfoContainer[brokenImageType].visualType = visualUrl.GetType();
+ if(mBrokenImageInfoContainer[brokenImageType].visualType == VisualUrl::Type::N_PATCH)
+ {
+ mBrokenImageInfoContainer[brokenImageType].npatchId = mNPatchLoader.Load( mTextureManager, NULL, mBrokenImageInfoContainer[brokenImageType].url, border, mPreMultiplyOnLoad, true);
+ if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[brokenImageType].npatchId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
+ {
+ mBrokenImageInfoContainer[brokenImageType].width = data->GetCroppedWidth();
+ mBrokenImageInfoContainer[brokenImageType].height = data->GetCroppedHeight();
+ }
+ }
+ else
+ {
+ GetBrokenVisualImage(brokenImageType);
+ }
+ }
+}
+
+VisualUrl::Type VisualFactoryCache::GetBrokenImageVisualType(BrokenImageType brokenImageType)
+{
+ return mBrokenImageInfoContainer[brokenImageType].visualType;
+}
+
+Geometry VisualFactoryCache::CreateNPatchGeometry(Uint16Pair gridSize)
+{
+ uint16_t gridWidth = gridSize.GetWidth();
+ uint16_t gridHeight = gridSize.GetHeight();
+
+ // Create vertices
+ Vector<Vector2> vertices;
+ vertices.Reserve((gridWidth + 1) * (gridHeight + 1));
+
+ for(int y = 0; y < gridHeight + 1; ++y)
+ {
+ for(int x = 0; x < gridWidth + 1; ++x)
+ {
+ AddVertex(vertices, x, y);
+ }
+ }
+
+ // Create indices
+ Vector<unsigned short> indices;
+ indices.Reserve(gridWidth * gridHeight * 6);
+
+ unsigned int rowIdx = 0;
+ unsigned int nextRowIdx = gridWidth + 1;
+ for(int y = 0; y < gridHeight; ++y, ++nextRowIdx, ++rowIdx)
+ {
+ for(int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx)
+ {
+ AddQuadIndices(indices, rowIdx, nextRowIdx);
+ }
+ }
+
+ return GenerateGeometry(vertices, indices);
+}
+
+Geometry VisualFactoryCache::GetNPatchGeometry(BrokenImageType brokenImageType)
+{
+ Geometry geometry;
+ const NPatchData* data;
+ if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[brokenImageType].npatchId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
+ {
+ if(data->GetStretchPixelsX().Size() == 1 && data->GetStretchPixelsY().Size() == 1)
+ {
+ geometry = GetGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY);
+ if(!geometry)
+ {
+ geometry = CreateNPatchGeometry(Uint16Pair(3,3));
+ SaveGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY, geometry);
+ }
+ }
+ else if(data->GetStretchPixelsX().Size() > 0 || data->GetStretchPixelsY().Size() > 0)
+ {
+ Uint16Pair gridSize(2 * data->GetStretchPixelsX().Size() + 1, 2 * data->GetStretchPixelsY().Size() + 1);
+ if(!data->GetRenderingMap())
+ {
+ geometry = CreateNPatchGeometry(gridSize);
+ }
+ }
+ }
+ else
+ {
+ // no N patch data so use default geometry
+ geometry = GetGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY);
+ if(!geometry)
+ {
+ geometry = CreateNPatchGeometry(Uint16Pair(3,3));
+ SaveGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY, geometry);
+ }
+ }
+ return geometry;
+}
+
+Shader VisualFactoryCache::GetNPatchShader(BrokenImageType brokenImageType)
+{
+ Shader shader;
+ const NPatchData* data;
+ // 0 is either no data (load failed?) or no stretch regions on image
+ // for both cases we use the default shader
+ NPatchUtility::StretchRanges::SizeType xStretchCount = 0;
+ NPatchUtility::StretchRanges::SizeType yStretchCount = 0;
+
+ // ask loader for the regions
+ if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[brokenImageType].npatchId, data))
+ {
+ xStretchCount = data->GetStretchPixelsX().Count();
+ yStretchCount = data->GetStretchPixelsY().Count();
+ }
+
+ if(DALI_LIKELY((xStretchCount == 1 && yStretchCount == 1) ||
+ (xStretchCount == 0 && yStretchCount == 0)))
+ {
+ shader = GetShader(VisualFactoryCache::NINE_PATCH_SHADER);
+ if(DALI_UNLIKELY(!shader))
+ {
+ shader = Shader::New(SHADER_NPATCH_VISUAL_3X3_SHADER_VERT, SHADER_NPATCH_VISUAL_SHADER_FRAG);
+
+ // Only cache vanilla 9 patch shaders
+ SaveShader(VisualFactoryCache::NINE_PATCH_SHADER, shader);
+ }
+ }
+ else if(xStretchCount > 0 || yStretchCount > 0)
+ {
+ std::stringstream vertexShader;
+ vertexShader << "#define FACTOR_SIZE_X " << xStretchCount + 2 << "\n"
+ << "#define FACTOR_SIZE_Y " << yStretchCount + 2 << "\n"
+ << SHADER_NPATCH_VISUAL_SHADER_VERT;
+ shader = Shader::New(vertexShader.str(), SHADER_NPATCH_VISUAL_SHADER_FRAG);
+ }
+ return shader;
+}
+
+void VisualFactoryCache::RegisterStretchProperties(Renderer& renderer, BrokenImageType brokenImageType, const char* uniformName, const NPatchUtility::StretchRanges& stretchPixels, uint16_t imageExtent)
+{
+ uint16_t prevEnd = 0;
+ uint16_t prevFix = 0;
+ uint16_t prevStretch = 0;
+ unsigned int i = 1;
+ for(NPatchUtility::StretchRanges::ConstIterator it = stretchPixels.Begin(); it != stretchPixels.End(); ++it, ++i)
+ {
+ uint16_t start = it->GetX();
+ uint16_t end = it->GetY();
+
+ uint16_t fix = prevFix + start - prevEnd;
+ uint16_t stretch = prevStretch + end - start;
+
+ std::stringstream uniform;
+ uniform << uniformName << "[" << i << "]";
+ renderer.RegisterProperty(uniform.str(), Vector2(fix, stretch));
+
+ prevEnd = end;
+ prevFix = fix;
+ prevStretch = stretch;
+ }
+
+ {
+ prevFix += imageExtent - prevEnd;
+ std::stringstream uniform;
+ uniform << uniformName << "[" << i << "]";
+ renderer.RegisterProperty(uniform.str(), Vector2(prevFix, prevStretch));
+ }
+}
+
+void VisualFactoryCache::ApplyTextureAndUniforms(Renderer& renderer, BrokenImageType brokenImageType)
+{
+ const NPatchData* data;
+ TextureSet textureSet;
+ if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[brokenImageType].npatchId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
+ {
+ textureSet = data->GetTextures();
+ mBrokenImageInfoContainer[brokenImageType].texture = data->GetTextures().GetTexture(0);
+
+ if(data->GetStretchPixelsX().Size() == 1 && data->GetStretchPixelsY().Size() == 1)
+ {
+ //special case for 9 patch
+ Uint16Pair stretchX = data->GetStretchPixelsX()[0];
+ Uint16Pair stretchY = data->GetStretchPixelsY()[0];
+
+ uint16_t stretchWidth = (stretchX.GetY() >= stretchX.GetX()) ? stretchX.GetY() - stretchX.GetX() : 0;
+ uint16_t stretchHeight = (stretchY.GetY() >= stretchY.GetX()) ? stretchY.GetY() - stretchY.GetX() : 0;
+
+ renderer.RegisterProperty("uFixed[0]", Vector2::ZERO);
+ renderer.RegisterProperty("uFixed[1]", Vector2(stretchX.GetX(), stretchY.GetX()));
+ renderer.RegisterProperty("uFixed[2]", Vector2(data->GetCroppedWidth() - stretchWidth, data->GetCroppedHeight() - stretchHeight));
+ renderer.RegisterProperty("uStretchTotal", Vector2(stretchWidth, stretchHeight));
+ }
+ else
+ {
+ renderer.RegisterProperty("uNinePatchFactorsX[0]", Vector2::ZERO);
+ renderer.RegisterProperty("uNinePatchFactorsY[0]", Vector2::ZERO);
+
+ RegisterStretchProperties(renderer, brokenImageType, "uNinePatchFactorsX", data->GetStretchPixelsX(), data->GetCroppedWidth());
+ RegisterStretchProperties(renderer, brokenImageType, "uNinePatchFactorsY", data->GetStretchPixelsY(), data->GetCroppedHeight());
+ }
+ }
+ else
+ {
+ textureSet = TextureSet::New();
+
+ Texture croppedImage = GetBrokenVisualImage(brokenImageType);
+ textureSet.SetTexture(0u, croppedImage);
+ renderer.RegisterProperty("uFixed[0]", Vector2::ZERO);
+ renderer.RegisterProperty("uFixed[1]", Vector2::ZERO);
+ renderer.RegisterProperty("uFixed[2]", Vector2::ZERO);
+ renderer.RegisterProperty("uStretchTotal", Vector2(croppedImage.GetWidth(), croppedImage.GetHeight()));
+ }
+
+ renderer.SetTextures(textureSet);
+}
+
+void VisualFactoryCache::GetBrokenImageRenderer(Renderer& renderer, const Vector2& size)
+{
+ BrokenImageType brokenImageType = GetProperBrokenImageType(size);
+
+ if(GetBrokenImageVisualType(brokenImageType) == VisualUrl::N_PATCH)
+ {
+ // Set geometry and shader for npatch
+ Geometry geometry = GetNPatchGeometry(brokenImageType);
+ Shader shader = GetNPatchShader(brokenImageType);
+ renderer.SetGeometry(geometry);
+ renderer.SetShader(shader);
+ ApplyTextureAndUniforms(renderer, brokenImageType);
+ }
+ else
+ {
+ Texture brokenImage = GetBrokenVisualImage(brokenImageType);
+ TextureSet textureSet = TextureSet::New();
+ textureSet.SetTexture(0u, brokenImage);
+ renderer.SetTextures(textureSet);
+ }
+}
+
+VisualFactoryCache::BrokenImageType VisualFactoryCache::GetProperBrokenImageType(const Vector2& size)
+{
+ // Sets the default broken type
+ BrokenImageType returnType = BrokenImageType::SMALL;
+
+ if((size.width == 0 && size.height == 0) || !mUseCustomBrokenImage )
+ {
+ // To do : Need to add observer about size
+ // Can't get size , just use default size of brokenImage
+ return returnType;
+ }
+
+ // Find the proper value if we know the size of the image
+ for(auto brokenImageIter = mBrokenImageInfoContainer.rbegin(); brokenImageIter != mBrokenImageInfoContainer.rend(); brokenImageIter++)
+ {
+ // Skip if the value is not set
+ if(brokenImageIter->width == 0 && brokenImageIter->height == 0)
+ {
+ continue;
+ }
+
+ if(brokenImageIter->width < size.width && brokenImageIter->height < size.height)
+ {
+ int index = std::distance(brokenImageIter,mBrokenImageInfoContainer.rend()-1);
+ returnType = (BrokenImageType)index;
+ break;
+ }
+ }
+
+ return returnType;
}
} // namespace Internal
#include <dali-toolkit/internal/visuals/npatch-loader.h>
#include <dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h>
#include <dali-toolkit/internal/visuals/texture-manager-impl.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
namespace Dali
{
GEOMETRY_TYPE_MAX = WIREFRAME_GEOMETRY
};
+ /**
+ * @brief The Type of BrokenImage
+ */
+ enum BrokenImageType
+ {
+ SMALL,
+ NORMAL,
+ LARGE
+ };
+
public:
+
/**
* @brief Constructor
*
static Geometry CreateGridGeometry(Uint16Pair gridSize);
/**
- * @brief Returns a new Texture to use when a visual has failed to correctly render
- * @return The broken image texture.
- */
- Texture GetBrokenVisualImage();
-
- /**
* @copydoc Toolkit::VisualFactory::SetPreMultiplyOnLoad()
*/
void SetPreMultiplyOnLoad(bool preMultiply);
bool GetPreMultiplyOnLoad();
/**
+ * @brief Enable a custom broken image
+ *
+ * @param[in] enabled True if cache use custom broken image
+ */
+ void EnableCustomBrokenImage(bool enabled);
+
+ /**
* @brief Set an image to be used when a visual has failed to correctly render
- * @param[in] brokenImageUrl The broken image url.
+ * @param[in] brokenImageType BrokenImage type
+ * @param[in] brokenImageUrl The broken image url
+ */
+ void SetBrokenImageUrl(BrokenImageType brokenImageType, const std::string& brokenImageUrl);
+
+ /**
+ * @brief Returns a broken image type
+ * @param[in] brokenImageType BrokenImage type
+ * @return The broken image type.
+ */
+ VisualUrl::Type GetBrokenImageVisualType(BrokenImageType brokenImageType);
+
+ /**
+ * @brief Get the Npatch Renderer object
+ * @param[in] renderer renderer for npatch
+ * @param[in] size the size of actor
*/
- void SetBrokenImageUrl(const std::string& brokenImageUrl);
+ void GetBrokenImageRenderer(Renderer& renderer, const Vector2& size);
public:
/**
VisualFactoryCache& operator=(const VisualFactoryCache& rhs);
private:
+ /**
+ * @brief Returns a new Texture to use when a visual has failed to correctly render
+ * @return The broken image texture.
+ */
+ Texture GetBrokenVisualImage(BrokenImageType brokenImageType);
+
+ /**
+ * @brief Change the Proper broken image type
+ * @param[in] size The size of actor
+ *
+ * @return The type of broken image
+ */
+ BrokenImageType GetProperBrokenImageType(const Vector2& size);
+
+ /**
+ * @brief Apply a texture and uniforms
+ *
+ * @param renderer The renderer for broken image
+ * @param brokenImageType The type of broken image
+ */
+ void ApplyTextureAndUniforms(Renderer& renderer, BrokenImageType brokenImageType);
+
+ /**
+ * @brief Creates a Npatch Geometry object
+ *
+ * @param[in] gridSize The gridSize for creating a geometry
+ * @return The Geometry for NPatch
+ */
+ Geometry CreateNPatchGeometry(Uint16Pair gridSize);
+
+ /**
+ * @brief Gets a geometry for npatch image
+ *
+ * @param[in] brokenImageType the type of broken image
+ * @return The Geometry for NPatch
+ */
+ Geometry GetNPatchGeometry(BrokenImageType brokenImageType);
+
+ /**
+ * @brief Gets the Npatch Shader object
+ *
+ * @param[in] brokenImageType The type of broken image
+ * @return The Shader for NPatch
+ */
+ Shader GetNPatchShader(BrokenImageType brokenImageType);
+
+ /**
+ * @brief Registers a properties for Stretch Ranges
+ *
+ * @param renderer The renderer for broken image
+ * @param brokenImageType The type of broken image
+ * @param uniformName The name of the uniform
+ * @param stretchPixels The stretchable pixels in the cropped image space
+ * @param imageExtent The imageExtent
+ */
+ void RegisterStretchProperties(Renderer& renderer, BrokenImageType brokenImageType, const char* uniformName, const NPatchUtility::StretchRanges& stretchPixels, uint16_t imageExtent);
+
+private:
+ struct BrokenImageInfo
+ {
+ BrokenImageInfo()
+ :visualType(),
+ url(""),
+ npatchId(NPatchData::INVALID_NPATCH_DATA_ID),
+ texture(),
+ width(0),
+ height(0)
+ {
+ }
+
+ ~BrokenImageInfo()
+ {
+ }
+
+ // Data
+ VisualUrl::Type visualType;
+ std::string url;
+ NPatchData::NPatchDataId npatchId;
+ Texture texture;
+ uint32_t width;
+ uint32_t height;
+ };
+
Geometry mGeometry[GEOMETRY_TYPE_MAX + 1];
Shader mShader[SHADER_TYPE_MAX + 1];
ImageAtlasManagerPtr mAtlasManager;
TextureManager mTextureManager;
NPatchLoader mNPatchLoader;
- Texture mBrokenImageTexture;
+
SvgRasterizeThread* mSvgRasterizeThread;
std::unique_ptr<VectorAnimationManager> mVectorAnimationManager;
- std::string mBrokenImageUrl;
bool mPreMultiplyOnLoad;
+ std::vector<BrokenImageInfo> mBrokenImageInfoContainer;
+ bool mUseCustomBrokenImage;
};
} // namespace Internal
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
#endif
+static constexpr int32_t COUNT_BROKEN_IMAGE_MAX = 3;
+
BaseHandle Create()
{
BaseHandle handle = Toolkit::VisualFactory::Get();
{
if(type == StyleChange::THEME_CHANGE)
{
- const std::string imageDirPath = AssetManager::GetDaliImagePath();
- std::string brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME;
-
- Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
- config["brokenImageUrl"].Get(brokenImageUrl);
-
- if(mFactoryCache)
- {
- mFactoryCache->SetBrokenImageUrl(brokenImageUrl);
- }
+ SetBrokenImageUrl(styleManager);
}
}
return GetFactoryCache().GetTextureManager();
}
-Internal::VisualFactoryCache& VisualFactory::GetFactoryCache()
+void VisualFactory::SetBrokenImageUrl(Toolkit::StyleManager& styleManager)
{
- if(!mFactoryCache)
+ const std::string imageDirPath = AssetManager::GetDaliImagePath();
+ std::string brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME;
+ std::string customBrokenImageUrl[COUNT_BROKEN_IMAGE_MAX];
+
+ if(styleManager)
{
- mFactoryCache = std::unique_ptr<VisualFactoryCache>(new VisualFactoryCache(mPreMultiplyOnLoad));
+ Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
+ config["brokenImageUrl"].Get(brokenImageUrl);
+ styleManager.StyleChangedSignal().Connect(mSlotDelegate, &VisualFactory::OnStyleChangedSignal);
- const std::string imageDirPath = AssetManager::GetDaliImagePath();
- std::string brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME;
+ bool findCustomBrokenImage = false;
+ for(int i=0;i<COUNT_BROKEN_IMAGE_MAX;i++)
+ {
+ customBrokenImageUrl[i] = Toolkit::DevelStyleManager::GetBrokenImageUrl(styleManager,Toolkit::DevelStyleManager::BrokenImageType(i));
+ if(!customBrokenImageUrl[i].empty())
+ {
+ findCustomBrokenImage = true;
+ }
+ }
- Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
- if(styleManager)
+ if(findCustomBrokenImage)
{
- Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
- config["brokenImageUrl"].Get(brokenImageUrl);
- styleManager.StyleChangedSignal().Connect(mSlotDelegate, &VisualFactory::OnStyleChangedSignal);
+ std::string customDefaultBrokenUrl = "";
+ mFactoryCache->EnableCustomBrokenImage(true);
+ customDefaultBrokenUrl = customBrokenImageUrl[0];
+
+ for(int i=0;i<COUNT_BROKEN_IMAGE_MAX;i++)
+ {
+ if(customDefaultBrokenUrl.empty())
+ {
+ if(!customBrokenImageUrl[i].empty())
+ {
+ customDefaultBrokenUrl = customBrokenImageUrl[i];
+ mFactoryCache->SetBrokenImageUrl(Toolkit::Internal::VisualFactoryCache::BrokenImageType::SMALL, customBrokenImageUrl[i]);
+ }
+ }
+ mFactoryCache->SetBrokenImageUrl(Toolkit::Internal::VisualFactoryCache::BrokenImageType(i), customBrokenImageUrl[i]);
+ }
+ }
+ else
+ {
+ mFactoryCache->SetBrokenImageUrl(Toolkit::Internal::VisualFactoryCache::BrokenImageType::SMALL, brokenImageUrl);
}
+ }
+ else
+ {
+ mFactoryCache->SetBrokenImageUrl(Toolkit::Internal::VisualFactoryCache::BrokenImageType::SMALL, brokenImageUrl);
+ }
+}
- mFactoryCache->SetBrokenImageUrl(brokenImageUrl);
+Internal::VisualFactoryCache& VisualFactory::GetFactoryCache()
+{
+ if(!mFactoryCache)
+ {
+ mFactoryCache = std::unique_ptr<VisualFactoryCache>(new VisualFactoryCache(mPreMultiplyOnLoad));
+ Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
+ SetBrokenImageUrl(styleManager);
}
return *mFactoryCache;
}
private:
/**
+ * @brief Set the Broken Image url
+ *
+ */
+ void SetBrokenImageUrl(Toolkit::StyleManager& styleManager);
+
+ /**
* Get the factory cache, creating it if necessary.
*/
Internal::VisualFactoryCache& GetFactoryCache();