utc-Dali-Dictionary.cpp
utc-Dali-FeedbackStyle.cpp
utc-Dali-ItemView-internal.cpp
+ utc-Dali-LineHelperFunctions.cpp
utc-Dali-LogicalModel.cpp
utc-Dali-PropertyHelper.cpp
+ utc-Dali-Text-AbstractStyleCharacterRun.cpp
utc-Dali-Text-Characters.cpp
utc-Dali-Text-CharacterSetConversion.cpp
utc-Dali-Text-Circular.cpp
--- /dev/null
+/*
+ * 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 <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/internal/text/line-helper-functions.h>
+#include <dali-toolkit/internal/text/rendering/text-typesetter.h>
+#include <dali-toolkit/internal/text/rendering/view-model.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+#include <toolkit-text-utils.h>
+
+using namespace Dali;
+using namespace Toolkit;
+using namespace Text;
+
+int UtcDaliGetPreOffsetVerticalLineAlignmentWithNegativeLineSpacing(void)
+{
+ tet_infoline(" UtcDaliGetPreOffsetVerticalLineAlignmentWithNegativeLineSpacing ");
+ ToolkitTestApplication application;
+
+ uint32_t expectedNumberOfLines = 2u;
+
+ // Creates a text controller.
+ ControllerPtr controller = Controller::New();
+
+ // Configures the text controller similarly to the text-label.
+ ConfigureTextLabel(controller);
+
+ // Sets the text.
+ controller->SetMarkupProcessorEnabled(true);
+ controller->SetTextElideEnabled(false);
+ controller->SetText("<p rel-line-height=0.5>Line one Line two</p>");
+
+ // Creates the text's model and relais-out the text.
+ const Size relayoutSize(120.f, 100.f);
+ controller->Relayout(relayoutSize);
+
+ // Tests the rendering controller has been created.
+ TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
+ DALI_TEST_CHECK(typesetter);
+
+ // Tests the view model has been created.
+ ViewModel* model = typesetter->GetViewModel();
+ DALI_TEST_CHECK(model);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(model->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION);
+ DALI_TEST_CHECK(model->GetLines());
+
+ const LineRun& lineOne = *(model->GetLines() + 0u);
+ const LineRun& lineTwo = *(model->GetLines() + 1u);
+
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliGetPreOffsetVerticalLineAlignmentWithPositiveLineSpacing(void)
+{
+ tet_infoline(" UtcDaliGetPreOffsetVerticalLineAlignmentWithPositiveLineSpacing ");
+ ToolkitTestApplication application;
+
+ uint32_t expectedNumberOfLines = 2u;
+
+ // Creates a text controller.
+ ControllerPtr controller = Controller::New();
+
+ // Configures the text controller similarly to the text-label.
+ ConfigureTextLabel(controller);
+
+ // Sets the text.
+ controller->SetMarkupProcessorEnabled(true);
+ controller->SetTextElideEnabled(false);
+ controller->SetText("<p rel-line-height=2.0>Line one Line two</p>");
+
+ // Creates the text's model and relais-out the text.
+ const Size relayoutSize(120.f, 100.f);
+ controller->Relayout(relayoutSize);
+
+ // Tests the rendering controller has been created.
+ TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
+ DALI_TEST_CHECK(typesetter);
+
+ // Tests the view model has been created.
+ ViewModel* model = typesetter->GetViewModel();
+ DALI_TEST_CHECK(model);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(model->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION);
+ DALI_TEST_CHECK(model->GetLines());
+
+ const LineRun& lineOne = *(model->GetLines() + 0u);
+ const LineRun& lineTwo = *(model->GetLines() + 1u);
+
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 9.5f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 19.0f, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPreOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliGetPostOffsetVerticalLineAlignmentWithNegativeLineSpacing(void)
+{
+ tet_infoline(" UtcDaliGetPostOffsetVerticalLineAlignmentWithNegativeLineSpacing ");
+ ToolkitTestApplication application;
+
+ uint32_t expectedNumberOfLines = 2u;
+
+ // Creates a text controller.
+ ControllerPtr controller = Controller::New();
+
+ // Configures the text controller similarly to the text-label.
+ ConfigureTextLabel(controller);
+
+ // Sets the text.
+ controller->SetMarkupProcessorEnabled(true);
+ controller->SetTextElideEnabled(false);
+ controller->SetText("<p rel-line-height=0.5>Line one Line two</p>");
+
+ // Creates the text's model and relais-out the text.
+ const Size relayoutSize(120.f, 100.f);
+ controller->Relayout(relayoutSize);
+
+ // Tests the rendering controller has been created.
+ TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
+ DALI_TEST_CHECK(typesetter);
+
+ // Tests the view model has been created.
+ ViewModel* model = typesetter->GetViewModel();
+ DALI_TEST_CHECK(model);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(model->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION);
+ DALI_TEST_CHECK(model->GetLines());
+
+ const LineRun& lineOne = *(model->GetLines() + 0u);
+ const LineRun& lineTwo = *(model->GetLines() + 1u);
+
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), -9.5f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), -9.5f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), -9.5f, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliGetPostOffsetVerticalLineAlignmentWithPositiveLineSpacing(void)
+{
+ tet_infoline(" UtcDaliGetPostOffsetVerticalLineAlignmentWithPositiveLineSpacing ");
+ ToolkitTestApplication application;
+
+ uint32_t expectedNumberOfLines = 2u;
+
+ // Creates a text controller.
+ ControllerPtr controller = Controller::New();
+
+ // Configures the text controller similarly to the text-label.
+ ConfigureTextLabel(controller);
+
+ // Sets the text.
+ controller->SetMarkupProcessorEnabled(true);
+ controller->SetTextElideEnabled(false);
+ controller->SetText("<p rel-line-height=2.0>Line one Line two</p>");
+
+ // Creates the text's model and relais-out the text.
+ const Size relayoutSize(120.f, 100.f);
+ controller->Relayout(relayoutSize);
+
+ // Tests the rendering controller has been created.
+ TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
+ DALI_TEST_CHECK(typesetter);
+
+ // Tests the view model has been created.
+ ViewModel* model = typesetter->GetViewModel();
+ DALI_TEST_CHECK(model);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(model->GetNumberOfLines(), expectedNumberOfLines, TEST_LOCATION);
+ DALI_TEST_CHECK(model->GetLines());
+
+ const LineRun& lineOne = *(model->GetLines() + 0u);
+ const LineRun& lineTwo = *(model->GetLines() + 1u);
+
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 19.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 9.5f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineOne, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::TOP), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetPostOffsetVerticalLineAlignment(lineTwo, Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM), 0.0f, TEST_LOCATION);
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 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 <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/internal/text/bounded-paragraph-run.h>
+#include <dali-toolkit/internal/text/character-spacing-character-run.h>
+#include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/strikethrough-character-run.h>
+#include <dali-toolkit/internal/text/underlined-character-run.h>
+
+using namespace Dali;
+using namespace Toolkit;
+using namespace Text;
+
+// Tests the following functions for AbstractStyleCharacterRun.
+// CharacterIndex GetStartCharacterIndex() const;
+// Length GetNumberOfCharacters() const;
+// CharacterIndex GetEndCharacterIndex() const;
+
+template<typename TYPE_OF_RUN>
+void TestAbstractStyleCharacterRunEmptyCharacterRun(std::string test_name)
+{
+ tet_infoline(" TestAbstractStyleCharacterRunEmptyCharacterRun ");
+ std::cout << " testing " << test_name << std::endl;
+
+ tet_infoline(" Default Constructor ");
+ TYPE_OF_RUN abstractStyleCharacterRun;
+
+ tet_infoline(" AbstractStyleCharacterRun_GetStartCharacterIndex ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetStartCharacterIndex(), 0u, TEST_LOCATION);
+
+ tet_infoline(" AbstractStyleCharacterRun_GetNumberOfCharacters ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetNumberOfCharacters(), 0u, TEST_LOCATION);
+
+ tet_infoline(" AbstractStyleCharacterRun_GetEndCharacterIndex ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetEndCharacterIndex(), 0u, TEST_LOCATION);
+}
+
+template<typename TYPE_OF_RUN>
+void TestAbstractStyleCharacterRunOneCharacter(std::string test_name)
+{
+ tet_infoline(" TestAbstractStyleCharacterRunOneCharacter ");
+ std::cout << " testing " << test_name << std::endl;
+
+ TYPE_OF_RUN abstractStyleCharacterRun;
+ abstractStyleCharacterRun.characterRun.numberOfCharacters = 1u;
+ tet_infoline(" AbstractStyleCharacterRun_GetStartCharacterIndex ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetStartCharacterIndex(), 0u, TEST_LOCATION);
+
+ tet_infoline(" AbstractStyleCharacterRun_GetNumberOfCharacters ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetNumberOfCharacters(), 1u, TEST_LOCATION);
+
+ tet_infoline(" AbstractStyleCharacterRun_GetEndCharacterIndex ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetEndCharacterIndex(), 0u, TEST_LOCATION);
+
+ abstractStyleCharacterRun.characterRun.characterIndex = 5u;
+ tet_infoline(" AbstractStyleCharacterRun_GetStartCharacterIndex ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetStartCharacterIndex(), 5u, TEST_LOCATION);
+
+ tet_infoline(" AbstractStyleCharacterRun_GetNumberOfCharacters ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetNumberOfCharacters(), 1u, TEST_LOCATION);
+
+ tet_infoline(" AbstractStyleCharacterRun_GetEndCharacterIndex ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetEndCharacterIndex(), 5u, TEST_LOCATION);
+}
+
+template<typename TYPE_OF_RUN>
+void TestAbstractStyleCharacterRunMoreThanOneCharacter(std::string test_name)
+{
+ tet_infoline(" TestAbstractStyleCharacterRunOneCharacter ");
+ std::cout << " testing " << test_name << std::endl;
+
+ TYPE_OF_RUN abstractStyleCharacterRun;
+ abstractStyleCharacterRun.characterRun.numberOfCharacters = 15u;
+ tet_infoline(" AbstractStyleCharacterRun_GetStartCharacterIndex ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetStartCharacterIndex(), 0u, TEST_LOCATION);
+
+ tet_infoline(" AbstractStyleCharacterRun_GetNumberOfCharacters ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetNumberOfCharacters(), 15u, TEST_LOCATION);
+
+ tet_infoline(" AbstractStyleCharacterRun_GetEndCharacterIndex ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetEndCharacterIndex(), 14u, TEST_LOCATION);
+
+ abstractStyleCharacterRun.characterRun.characterIndex = 5u;
+ tet_infoline(" AbstractStyleCharacterRun_GetStartCharacterIndex ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetStartCharacterIndex(), 5u, TEST_LOCATION);
+
+ tet_infoline(" AbstractStyleCharacterRun_GetNumberOfCharacters ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetNumberOfCharacters(), 15u, TEST_LOCATION);
+
+ tet_infoline(" AbstractStyleCharacterRun_GetEndCharacterIndex ");
+ DALI_TEST_EQUALS(abstractStyleCharacterRun.GetEndCharacterIndex(), 19u, TEST_LOCATION);
+}
+
+int UtcDaliTextAbstractStyleCharacterRun(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextAbstractStyleCharacterRun");
+
+ TestAbstractStyleCharacterRunEmptyCharacterRun<Dali::Toolkit::Text::ColorRun>("ColorRun");
+ TestAbstractStyleCharacterRunEmptyCharacterRun<Dali::Toolkit::Text::CharacterSpacingCharacterRun>("CharacterSpacingCharacterRun");
+ TestAbstractStyleCharacterRunEmptyCharacterRun<Dali::Toolkit::Text::FontDescriptionRun>("FontDescriptionRun");
+ TestAbstractStyleCharacterRunEmptyCharacterRun<Dali::Toolkit::Text::UnderlinedCharacterRun>("UnderlinedCharacterRun");
+ TestAbstractStyleCharacterRunEmptyCharacterRun<Dali::Toolkit::Text::StrikethroughCharacterRun>("StrikethroughCharacterRun");
+ TestAbstractStyleCharacterRunEmptyCharacterRun<Dali::Toolkit::Text::BoundedParagraphRun>("BoundedParagraphRun");
+
+ TestAbstractStyleCharacterRunOneCharacter<Dali::Toolkit::Text::ColorRun>("ColorRun");
+ TestAbstractStyleCharacterRunOneCharacter<Dali::Toolkit::Text::CharacterSpacingCharacterRun>("CharacterSpacingCharacterRun");
+ TestAbstractStyleCharacterRunOneCharacter<Dali::Toolkit::Text::FontDescriptionRun>("FontDescriptionRun");
+ TestAbstractStyleCharacterRunOneCharacter<Dali::Toolkit::Text::UnderlinedCharacterRun>("UnderlinedCharacterRun");
+ TestAbstractStyleCharacterRunOneCharacter<Dali::Toolkit::Text::StrikethroughCharacterRun>("StrikethroughCharacterRun");
+ TestAbstractStyleCharacterRunOneCharacter<Dali::Toolkit::Text::BoundedParagraphRun>("BoundedParagraphRun");
+
+ TestAbstractStyleCharacterRunMoreThanOneCharacter<Dali::Toolkit::Text::ColorRun>("ColorRun");
+ TestAbstractStyleCharacterRunMoreThanOneCharacter<Dali::Toolkit::Text::CharacterSpacingCharacterRun>("CharacterSpacingCharacterRun");
+ TestAbstractStyleCharacterRunMoreThanOneCharacter<Dali::Toolkit::Text::FontDescriptionRun>("FontDescriptionRun");
+ TestAbstractStyleCharacterRunMoreThanOneCharacter<Dali::Toolkit::Text::UnderlinedCharacterRun>("UnderlinedCharacterRun");
+ TestAbstractStyleCharacterRunMoreThanOneCharacter<Dali::Toolkit::Text::StrikethroughCharacterRun>("StrikethroughCharacterRun");
+ TestAbstractStyleCharacterRunMoreThanOneCharacter<Dali::Toolkit::Text::BoundedParagraphRun>("BoundedParagraphRun");
+
+ END_TEST;
+}
.Add(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME)
.Add(ImageVisual::Property::MASK_CONTENT_SCALE, 1.6f)
.Add(ImageVisual::Property::CROP_TO_MASK, true)
+ .Add(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING)
.Add(DevelVisual::Property::CORNER_RADIUS, 22.2f)
.Add(DevelVisual::Property::CORNER_RADIUS_POLICY, Visual::Transform::Policy::ABSOLUTE)
.Add(DevelVisual::Property::BORDERLINE_WIDTH, 33.3f)
DALI_TEST_CHECK(value);
DALI_TEST_EQUALS(value->Get<bool>(), true, TEST_LOCATION);
+ value = resultMap.Find(DevelImageVisual::Property::MASKING_TYPE, Property::INTEGER);
+ DALI_TEST_CHECK(value);
+ DALI_TEST_CHECK(value->Get<int>() == DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
Vector2 naturalSize;
animatedImageVisual.GetNaturalSize(naturalSize);
DALI_TEST_EQUALS(naturalSize, Vector2(100, 100), TEST_LOCATION);
.Add("alphaMaskUrl", TEST_MASK_IMAGE_FILE_NAME)
.Add("maskContentScale", 1.6f)
.Add("cropToMask", true)
+ .Add(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING)
.Add("cornerRadius", Vector4(50.0f, 25.0f, 12.5f, 33.0f))
.Add("cornerRadiusPolicy", Visual::Transform::Policy::RELATIVE)
.Add("borderlineWidth", 20.0f)
DALI_TEST_CHECK(value);
DALI_TEST_EQUALS(value->Get<bool>(), true, TEST_LOCATION);
+ value = resultMap.Find(DevelImageVisual::Property::MASKING_TYPE, Property::INTEGER);
+ DALI_TEST_CHECK(value);
+ DALI_TEST_CHECK(value->Get<int>() == DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
END_TEST;
}
.Add("alphaMaskUrl", TEST_MASK_IMAGE_FILE_NAME)
.Add("maskContentScale", 1.6f)
.Add("cropToMask", true)
+ .Add(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING)
.Add("cornerRadius", 50.5f));
Property::Map resultMap;
DALI_TEST_CHECK(value);
DALI_TEST_EQUALS(value->Get<bool>(), true, TEST_LOCATION);
+ value = resultMap.Find(DevelImageVisual::Property::MASKING_TYPE, Property::INTEGER);
+ DALI_TEST_CHECK(value);
+ DALI_TEST_CHECK(value->Get<bool>() == DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
END_TEST;
}
END_TEST;
}
-int UtcDaliAnimatedImageVisualSynchronousLoadingWithAlphaMask(void)
+int UtcDaliAnimatedImageVisualSynchronousLoadingWithAlphaMask01(void)
{
ToolkitTestApplication application;
- TestGlAbstraction& gl = application.GetGlAbstraction();
+ tet_infoline("UtcDaliAnimatedImageVisualSynchronousLoadingWithAlphaMask01 for CPU Alpha Masking");
+ TestGlAbstraction& gl = application.GetGlAbstraction();
{
Property::Map propertyMap;
END_TEST;
}
+int UtcDaliAnimatedImageVisualSynchronousLoadingWithAlphaMask02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliAnimatedImageVisualSynchronousLoadingWithAlphaMask02 for GPU Alpha Masking");
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ {
+ Property::Map propertyMap;
+ propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 2);
+ propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 2);
+ propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 20);
+ propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME);
+ propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+ propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS, 0.23f);
+ propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS_POLICY, Visual::Transform::Policy::ABSOLUTE);
+
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+
+ Property::Map testMap;
+ visual.CreatePropertyMap(testMap);
+ DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION);
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+ dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(dummyControl);
+
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ application.SendNotification();
+ application.Render(20);
+
+ // The first frame is loaded synchronously and load next batch with masking
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::GetTimerCount(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 4, TEST_LOCATION);
+
+ dummyControl.Unparent();
+ }
+ tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.SendNotification();
+ application.Render(16);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliAnimatedImageVisualJumpToAction(void)
{
ToolkitTestApplication application;
int UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask01(void)
{
ToolkitTestApplication application;
- TestGlAbstraction& gl = application.GetGlAbstraction();
+ tet_infoline("UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask01 for CPU Alpha Masking");
+ TestGlAbstraction& gl = application.GetGlAbstraction();
{
Property::Map propertyMap;
END_TEST;
}
+int UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask02 for GPU Alpha Masking");
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ {
+ Property::Map propertyMap;
+ propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 2);
+ propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 4);
+ propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 20);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME);
+ propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+ dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(dummyControl);
+
+ application.SendNotification();
+ application.Render();
+
+ // load two frame(batch size), load mask image, and request two masking
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(20);
+
+ DALI_TEST_EQUALS(gl.GetLastGenTextureId(), 3, TEST_LOCATION);
+
+ dummyControl.Unparent();
+ }
+ tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.SendNotification();
+ application.Render(20);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask03(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask03 for GPU Alpha Masking with broken mask texture");
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ {
+ Property::Map propertyMap;
+ propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 2);
+ propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 4);
+ propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 20);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, "");
+ propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+ dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(dummyControl);
+
+ application.SendNotification();
+ application.Render();
+
+ // load two frame(batch size), load mask image, and request two masking
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(20);
+
+ DALI_TEST_EQUALS(gl.GetLastGenTextureId(), 3, TEST_LOCATION);
+
+ dummyControl.Unparent();
+ }
+ tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.SendNotification();
+ application.Render(20);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliAnimatedImageVisualMultiImage01(void)
{
ToolkitTestApplication application;
application.SendNotification();
application.Render();
- // Wait for rasterization
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ // Wait for loading & rasterization
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
DALI_TEST_EQUALS(control.IsResourceReady(), true, TEST_LOCATION);
DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION);
{
tet_infoline("Test signal handler various case.");
- ToolkitTestApplication application;
+ auto TestResourceReadyUrl = [](int eventTriggerCount, bool isSynchronous, bool loadSuccess, const std::string& url, const std::string& mask, const char* location) {
+ ToolkitTestApplication application;
- auto TestResourceReadyUrl = [&application](int eventTriggerCount, bool isSynchronous, bool loadSuccess, const std::string& url, const std::string& mask, const char* location) {
gResourceReadySignalCounter = 0;
Property::Map map;
imageView.Unparent();
};
- auto TestAuxiliaryResourceReadyUrl = [&application](bool isSynchronous, bool loadSuccess, const std::string& url, const std::string& auxiliaryUrl, const char* location) {
+ auto TestAuxiliaryResourceReadyUrl = [](bool isSynchronous, bool loadSuccess, const std::string& url, const std::string& auxiliaryUrl, const char* location) {
+ ToolkitTestApplication application;
+
gResourceReadySignalCounter = 0;
Property::Map map;
END_TEST;
}
-int UtcDaliImageVisualAlphaMask(void)
+int UtcDaliImageVisualAlphaMask01(void)
{
ToolkitTestApplication application;
tet_infoline("Request image visual with a Property::Map containing an Alpha mask");
END_TEST;
}
-int UtcDaliImageVisualSynchronousLoadAlphaMask(void)
+int UtcDaliImageVisualAlphaMask02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU");
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK(factory);
+
+ Property::Map propertyMap;
+ propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME);
+ propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+ DALI_TEST_CHECK(visual);
+
+ Property::Map testMap;
+ visual.CreatePropertyMap(testMap);
+ DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION);
+ DALI_TEST_EQUALS(*testMap.Find(DevelImageVisual::Property::MASKING_TYPE), Property::Value(DevelImageVisual::MaskingType::MASKING_ON_RENDERING), TEST_LOCATION);
+
+ // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied.
+ // Image with a size smaller than 512*512 will be uploaded as a part of the atlas.
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ DummyControl actor = DummyControl::New();
+ DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual);
+
+ actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION);
+
+ application.GetScene().Add(actor);
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+ Renderer renderer = actor.GetRendererAt(0u);
+ TextureSet textures = renderer.GetTextures();
+ DALI_TEST_CHECK(textures);
+ DALI_TEST_EQUALS(textures.GetTextureCount(), 2u, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+
+ dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1);
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliImageVisualAlphaMask03(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU with fail case");
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK(factory);
+
+ Property::Map propertyMap;
+ propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, "dummy_path");
+ propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+ DALI_TEST_CHECK(visual);
+
+ Property::Map testMap;
+ visual.CreatePropertyMap(testMap);
+
+ // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied.
+ // Image with a size smaller than 512*512 will be uploaded as a part of the atlas.
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ DummyControl actor = DummyControl::New();
+ DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual);
+
+ actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION);
+
+ application.GetScene().Add(actor);
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+ Renderer renderer = actor.GetRendererAt(0u);
+ TextureSet textures = renderer.GetTextures();
+ DALI_TEST_CHECK(textures);
+ DALI_TEST_EQUALS(textures.GetTextureCount(), 1u, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+
+ dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1);
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliImageVisualSynchronousLoadAlphaMask01(void)
{
ToolkitTestApplication application;
tet_infoline("Request image visual with a Property::Map containing an Alpha mask with synchronous loading");
END_TEST;
}
+int UtcDaliImageVisualSynchronousLoadAlphaMask02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU with synchronous loading");
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK(factory);
+
+ Property::Map propertyMap;
+ propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true);
+ propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+ DALI_TEST_CHECK(visual);
+
+ Property::Map testMap;
+ visual.CreatePropertyMap(testMap);
+ DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION);
+
+ // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied.
+ // Image with a size smaller than 512*512 will be uploaded as a part of the atlas.
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ DummyControl actor = DummyControl::New();
+ DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual);
+
+ actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION);
+
+ application.GetScene().Add(actor);
+
+ // Do not wait for any EventThreadTrigger in synchronous alpha mask.
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+ Renderer renderer = actor.GetRendererAt(0u);
+ TextureSet textures = renderer.GetTextures();
+ DALI_TEST_CHECK(textures);
+ DALI_TEST_EQUALS(textures.GetTextureCount(), 2u, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+
+ dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1);
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliImageVisualRemoteAlphaMask(void)
{
ToolkitTestApplication application;
application.SendNotification();
application.Render(0);
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ // Wait for loading & rasterization
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
Renderer renderer = actor.GetRendererAt(0);
auto textures = renderer.GetTextures();
application.SendNotification();
application.Render();
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ // Wait for loading & rasterization
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
Renderer renderer = dummy.GetRendererAt(0);
Shader shader2 = renderer.GetShader();
int UtcDaliVisualRoundedCorner(void)
{
- ToolkitTestApplication application;
tet_infoline("UtcDaliVisualRoundedCorner");
static std::vector<UniformData> customUniforms =
UniformData("cornerRadiusPolicy", Property::Type::FLOAT),
};
- TestGraphicsController& graphics = application.GetGraphicsController();
- graphics.AddCustomUniforms(customUniforms);
-
// image visual
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
float cornerRadius = 30.0f;
// color visual 1
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
float cornerRadius = 30.0f;
// color visual 2
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
Vector4 cornerRadius(0.5f, 0.5f, 0.5f, 0.3f);
// color visual 3 - invalid value
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
Vector4 cornerRadius(30.0f, 30.0f, 30.0f, 20.0f);
// gradient visual
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
float cornerRadius = 30.0f;
// animated image visual
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
Vector4 cornerRadius(24.0f, 23.0f, 22.0f, 21.0f);
// vector image visual
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
Vector4 cornerRadius(27.0f, 72.0f, 11.0f, 500.5f);
application.SendNotification();
application.Render();
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ // Wait for loading & rasterization
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
application.SendNotification();
application.Render();
// animated vector image visual
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
float cornerRadius = 1.3f;
int UtcDaliVisualBorderline(void)
{
- ToolkitTestApplication application;
tet_infoline("UtcDaliVisualBorderline");
static std::vector<UniformData> customUniforms =
UniformData("borderlineOffset", Property::Type::FLOAT),
};
- TestGraphicsController& graphics = application.GetGraphicsController();
- graphics.AddCustomUniforms(customUniforms);
-
// image visual
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
float cornerRadius = 5.0f;
// color visual 1
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
Vector4 cornerRadius(23.0f, 2.0f, 3.0f, 2.3f);
// color visual 2, default color, default offset
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
float borderlineWidth = 30.0f;
// color visual 3, offset not [-1.0 ~ 1.0], but uniform value is same anyway
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
float borderlineWidth = 30.0f;
// gradient visual
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
float borderlineWidth = 30.0f;
// animated image visual
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
float borderlineWidth = 24.0f;
// vector image visual
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
Vector4 cornerRadius(54.0f, 43.0f, 32.0f, 21.0f);
application.SendNotification();
application.Render();
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ // Wait for loading & rasterization
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
application.SendNotification();
application.Render();
// animated vector image visual
{
+ ToolkitTestApplication application;
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.AddCustomUniforms(customUniforms);
+
VisualFactory factory = VisualFactory::Get();
Property::Map properties;
Vector4 cornerRadius(1.3f, 0.0f, 0.4f, 0.2f);
application.SendNotification();
application.Render();
- // Wait for image loading
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ // Wait for loading & rasterization
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
application.SendNotification();
application.Render();
// Either application.SendNotification() or the trigger can now complete the task.
application.SendNotification();
application.Render();
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ // Wait for loading & rasterization
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
// renderer is added to actor
DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
// Either application.SendNotification() or the trigger can now complete the task.
application.SendNotification();
application.Render();
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ // Wait for loading & rasterization
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
// renderer is added to actor
DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
DALI_TEST_CHECK(actor.GetRendererCount() == 0u);
application.SendNotification();
application.Render();
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ // Wait for loading & rasterization
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
// renderer is added to actor
DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
* @details Name "redrawInScalingDown", type Property::BOOLEAN.
* @note It is used in the AnimatedVectorImageVisual. The default is true.
*/
- REDRAW_IN_SCALING_DOWN
+ REDRAW_IN_SCALING_DOWN = ORIENTATION_CORRECTION + 11,
+
+ /**
+ * @brief Whether to apply mask in loading time or rendering time.
+ * @details Name "maskingType", type PlayState::Type (Property::INTEGER).
+ * @note It is used in the ImageVisual and AnimatedImageVisual. The default is MASKING_ON_LOADING.
+ */
+ MASKING_TYPE = ORIENTATION_CORRECTION + 12
};
} //namespace Property
} // namespace LoopingMode
+/**
+ * @brief Enumeration for what masking type is in.
+ */
+namespace MaskingType
+{
+enum Type
+{
+ MASKING_ON_RENDERING, ///< Alpha masking is applied for each rendering time. (On GPU)
+ MASKING_ON_LOADING ///< Alpha masking is applied when the image is loading. (On CPU)
+};
+
+}
+
} // namespace DevelImageVisual
} // namespace Toolkit
${toolkit_src_dir}/image-loader/image-load-thread.cpp
${toolkit_src_dir}/image-loader/image-url-impl.cpp
${toolkit_src_dir}/styling/style-manager-impl.cpp
+ ${toolkit_src_dir}/text/abstract-style-character-run.cpp
${toolkit_src_dir}/text/bidirectional-support.cpp
${toolkit_src_dir}/text/bounded-paragraph-helper-functions.cpp
${toolkit_src_dir}/text/character-set-conversion.cpp
${toolkit_src_dir}/text/multi-language-support.cpp
${toolkit_src_dir}/text/hidden-text.cpp
${toolkit_src_dir}/text/input-filter.cpp
+ ${toolkit_src_dir}/text/line-helper-functions.cpp
${toolkit_src_dir}/text/property-string-parser.cpp
${toolkit_src_dir}/text/segmentation.cpp
${toolkit_src_dir}/text/shaper.cpp
#ifndef IS_REQUIRED_BORDERLINE
#define IS_REQUIRED_BORDERLINE 0
#endif
+#ifndef IS_REQUIRED_ALPHA_MASKING
+#define IS_REQUIRED_ALPHA_MASKING 0
+#endif
#ifndef ATLAS_DEFAULT_WARP
#define ATLAS_DEFAULT_WARP 0
#endif
#endif
uniform sampler2D sTexture;
+
+#if IS_REQUIRED_ALPHA_MASKING
+uniform sampler2D sMaskTexture;
+INPUT mediump vec2 vMaskTexCoord;
+#endif
+
#if ATLAS_DEFAULT_WARP
uniform mediump vec4 uAtlasRect;
#elif ATLAS_CUSTOM_WARP
lowp vec4 textureColor = TEXTURE( sTexture, texCoord ) * vec4( mixColor, 1.0 ) * uColor;
+#if IS_REQUIRED_ALPHA_MASKING
+ mediump float maskAlpha = TEXTURE(sMaskTexture, vMaskTexCoord).a;
+ textureColor.a *= maskAlpha;
+ textureColor.rgb *= mix(1.0, maskAlpha, preMultipliedAlpha);
+#endif
+
#if IS_REQUIRED_ROUNDED_CORNER || IS_REQUIRED_BORDERLINE
// skip most potential calculate for performance
if(abs(vPosition.x) < vOptRectSize.x && abs(vPosition.y) < vOptRectSize.y)
#ifndef IS_REQUIRED_BORDERLINE
#define IS_REQUIRED_BORDERLINE 0
#endif
+#ifndef IS_REQUIRED_ALPHA_MASKING
+#define IS_REQUIRED_ALPHA_MASKING 0
+#endif
INPUT mediump vec2 aPosition;
OUTPUT mediump vec2 vTexCoord;
uniform mediump vec4 cornerRadius;
uniform mediump float cornerRadiusPolicy;
#endif
+#if IS_REQUIRED_ALPHA_MASKING
+OUTPUT mediump vec2 vMaskTexCoord;
+uniform lowp float cropToMask;
+uniform mediump vec2 maskTextureRatio;
+#endif
uniform mediump vec2 extraSize;
vec4 ComputeVertexPosition()
mediump vec2 vPosition = aPosition * visualSize;
#endif
- vTexCoord = pixelArea.xy + pixelArea.zw * (vPosition.xy / max(vec2(1.0), visualSize) + vec2(0.5));
+ vec4 finalPixelArea = pixelArea;
+#if IS_REQUIRED_ALPHA_MASKING
+ finalPixelArea = mix(pixelArea,
+ vec4(
+ vec2(0.5) + (pixelArea.xy - vec2(0.5)) * maskTextureRatio,
+ pixelArea.zw * maskTextureRatio
+ ),
+ cropToMask);
+ vMaskTexCoord = pixelArea.xy + pixelArea.zw * (vPosition.xy / max(vec2(1.0), visualSize) + vec2(0.5));
+#endif
+ vTexCoord = finalPixelArea.xy + finalPixelArea.zw * (vPosition.xy / max(vec2(1.0), visualSize) + vec2(0.5));
+
return vec4(vPosition + anchorPoint * visualSize + (visualOffset + origin) * uSize.xy, 0.0, 1.0);
}
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/text/abstract-style-character-run.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+CharacterIndex AbstractStyleCharacterRun::GetStartCharacterIndex() const
+{
+ return characterRun.characterIndex;
+}
+
+Length AbstractStyleCharacterRun::GetNumberOfCharacters() const
+{
+ return characterRun.numberOfCharacters;
+}
+
+CharacterIndex AbstractStyleCharacterRun::GetEndCharacterIndex() const
+{
+ return characterRun.GetEndCharacterIndex();
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_TOOLKIT_TEXT_ABSTRACT_STYLE_CHARACTER_RUN_H
+#define DALI_TOOLKIT_TEXT_ABSTRACT_STYLE_CHARACTER_RUN_H
+
+/*
+ * Copyright (c) 2022 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/type-traits.h>
+#include <dali/public-api/math/vector4.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-run.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+/**
+ * @brief Run of characters with the same style.
+ */
+struct AbstractStyleCharacterRun
+{
+ CharacterRun characterRun; ///< The initial character index and the number of characters of the run.
+
+ // Constructors
+
+protected:
+ /**
+ * @brief Constructor.
+ * Default constructor to set the default values
+ */
+ AbstractStyleCharacterRun()
+ : characterRun{}
+ {
+ }
+
+ /**
+ * @brief Constructor.
+ * Default constructor to set the default values
+ *
+ * @param[in] characterRun the character run
+ */
+ AbstractStyleCharacterRun(const CharacterRun& characterRun)
+ : characterRun{characterRun}
+ {
+ }
+
+public:
+ AbstractStyleCharacterRun(const AbstractStyleCharacterRun&) = default;
+
+ AbstractStyleCharacterRun(AbstractStyleCharacterRun&&) noexcept = default;
+
+ // Operators
+
+ AbstractStyleCharacterRun& operator=(const AbstractStyleCharacterRun&) = default;
+
+ AbstractStyleCharacterRun& operator=(AbstractStyleCharacterRun&&) noexcept = default;
+
+ /**
+ * @brief Destructor.
+ */
+ virtual ~AbstractStyleCharacterRun() = default;
+
+ //Methods
+
+ /**
+ * @brief Retrive the first index in run.
+ * @return the end character index in run.
+ */
+ CharacterIndex GetStartCharacterIndex() const;
+
+ /**
+ * @brief Retrive the number of characters in the run.
+ * @return the the number of characters in run.
+ */
+ Length GetNumberOfCharacters() const;
+
+ /**
+ * @brief Calculate the end index in run.
+ * @return the end character index in run.
+ */
+ CharacterIndex GetEndCharacterIndex() const;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+// Allow AbstractStyleCharacterRun to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::AbstractStyleCharacterRun> : public Dali::BasicTypes<Dali::Toolkit::Text::AbstractStyleCharacterRun>
+{
+ enum
+ {
+ IS_TRIVIAL_TYPE = true
+ };
+};
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_ABSTRACT_STYLE_CHARACTER_RUN_H
#include <dali/public-api/math/vector2.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/character-run.h>
+#include <dali-toolkit/internal/text/abstract-style-character-run.h>
#include <dali-toolkit/public-api/text/text-enumerations.h>
namespace Dali
* Bounded-paragraph could contain multi paragraphs that have been breaked by Paragraph Separators or appropriate Newline Functions.
* This will be used to handle information for the attributes of markup tag. Like TextAlign, TextDirection, TextIndent, LineHeight, etc.
*/
-struct BoundedParagraphRun
+struct BoundedParagraphRun : public AbstractStyleCharacterRun
{
/**
* Default constructor to set the default values of bitfields
*/
BoundedParagraphRun()
- : characterRun{},
+ : AbstractStyleCharacterRun(),
horizontalAlignment(Text::HorizontalAlignment::BEGIN),
relativeLineSize(1),
horizontalAlignmentDefined{false},
{
}
- CharacterRun characterRun; ///< The initial character index within the whole text and the number of characters of the run.
Text::HorizontalAlignment::Type horizontalAlignment; ///< The paragraph horizontal alignment. Values "BEGIN" "CENTER" "END".
float relativeLineSize; ///< The relative line height to be used for this paragaraph.
bool horizontalAlignmentDefined : 1; ///< Whether the horizontal alignment is defined.
} // namespace Toolkit
+// Allow BoundedParagraphRun to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::BoundedParagraphRun> : public Dali::BasicTypes<Dali::Toolkit::Text::BoundedParagraphRun>
+{
+ enum
+ {
+ IS_TRIVIAL_TYPE = true
+ };
+};
+
} // namespace Dali
#endif // DALI_TOOLKIT_TEXT_BOUNDED_PARAGRAPH_RUN_H
*
*/
-// EXTERNAL INCLUDES
-#include <dali/public-api/math/vector4.h>
-
// INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/character-run.h>
+#include <dali-toolkit/internal/text/abstract-style-character-run.h>
namespace Dali
{
/**
* @brief Run of character-spacing characters with same properties.
*/
-struct CharacterSpacingCharacterRun
+struct CharacterSpacingCharacterRun : public AbstractStyleCharacterRun
{
/**
- * Default constructor to set the default values of bitfields
+ * @brief Constructor.
+ * Default constructor to set the default values
*/
CharacterSpacingCharacterRun()
- : characterRun{},
+ : AbstractStyleCharacterRun(),
value{0.f} //The default value is 0.f which does nothing.
{
}
- CharacterRun characterRun; ///< The initial character index and the number of characters of the run.
- float value; /// The spaces between characters in Pixels. A positive value will make the characters far apart (expanded) and a negative value will bring them closer (condensed).
+ float value; /// The spaces between characters in Pixels. A positive value will make the characters far apart (expanded) and a negative value will bring them closer (condensed).
//TODO: Add unit property to choose between Pixel or Scale (%)
};
} // namespace Toolkit
+// Allow ColorRun to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::CharacterSpacingCharacterRun> : public Dali::BasicTypes<Dali::Toolkit::Text::CharacterSpacingCharacterRun>
+{
+ enum
+ {
+ IS_TRIVIAL_TYPE = true
+ };
+};
+
} // namespace Dali
#endif // DALI_TOOLKIT_TEXT_CHARACTER_SPACING_CHARACTER_RUN_H
#define DALI_TOOLKIT_TEXT_COLOR_RUN_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
*
*/
-// EXTERNAL INCLUDES
-#include <dali/public-api/math/vector4.h>
-
// INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/character-run.h>
-#include <dali-toolkit/internal/text/glyph-run.h>
+#include <dali-toolkit/internal/text/abstract-style-character-run.h>
namespace Dali
{
/**
* @brief Run of characters with the same color.
*/
-struct ColorRun
+struct ColorRun : public AbstractStyleCharacterRun
{
- CharacterRun characterRun; ///< The initial character index and the number of characters of the run.
- Vector4 color; ///< The color of the characters.
+ /**
+ * @brief Constructor.
+ * Default constructor to set the default values
+ */
+ ColorRun()
+ : AbstractStyleCharacterRun()
+ {
+ }
+ Vector4 color; ///< The color of the characters.
};
} // namespace Text
} // namespace Toolkit
+// Allow ColorRun to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::ColorRun> : public Dali::BasicTypes<Dali::Toolkit::Text::ColorRun>
+{
+ enum
+ {
+ IS_TRIVIAL_TYPE = true
+ };
+};
+
} // namespace Dali
#endif // DALI_TOOLKIT_TEXT_COLOR_RUN_H
#define DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
#include <dali/devel-api/text-abstraction/font-list.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/character-run.h>
+#include <dali-toolkit/internal/text/abstract-style-character-run.h>
#include <dali-toolkit/internal/text/text-definitions.h>
namespace Dali
/**
* @brief Run of characters with the same font.
*/
-struct FontDescriptionRun
+struct FontDescriptionRun : public AbstractStyleCharacterRun
{
/**
* Default constructor to set the default values of bitfields
*/
FontDescriptionRun()
- : characterRun{},
+ : AbstractStyleCharacterRun(),
familyName{nullptr},
familyLength{0u},
weight{FontWeight::NONE},
bool widthDefined,
bool slantDefined,
bool sizeDefined)
- : characterRun{characterRun},
+ : AbstractStyleCharacterRun(characterRun),
familyName{familyName},
familyLength{familyLength},
weight{weight},
{
}
- CharacterRun characterRun; ///< The initial character index and the number of characters of the run.
char* familyName; ///< The font's family name.
Length familyLength; ///< The length of the font's family name.
FontWeight weight; ///< The font's weight.
} // namespace Toolkit
+// Allow FontDescriptionRun to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::FontDescriptionRun> : public Dali::BasicTypes<Dali::Toolkit::Text::FontDescriptionRun>
+{
+ enum
+ {
+ IS_TRIVIAL_TYPE = true
+ };
+};
+
} // namespace Dali
#endif // DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H
--- /dev/null
+/*
+ * Copyright (c) 2021 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.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/text/line-helper-functions.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+float GetPreOffsetVerticalLineAlignment(const LineRun& line, const DevelText::VerticalLineAlignment::Type& verLineAlign)
+{
+ // Calculate vertical line alignment
+ float offset = 0.0f;
+
+ switch(verLineAlign)
+ {
+ case DevelText::VerticalLineAlignment::TOP:
+ {
+ break;
+ }
+ case DevelText::VerticalLineAlignment::MIDDLE:
+ {
+ offset = line.lineSpacing * 0.5f;
+ break;
+ }
+ case DevelText::VerticalLineAlignment::BOTTOM:
+ {
+ offset = line.lineSpacing;
+ break;
+ }
+ }
+
+ // Apply TOP case when the lineSpacing is less than zero.
+ offset = line.lineSpacing < 0.0f ? 0.0f : offset;
+
+ return offset;
+}
+
+float GetPostOffsetVerticalLineAlignment(const LineRun& line, const DevelText::VerticalLineAlignment::Type& verLineAlign)
+{
+ // Calculate vertical line alignment
+ float offset = 0.0f;
+
+ switch(verLineAlign)
+ {
+ case DevelText::VerticalLineAlignment::TOP:
+ {
+ offset = line.lineSpacing;
+ break;
+ }
+ case DevelText::VerticalLineAlignment::MIDDLE:
+ {
+ offset = line.lineSpacing * 0.5f;
+ break;
+ }
+ case DevelText::VerticalLineAlignment::BOTTOM:
+ {
+ break;
+ }
+ }
+
+ // Apply TOP case when the lineSpacing is less than zero.
+ offset = line.lineSpacing < 0.0f ? line.lineSpacing : offset;
+
+ return offset;
+}
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_TOOLKIT_TEXT_LINE_HELPER_FUNCTIONS_H
+#define DALI_TOOLKIT_TEXT_LINE_HELPER_FUNCTIONS_H
+
+/*
+ * Copyright (c) 2021 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+
+#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
+#include <dali-toolkit/internal/text/line-run.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+/**
+ * @brief Retrieves the vertical offset to shift text inside line to up by negative value and to down by positive value.
+ * The shifting depends on the vertical line alignment @p verLineAlign and lineSpacing when the lineSpacing is poistive.
+ * When the lineSpacing is negative then ignore @p verLineAlign
+ * @param[in] line the line.
+ * @param[in] line the line.
+ *
+ * @return The vertical offset before text.
+ */
+float GetPreOffsetVerticalLineAlignment(const LineRun& line, const Dali::Toolkit::DevelText::VerticalLineAlignment::Type& verLineAlign);
+
+/**
+ * @brief Retrieves the vertical offset to shift the next line to up by negative value and to down by positive value.
+ * The shifting depends on the vertical line alignment @p verLineAlign and lineSpacing when the lineSpacing is poistive.
+ * When the lineSpacing is negative then ignore @p verLineAlign
+ * @param[in] line the line.
+ * @param[in] line the line.
+ *
+ * @return The vertical offset after text.
+ */
+float GetPostOffsetVerticalLineAlignment(const LineRun& line, const Dali::Toolkit::DevelText::VerticalLineAlignment::Type& verLineAlign);
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_LINE_HELPER_FUNCTIONS_H
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/text-controls/text-label-devel.h>
#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
+#include <dali-toolkit/internal/text/line-helper-functions.h>
#include <dali-toolkit/internal/text/rendering/styles/character-spacing-helper-functions.h>
#include <dali-toolkit/internal/text/rendering/styles/strikethrough-helper-functions.h>
#include <dali-toolkit/internal/text/rendering/styles/underline-helper-functions.h>
const Vector4* const backgroundColorsBuffer = model->GetBackgroundColors();
const ColorIndex* const backgroundColorIndicesBuffer = model->GetBackgroundColorIndices();
+ const DevelText::VerticalLineAlignment::Type verLineAlign = model->GetVerticalLineAlignment();
+
// Create and initialize the pixel buffer.
GlyphData glyphData;
glyphData.verticalOffset = verticalOffset;
glyphData.horizontalOffset += horizontalOffset;
// Increases the vertical offset with the line's ascender.
- glyphData.verticalOffset += static_cast<int32_t>(line.ascender);
-
- // Include line spacing after first line
- if(lineIndex > 0u)
- {
- glyphData.verticalOffset += static_cast<int32_t>(line.lineSpacing);
- }
+ glyphData.verticalOffset += static_cast<int32_t>(line.ascender + GetPreOffsetVerticalLineAlignment(line, verLineAlign));
float left = bufferWidth;
float right = 0.0f;
}
// Increases the vertical offset with the line's descender.
- glyphData.verticalOffset += static_cast<int32_t>(-line.descender);
+ glyphData.verticalOffset += static_cast<int32_t>(-line.descender + GetPostOffsetVerticalLineAlignment(line, verLineAlign));
}
return glyphData.bitmapBuffer;
}
}
- // Calculate vertical line alignment
- switch(mModel->GetVerticalLineAlignment())
- {
- case DevelText::VerticalLineAlignment::TOP:
- {
- break;
- }
- case DevelText::VerticalLineAlignment::MIDDLE:
- {
- const auto& line = *mModel->GetLines();
- penY -= line.descender;
- penY += static_cast<int32_t>(line.lineSpacing * 0.5f + line.descender);
- break;
- }
- case DevelText::VerticalLineAlignment::BOTTOM:
- {
- const auto& line = *mModel->GetLines();
- const auto lineHeight = line.ascender + (-line.descender) + line.lineSpacing;
- penY += static_cast<int32_t>(lineHeight - (line.ascender - line.descender));
- break;
- }
- }
-
// Generate the image buffers of the text for each different style first,
// then combine all of them together as one final image buffer. We try to
// do all of these in CPU only, so that once the final texture is generated,
const Vector<CharacterIndex>& glyphToCharacterMap = mModel->GetGlyphsToCharacters();
const CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
+ const DevelText::VerticalLineAlignment::Type verLineAlign = mModel->GetVerticalLineAlignment();
+
// Traverses the lines of the text.
for(LineIndex lineIndex = 0u; lineIndex < modelNumberOfLines; ++lineIndex)
{
glyphData.horizontalOffset += horizontalOffset;
// Increases the vertical offset with the line's ascender.
- glyphData.verticalOffset += static_cast<int32_t>(line.ascender);
+ glyphData.verticalOffset += static_cast<int32_t>(line.ascender + GetPreOffsetVerticalLineAlignment(line, verLineAlign));
// Retrieves the glyph's outline width
float outlineWidth = static_cast<float>(mModel->GetOutlineWidth());
}
// Increases the vertical offset with the line's descender & line spacing.
- glyphData.verticalOffset += static_cast<int32_t>(-line.descender + line.lineSpacing);
+ glyphData.verticalOffset += static_cast<int32_t>(-line.descender + GetPostOffsetVerticalLineAlignment(line, verLineAlign));
}
return glyphData.bitmapBuffer;
#include <dali/public-api/math/vector4.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/character-run.h>
+#include <dali-toolkit/internal/text/abstract-style-character-run.h>
#include <dali-toolkit/internal/text/strikethrough-style-properties.h>
namespace Dali
/**
* @brief Run of strikethrough characters with same properties.
*/
-struct StrikethroughCharacterRun
+struct StrikethroughCharacterRun : public AbstractStyleCharacterRun
{
/**
* Default constructor to set the default values of bitfields
*/
StrikethroughCharacterRun()
- : characterRun{},
+ : AbstractStyleCharacterRun(),
properties{}
{
}
- CharacterRun characterRun; ///< The initial character index and the number of characters of the run.
- StrikethroughStyleProperties properties; /// The properties of strikethrough style
+ StrikethroughStyleProperties properties; /// The properties of strikethrough style
};
} // namespace Text
} // namespace Toolkit
+// Allow StrikethroughCharacterRun to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::StrikethroughCharacterRun> : public Dali::BasicTypes<Dali::Toolkit::Text::StrikethroughCharacterRun>
+{
+ enum
+ {
+ IS_TRIVIAL_TYPE = true
+ };
+};
+
} // namespace Dali
#endif // DALI_TOOLKIT_TEXT_STRIKETHROUGH_CHARACTER_RUN_H
#include <dali/public-api/math/vector4.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/character-run.h>
+#include <dali-toolkit/internal/text/abstract-style-character-run.h>
#include <dali-toolkit/internal/text/underline-style-properties.h>
namespace Dali
/**
* @brief Run of underlined characters with same properties.
*/
-struct UnderlinedCharacterRun
+struct UnderlinedCharacterRun : public AbstractStyleCharacterRun
{
/**
* Default constructor to set the default values of bitfields
*/
UnderlinedCharacterRun()
- : characterRun{},
+ : AbstractStyleCharacterRun(),
properties{}
{
}
- CharacterRun characterRun; ///< The initial character index and the number of characters of the run.
- UnderlineStyleProperties properties; /// The properties of underline style
+ UnderlineStyleProperties properties; /// The properties of underline style
};
} // namespace Text
} // namespace Toolkit
+// Allow UnderlinedCharacterRun to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::UnderlinedCharacterRun> : public Dali::BasicTypes<Dali::Toolkit::Text::UnderlinedCharacterRun>
+{
+ enum
+ {
+ IS_TRIVIAL_TYPE = true
+ };
+};
+
} // namespace Dali
#endif // DALI_TOOLKIT_TEXT_UNDERLINED_CHARACTER_RUN_H
const Dali::FittingMode::Type& fittingMode,
const Dali::SamplingMode::Type& samplingMode,
const TextureCacheManager::UseAtlas& useAtlas,
+ const StorageType& storageType,
const TextureCacheManager::TextureId& maskTextureId,
const bool& cropToMask,
const TextureCacheManager::MultiplyOnLoad& preMultiplyOnLoad,
(cropToMask == textureInfo.cropToMask) &&
(size == textureInfo.desiredSize) &&
(isAnimatedImage == textureInfo.isAnimatedImageFormat) &&
+ (storageType == textureInfo.storageType) &&
(frameIndex == textureInfo.frameIndex) &&
((size.GetWidth() == 0 && size.GetHeight() == 0) ||
(fittingMode == textureInfo.fittingMode &&
* @param[in] fittingMode The FittingMode to use
* @param[in] samplingMode The SamplingMode to use
* @param[in] useAtlas True if atlased
+ * @param[in] storageType Whether the pixel data is stored in the cache or uploaded to the GPU
* @param[in] maskTextureId Optional texture ID to use to mask this image
* @param[in] cropToMask True if crop to mask
* @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
const Dali::FittingMode::Type& fittingMode,
const Dali::SamplingMode::Type& samplingMode,
const TextureCacheManager::UseAtlas& useAtlas,
+ const StorageType& storageType,
const TextureCacheManager::TextureId& maskTextureId,
const bool& cropToMask,
const TextureCacheManager::MultiplyOnLoad& preMultiplyOnLoad,
: mAlphaMaskUrl(),
mAlphaMaskId(INVALID_TEXTURE_ID),
mContentScaleFactor(1.0f),
- mCropToMask(true)
+ mCropToMask(true),
+ mPreappliedMasking(true),
+ mMaskImageLoadingFailed(false)
{
}
TextureManager::TextureManager()
: mTextureCacheManager(),
- mAsyncLocalLoaders(GetNumberOfLocalLoaderThreads(), [&]() { return TextureAsyncLoadingHelper(*this); }),
- mAsyncRemoteLoaders(GetNumberOfRemoteLoaderThreads(), [&]() { return TextureAsyncLoadingHelper(*this); }),
+ mAsyncLocalLoaders(GetNumberOfLocalLoaderThreads(), [&]()
+ { return TextureAsyncLoadingHelper(*this); }),
+ mAsyncRemoteLoaders(GetNumberOfRemoteLoaderThreads(), [&]()
+ { return TextureAsyncLoadingHelper(*this); }),
mLifecycleObservers(),
mLoadQueue(),
mRemoveQueue(),
}
else
{
+ Texture maskTexture;
if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
{
Devel::PixelBuffer maskPixelBuffer = LoadImageFromFile(maskInfo->mAlphaMaskUrl.GetUrl(), ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, true);
if(maskPixelBuffer)
{
- pixelBuffer.ApplyMask(maskPixelBuffer, maskInfo->mContentScaleFactor, maskInfo->mCropToMask);
+ if(!maskInfo->mPreappliedMasking)
+ {
+ PixelData maskPixelData = Devel::PixelBuffer::Convert(maskPixelBuffer); // takes ownership of buffer
+ maskTexture = Texture::New(Dali::TextureType::TEXTURE_2D, maskPixelData.GetPixelFormat(), maskPixelData.GetWidth(), maskPixelData.GetHeight());
+ maskTexture.Upload(maskPixelData);
+ }
+ else
+ {
+ pixelBuffer.ApplyMask(maskPixelBuffer, maskInfo->mContentScaleFactor, maskInfo->mCropToMask);
+ }
}
else
{
texture.Upload(pixelData);
textureSet = TextureSet::New();
textureSet.SetTexture(0u, texture);
+ if(maskTexture)
+ {
+ textureSet.SetTexture(1u, maskTexture);
+ }
}
}
}
bool cropToMask = false;
if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
{
- maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl);
+ maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, maskInfo->mPreappliedMasking ? StorageType::KEEP_PIXEL_BUFFER : StorageType::KEEP_TEXTURE);
alphaMaskId = maskInfo->mAlphaMaskId;
- contentScaleFactor = maskInfo->mContentScaleFactor;
- cropToMask = maskInfo->mCropToMask;
+ if(maskInfo->mPreappliedMasking)
+ {
+ contentScaleFactor = maskInfo->mContentScaleFactor;
+ cropToMask = maskInfo->mCropToMask;
+ }
}
- textureId = RequestLoadInternal(url, alphaMaskId, contentScaleFactor, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, UseAtlas::NO_ATLAS, cropToMask, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad, animatedImageLoading, frameIndex, false);
+ textureId = RequestLoadInternal(url, alphaMaskId, contentScaleFactor, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, UseAtlas::NO_ATLAS, cropToMask, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad, animatedImageLoading, frameIndex, false);
TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
if(loadState == TextureManager::LoadState::UPLOADED)
if(!textureSet) // big image, no atlasing or atlasing failed
{
atlasingStatus = false;
- if(!maskInfo || !maskInfo->mAlphaMaskUrl.IsValid())
- {
- textureId = RequestLoad(
- url,
- desiredSize,
- fittingMode,
- samplingMode,
- UseAtlas::NO_ATLAS,
- textureObserver,
- orientationCorrection,
- reloadPolicy,
- preMultiplyOnLoad,
- synchronousLoading);
- }
- else
+
+ TextureId alphaMaskId = INVALID_TEXTURE_ID;
+ float contentScaleFactor = 1.0f;
+ bool cropToMask = false;
+ if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
{
- maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, synchronousLoading);
- textureId = RequestLoad(
- url,
- maskInfo->mAlphaMaskId,
- maskInfo->mContentScaleFactor,
- desiredSize,
- fittingMode,
- samplingMode,
- UseAtlas::NO_ATLAS,
- maskInfo->mCropToMask,
- textureObserver,
- orientationCorrection,
- reloadPolicy,
- preMultiplyOnLoad,
- synchronousLoading);
+ maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, maskInfo->mPreappliedMasking ? StorageType::KEEP_PIXEL_BUFFER : StorageType::KEEP_TEXTURE, synchronousLoading);
+ alphaMaskId = maskInfo->mAlphaMaskId;
+ if(maskInfo && maskInfo->mPreappliedMasking)
+ {
+ contentScaleFactor = maskInfo->mContentScaleFactor;
+ cropToMask = maskInfo->mCropToMask;
+ }
}
+ textureId = RequestLoad(
+ url,
+ alphaMaskId,
+ contentScaleFactor,
+ desiredSize,
+ fittingMode,
+ samplingMode,
+ UseAtlas::NO_ATLAS,
+ cropToMask,
+ textureObserver,
+ orientationCorrection,
+ reloadPolicy,
+ preMultiplyOnLoad,
+ synchronousLoading);
+
TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
if(loadState == TextureManager::LoadState::UPLOADED)
{
TextureManager::TextureId TextureManager::RequestMaskLoad(
const VisualUrl& maskUrl,
+ StorageType storageType,
const bool& synchronousLoading)
{
// Use the normal load procedure to get the alpha mask.
auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
- return RequestLoadInternal(maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, UseAtlas::NO_ATLAS, false, StorageType::KEEP_PIXEL_BUFFER, NULL, true, TextureManager::ReloadPolicy::CACHED, preMultiply, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
+ return RequestLoadInternal(maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, UseAtlas::NO_ATLAS, false, storageType, NULL, true, TextureManager::ReloadPolicy::CACHED, preMultiply, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
}
TextureManager::TextureId TextureManager::RequestLoadInternal(
textureHash = mTextureCacheManager.GenerateHash(url, desiredSize, fittingMode, samplingMode, useAtlas, maskTextureId, cropToMask, frameIndex);
// Look up the texture by hash. Note: The extra parameters are used in case of a hash collision.
- cacheIndex = mTextureCacheManager.FindCachedTexture(textureHash, url, desiredSize, fittingMode, samplingMode, useAtlas, maskTextureId, cropToMask, preMultiplyOnLoad, (animatedImageLoading) ? true : false, frameIndex);
+ cacheIndex = mTextureCacheManager.FindCachedTexture(textureHash, url, desiredSize, fittingMode, samplingMode, useAtlas, storageType, maskTextureId, cropToMask, preMultiplyOnLoad, (animatedImageLoading) ? true : false, frameIndex);
}
TextureManager::TextureId textureId = INVALID_TEXTURE_ID;
}
else // For the image loading.
{
+ Texture maskTexture;
if(maskTextureId != INVALID_TEXTURE_ID)
{
TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(maskTextureId);
if(maskCacheIndex != INVALID_CACHE_INDEX)
{
- Devel::PixelBuffer maskPixelBuffer = mTextureCacheManager[maskCacheIndex].pixelBuffer;
- if(maskPixelBuffer)
+ if(mTextureCacheManager[maskCacheIndex].storageType == StorageType::KEEP_TEXTURE)
{
- pixelBuffer.ApplyMask(maskPixelBuffer, contentScale, cropToMask);
+ TextureSet maskTextures = mTextureCacheManager[maskCacheIndex].textureSet;
+ if(maskTextures && maskTextures.GetTextureCount())
+ {
+ maskTexture = maskTextures.GetTexture(0u);
+ }
}
- else
+ else if(mTextureCacheManager[maskCacheIndex].storageType == StorageType::KEEP_PIXEL_BUFFER)
{
- DALI_LOG_ERROR("Mask image cached invalid pixel buffer!\n");
+ Devel::PixelBuffer maskPixelBuffer = mTextureCacheManager[maskCacheIndex].pixelBuffer;
+ if(maskPixelBuffer)
+ {
+ pixelBuffer.ApplyMask(maskPixelBuffer, contentScale, cropToMask);
+ }
+ else
+ {
+ DALI_LOG_ERROR("Mask image cached invalid pixel buffer!\n");
+ }
}
}
else
// Upload texture
UploadTexture(pixelBuffer, textureInfo);
+ if(maskTexture && textureInfo.textureSet)
+ {
+ textureInfo.textureSet.SetTexture(1u, maskTexture);
+ }
}
}
}
{
textureInfo.loadState = LoadState::WAITING_FOR_MASK;
}
- else if(maskLoadState == LoadState::LOAD_FINISHED)
+ else if(maskLoadState == LoadState::LOAD_FINISHED || maskLoadState == LoadState::UPLOADED)
{
// Send New Task to Thread
- ApplyMask(textureInfo, textureInfo.maskTextureId);
+ TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(textureInfo.maskTextureId);
+ if(maskCacheIndex != INVALID_CACHE_INDEX)
+ {
+ TextureInfo& maskTextureInfo(mTextureCacheManager[maskCacheIndex]);
+ if(maskTextureInfo.storageType == StorageType::KEEP_PIXEL_BUFFER)
+ {
+ // Send New Task to Thread
+ ApplyMask(textureInfo, textureInfo.maskTextureId);
+ }
+ else if(maskTextureInfo.storageType == StorageType::KEEP_TEXTURE)
+ {
+ // Upload image texture. textureInfo.loadState will be UPLOADED.
+ UploadTexture(textureInfo.pixelBuffer, textureInfo);
+ if(maskTextureInfo.textureSet.GetTextureCount() > 0u)
+ {
+ Texture maskTexture = maskTextureInfo.textureSet.GetTexture(0u);
+ textureInfo.textureSet.SetTexture(1u, maskTexture);
+ }
+ // notify mask texture set.
+ NotifyObservers(textureInfo, true);
+ }
+ }
}
else // maskLoadState == LoadState::LOAD_FAILED
{
{
NotifyObservers(textureInfo, true);
}
- else
+ else // for the StorageType::KEEP_PIXEL_BUFFER and StorageType::KEEP_TEXTURE
{
// Check if there was another texture waiting for this load to complete
// (e.g. if this was an image mask, and its load is on a different thread)
else
{
textureInfo.loadState = LoadState::LOAD_FAILED;
- if(textureInfo.storageType != StorageType::KEEP_PIXEL_BUFFER)
- {
- NotifyObservers(textureInfo, false);
- }
- else // if(textureInfo.storageType == StorageType::KEEP_PIXEL_BUFFER) // image mask case
+ if(textureInfo.storageType == StorageType::KEEP_PIXEL_BUFFER || textureInfo.storageType == StorageType::KEEP_TEXTURE)
{
// Check if there was another texture waiting for this load to complete
// (e.g. if this was an image mask, and its load is on a different thread)
CheckForWaitingTexture(textureInfo);
}
+ else
+ {
+ NotifyObservers(textureInfo, false);
+ }
}
}
void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTextureInfo)
{
+ if(maskTextureInfo.loadState == LoadState::LOAD_FINISHED &&
+ maskTextureInfo.storageType == StorageType::KEEP_TEXTURE)
+ {
+ // Upload mask texture. textureInfo.loadState will be UPLOADED.
+ UploadTexture(maskTextureInfo.pixelBuffer, maskTextureInfo);
+ }
+
// Search the cache, checking if any texture has this texture id as a
// maskTextureId:
const std::size_t size = mTextureCacheManager.size();
- const bool maskLoadSuccess = maskTextureInfo.loadState == LoadState::LOAD_FINISHED ? true : false;
-
// TODO : Refactorize here to not iterate whole cached image.
for(TextureCacheIndex cacheIndex = TextureCacheIndex(TextureManagerType::TEXTURE_CACHE_INDEX_TYPE_LOCAL, 0u); cacheIndex.GetIndex() < size; ++cacheIndex.detailValue.index)
{
{
TextureInfo& textureInfo(mTextureCacheManager[cacheIndex]);
- if(maskLoadSuccess)
+ if(maskTextureInfo.loadState == LoadState::LOAD_FINISHED)
+ {
+ if(maskTextureInfo.storageType == StorageType::KEEP_PIXEL_BUFFER)
+ {
+ // Send New Task to Thread
+ ApplyMask(textureInfo, maskTextureInfo.textureId);
+ }
+ }
+ else if(maskTextureInfo.loadState == LoadState::UPLOADED)
{
- // Send New Task to Thread
- ApplyMask(textureInfo, maskTextureInfo.textureId);
+ if(maskTextureInfo.storageType == StorageType::KEEP_TEXTURE)
+ {
+ // Upload image texture. textureInfo.loadState will be UPLOADED.
+ UploadTexture(textureInfo.pixelBuffer, textureInfo);
+ if(maskTextureInfo.textureSet.GetTextureCount() > 0u)
+ {
+ Texture maskTexture = maskTextureInfo.textureSet.GetTexture(0u);
+ textureInfo.textureSet.SetTexture(1u, maskTexture);
+ }
+ // notify mask texture set.
+ NotifyObservers(textureInfo, true);
+ }
}
else
{
TextureManager::TextureId mAlphaMaskId;
float mContentScaleFactor;
bool mCropToMask;
+ bool mPreappliedMasking;
+ bool mMaskImageLoadingFailed;
};
using MaskingDataPointer = std::unique_ptr<MaskingData>;
* @brief Requests a masking image to be loaded. This mask is not uploaded to GL,
* instead, it is stored in CPU memory, and can be used for CPU blending.
* @param[in] maskUrl The URL of the mask image to load
+ * @param[in] storageType, Whether the pixel data is stored in the cache or uploaded to the GPU
* @param[in] synchronousLoading True if the frame should be loaded synchronously. If you skip this parameter,
* default is false.
* @return A TextureId to use as a handle to reference this mask Texture
*/
TextureId RequestMaskLoad(
const VisualUrl& maskUrl,
+ StorageType storageType,
const bool& synchronousLoading = false);
private:
KEEP_PIXEL_BUFFER, ///< Keep loaded pixel buffer inside of texture manager without making texture. This could be used for inside pixel process like mask image.
RETURN_PIXEL_BUFFER, ///< Return loaded pixel buffer without making texture.
/// Because a pixel buffer cannot be used multiple texture, this pixel buffer only cached during loading, and is removed after loading is finished.
+ KEEP_TEXTURE, ///< Keep loaded texture inside of texture manager. This could be used for pixel processing like GPU masking.
UPLOAD_TO_TEXTURE ///< Loaded image will be uploaded to texture and the texture will be returned.
};
{
namespace
{
-const int CUSTOM_PROPERTY_COUNT(3); // ltr, wrap, pixel area,
+const int CUSTOM_PROPERTY_COUNT(10); // ltr, wrap, pixel area, crop to mask, mask texture ratio + border/corner
// stop behavior
DALI_ENUM_TO_STRING_TABLE_BEGIN(STOP_BEHAVIOR)
static constexpr auto LOOP_FOREVER = -1;
static constexpr auto FIRST_LOOP = 0u;
+constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u;
+
#if defined(DEBUG_ENABLED)
Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ANIMATED_IMAGE");
#endif
map.Insert(Toolkit::ImageVisual::Property::ALPHA_MASK_URL, mMaskingData->mAlphaMaskUrl.GetUrl());
map.Insert(Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE, mMaskingData->mContentScaleFactor);
map.Insert(Toolkit::ImageVisual::Property::CROP_TO_MASK, mMaskingData->mCropToMask);
+ map.Insert(Toolkit::DevelImageVisual::Property::MASKING_TYPE, mMaskingData->mPreappliedMasking ? DevelImageVisual::MaskingType::MASKING_ON_LOADING : DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
}
map.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, mLoadPolicy);
{
DoSetProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, keyValue.second);
}
+ else if(keyValue.first == MASKING_TYPE_NAME)
+ {
+ DoSetProperty(Toolkit::DevelImageVisual::Property::MASKING_TYPE, keyValue.second);
+ }
else if(keyValue.first == LOAD_POLICY_NAME)
{
DoSetProperty(Toolkit::ImageVisual::Property::LOAD_POLICY, keyValue.second);
break;
}
+ case Toolkit::DevelImageVisual::Property::MASKING_TYPE:
+ {
+ int maskingType = 0;
+ if(value.Get(maskingType))
+ {
+ AllocateMaskData();
+ mMaskingData->mPreappliedMasking = Toolkit::DevelImageVisual::MaskingType::Type(maskingType) == Toolkit::DevelImageVisual::MaskingType::MASKING_ON_LOADING ? true : false;
+ }
+ break;
+ }
+
case Toolkit::ImageVisual::Property::RELEASE_POLICY:
{
int releasePolicy = 0;
Shader AnimatedImageVisual::GenerateShader() const
{
- bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE;
+ bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE;
+ bool requiredAlphaMaskingOnRendering = (mMaskingData && !mMaskingData->mMaskImageLoadingFailed) ? !mMaskingData->mPreappliedMasking : false;
Shader shader;
shader = mImageVisualShaderFactory.GetShader(
mFactoryCache,
ImageVisualShaderFeature::FeatureBuilder()
.ApplyDefaultTextureWrapMode(defaultWrapMode)
.EnableRoundedCorner(IsRoundedCornerRequired())
- .EnableBorderline(IsBorderlineRequired()));
+ .EnableBorderline(IsBorderlineRequired())
+ .EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering));
return shader;
}
mImpl->mRenderer.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, mPixelArea);
}
+ if(mMaskingData)
+ {
+ mImpl->mRenderer.RegisterProperty(CROP_TO_MASK_NAME, static_cast<float>(mMaskingData->mCropToMask));
+ }
+
// Enable PreMultipliedAlpha if it need premultiplied
auto preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader
? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
if(mImpl->mRenderer)
{
mImpl->mRenderer.SetTextures(textureSet);
+ CheckMaskTexture();
Actor actor = mPlacementActor.GetHandle();
if(actor)
mImageSize.SetWidth(texture.GetWidth());
mImageSize.SetHeight(texture.GetHeight());
}
+
+ if(textureSet.GetTextureCount() > 1u && mMaskingData && mMaskingData->mCropToMask)
+ {
+ Texture maskTexture = textureSet.GetTexture(1);
+ if(maskTexture)
+ {
+ mImageSize.SetWidth(std::min(static_cast<uint32_t>(mImageSize.GetWidth() * mMaskingData->mContentScaleFactor), maskTexture.GetWidth()));
+ mImageSize.SetHeight(std::min(static_cast<uint32_t>(mImageSize.GetHeight() * mMaskingData->mContentScaleFactor), maskTexture.GetHeight()));
+
+ float textureWidth = std::max(static_cast<float>(texture.GetWidth() * mMaskingData->mContentScaleFactor), Dali::Math::MACHINE_EPSILON_1);
+ float textureHeight = std::max(static_cast<float>(texture.GetHeight() * mMaskingData->mContentScaleFactor), Dali::Math::MACHINE_EPSILON_1);
+ Vector2 textureRatio(std::min(static_cast<float>(maskTexture.GetWidth()), textureWidth) / textureWidth,
+ std::min(static_cast<float>(maskTexture.GetHeight()), textureHeight) / textureHeight);
+ mImpl->mRenderer.RegisterProperty(MASK_TEXTURE_RATIO_NAME, textureRatio);
+ }
+ }
}
}
mFrameDelayTimer.SetInterval(interval);
}
mImpl->mRenderer.SetTextures(textureSet);
+ CheckMaskTexture();
}
}
}
if(mImpl->mRenderer)
{
mImpl->mRenderer.SetTextures(textureSet);
+ CheckMaskTexture();
}
mFrameDelayTimer.SetInterval(mImageCache->GetFrameInterval(frameIndex));
}
}
}
+void AnimatedImageVisual::CheckMaskTexture()
+{
+ if(mMaskingData && !mMaskingData->mPreappliedMasking)
+ {
+ bool maskLoadFailed = true;
+ TextureSet textures = mImpl->mRenderer.GetTextures();
+ if(textures && textures.GetTextureCount() >= TEXTURE_COUNT_FOR_GPU_ALPHA_MASK)
+ {
+ maskLoadFailed = false;
+ }
+ if(mMaskingData->mMaskImageLoadingFailed != maskLoadFailed)
+ {
+ mMaskingData->mMaskImageLoadingFailed = maskLoadFailed;
+ UpdateShader();
+ }
+ }
+}
+
} // namespace Internal
} // namespace Toolkit
*/
void AllocateMaskData();
+ /**
+ * @brief Check whether the mask texture is loaded or not.
+ * If MaskingType is MASKING_ON_LOADING and mask texture is failed to load, update shader.
+ */
+ void CheckMaskTexture();
+
// Undefined
AnimatedImageVisual(const AnimatedImageVisual& animatedImageVisual);
const int NATIVE_SHADER_TYPE_OFFSET = VisualFactoryCache::ShaderType::NATIVE_IMAGE_SHADER - VisualFactoryCache::ShaderType::IMAGE_SHADER;
+// enum of required list when we select shader
+enum class ImageVisualRequireFlag : uint32_t
+{
+ DEFAULT = 0,
+ ROUNDED_CORNER = 1 << 0,
+ BORDERLINE = 1 << 1,
+ ALPHA_MASKING = 1 << 2,
+};
+
+static constexpr auto SHADER_TYPE_COUNT = 8u;
+VisualFactoryCache::ShaderType SHADER_TYPE_TABLE[SHADER_TYPE_COUNT] =
+{
+ VisualFactoryCache::IMAGE_SHADER,
+ VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER,
+ VisualFactoryCache::IMAGE_SHADER_BORDERLINE,
+ VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE,
+ VisualFactoryCache::IMAGE_SHADER_MASKING,
+ VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER_MASKING,
+ VisualFactoryCache::IMAGE_SHADER_BORDERLINE_MASKING,
+ VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE_MASKING
+};
+
} // unnamed namespace
namespace ImageVisualShaderFeature
mTexture = texture;
return *this;
}
+FeatureBuilder& FeatureBuilder::EnableAlphaMaskingOnRendering(bool enableAlphaMaskingOnRendering)
+{
+ mAlphaMaskingOnRendering = (enableAlphaMaskingOnRendering ? AlphaMaskingOnRendering::ENABLED : AlphaMaskingOnRendering::DISABLED);
+ return *this;
+}
} // namespace ImageVisualShaderFeature
ImageVisualShaderFactory::ImageVisualShaderFactory()
Shader shader;
VisualFactoryCache::ShaderType shaderType = VisualFactoryCache::IMAGE_SHADER;
- const auto& atlasing = featureBuilder.mTextureAtlas;
- const auto& defaultTextureWrapping = featureBuilder.mDefaultTextureWrapMode;
- const auto& roundedCorner = featureBuilder.mRoundedCorner;
- const auto& borderline = featureBuilder.mBorderline;
- const auto& changeFragmentShader = (featureBuilder.mTexture && DevelTexture::IsNative(featureBuilder.mTexture))
- ? ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE
- : ImageVisualShaderFeature::ChangeFragmentShader::DONT_CHANGE;
+ const auto& atlasing = featureBuilder.mTextureAtlas;
+ const auto& defaultTextureWrapping = featureBuilder.mDefaultTextureWrapMode;
+ const auto& roundedCorner = featureBuilder.mRoundedCorner;
+ const auto& borderline = featureBuilder.mBorderline;
+ const auto& alphaMaskingOnRendering = featureBuilder.mAlphaMaskingOnRendering;
+ const auto& changeFragmentShader = (featureBuilder.mTexture && DevelTexture::IsNative(featureBuilder.mTexture))
+ ? ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE
+ : ImageVisualShaderFeature::ChangeFragmentShader::DONT_CHANGE;
if(atlasing == ImageVisualShaderFeature::TextureAtlas::ENABLED)
{
}
else
{
+ uint32_t shaderTypeFlag = static_cast<uint32_t>(ImageVisualRequireFlag::DEFAULT);
if(roundedCorner == ImageVisualShaderFeature::RoundedCorner::ENABLED)
{
- if(borderline == ImageVisualShaderFeature::Borderline::ENABLED)
- {
- shaderType = VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE;
- }
- else
- {
- shaderType = VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER;
- }
+ shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::ROUNDED_CORNER);
}
- else
+ if(borderline == ImageVisualShaderFeature::Borderline::ENABLED)
{
- if(borderline == ImageVisualShaderFeature::Borderline::ENABLED)
- {
- shaderType = VisualFactoryCache::IMAGE_SHADER_BORDERLINE;
- }
+ shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::BORDERLINE);
+ }
+ if(alphaMaskingOnRendering == ImageVisualShaderFeature::AlphaMaskingOnRendering::ENABLED)
+ {
+ shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::ALPHA_MASKING);
}
+ shaderType = SHADER_TYPE_TABLE[shaderTypeFlag];
}
if(changeFragmentShader == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE &&
vertexShaderPrefixList += "#define IS_REQUIRED_BORDERLINE 1\n";
fragmentShaderPrefixList += "#define IS_REQUIRED_BORDERLINE 1\n";
}
+ if(alphaMaskingOnRendering == ImageVisualShaderFeature::AlphaMaskingOnRendering::ENABLED)
+ {
+ vertexShaderPrefixList += "#define IS_REQUIRED_ALPHA_MASKING 1\n";
+ fragmentShaderPrefixList += "#define IS_REQUIRED_ALPHA_MASKING 1\n";
+ }
}
std::string vertexShader = std::string(Dali::Shader::GetVertexShaderPrefix() + vertexShaderPrefixList + SHADER_IMAGE_VISUAL_SHADER_VERT.data());
};
} // namespace ChangeFragmentShader
+namespace AlphaMaskingOnRendering
+{
+/**
+ * @brief Whether use runtime alpha masking in shader, or not
+ */
+enum Type
+{
+ DISABLED = 0, ///< Image visual doesn't use runtime alpha masking
+ ENABLED ///< Image visual uses runtime alpha masking
+};
+} // namespace AlphaMaskingOnRendering
+
/**
* @brief Collection of current image visual feature. Only use for ImageVisualShaderFactory::GetShader()
*/
mDefaultTextureWrapMode(DefaultTextureWrapMode::APPLY),
mRoundedCorner(RoundedCorner::DISABLED),
mBorderline(Borderline::DISABLED),
+ mAlphaMaskingOnRendering(AlphaMaskingOnRendering::DISABLED),
mTexture()
{
}
FeatureBuilder& EnableRoundedCorner(bool enableRoundedCorner);
FeatureBuilder& EnableBorderline(bool enableBorderline);
FeatureBuilder& SetTextureForFragmentShaderCheck(const Dali::Texture& texture);
-
- TextureAtlas::Type mTextureAtlas : 2; ///< Whether use texture with atlas, or not. default as TextureAtlas::DISABLED
- DefaultTextureWrapMode::Type mDefaultTextureWrapMode : 2; ///< Whether apply to texture wraping in default, or not. default as DefaultTextureWrapMode::APPLY
- RoundedCorner::Type mRoundedCorner : 2; ///< Whether use rounded corner, or not. default as RoundedCorner::DISABLED
- Borderline::Type mBorderline : 2; ///< Whether use borderline, or not. default as Borderline::DISABLED
- Dali::Texture mTexture; ///< Texture to check whether we need to change fragment shader or not
+ FeatureBuilder& EnableAlphaMaskingOnRendering(bool enableAlphaMaskingOnRendering);
+
+ TextureAtlas::Type mTextureAtlas : 2; ///< Whether use texture with atlas, or not. default as TextureAtlas::DISABLED
+ DefaultTextureWrapMode::Type mDefaultTextureWrapMode : 2; ///< Whether apply to texture wraping in default, or not. default as DefaultTextureWrapMode::APPLY
+ RoundedCorner::Type mRoundedCorner : 2; ///< Whether use rounded corner, or not. default as RoundedCorner::DISABLED
+ Borderline::Type mBorderline : 2; ///< Whether use borderline, or not. default as Borderline::DISABLED
+ AlphaMaskingOnRendering::Type mAlphaMaskingOnRendering : 2; ///< Whether use runtime alpha masking, or not. default as AlphaMaskingOnRendering::DISABLED
+ Dali::Texture mTexture; ///< Texture to check whether we need to change fragment shader or not
};
-} // namespace ImageVisualShaderFactoryFeature
+} // namespace ImageVisualShaderFeature
/**
* ImageVisualShaderFactory is an object that provides and shares shaders between image visuals
{
namespace
{
-const int CUSTOM_PROPERTY_COUNT(9); // wrap, pixel area, atlas, pixalign, + border/corner
+const int CUSTOM_PROPERTY_COUNT(12); // ltr, wrap, pixel area, atlas, pixalign, crop to mask, mask texture ratio + border/corner
// fitting modes
DALI_ENUM_TO_STRING_TABLE_BEGIN(FITTING_MODE)
const float PIXEL_ALIGN_ON = 1.0f;
const float PIXEL_ALIGN_OFF = 0.0f;
+constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u;
+
Geometry CreateGeometry(VisualFactoryCache& factoryCache, ImageDimensions gridSize)
{
Geometry geometry;
{
DoSetProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, keyValue.second);
}
+ else if(keyValue.first == MASKING_TYPE_NAME)
+ {
+ DoSetProperty(Toolkit::DevelImageVisual::Property::MASKING_TYPE, keyValue.second);
+ }
else if(keyValue.first == LOAD_POLICY_NAME)
{
DoSetProperty(Toolkit::ImageVisual::Property::LOAD_POLICY, keyValue.second);
break;
}
+ case Toolkit::DevelImageVisual::Property::MASKING_TYPE:
+ {
+ int maskingType = 0;
+ if(value.Get(maskingType))
+ {
+ AllocateMaskData();
+ mMaskingData->mPreappliedMasking = Toolkit::DevelImageVisual::MaskingType::Type(maskingType) == Toolkit::DevelImageVisual::MaskingType::MASKING_ON_LOADING ? true : false;
+ }
+ break;
+ }
+
case Toolkit::ImageVisual::Property::RELEASE_POLICY:
{
int releasePolicy = 0;
auto textureSet = mImpl->mRenderer.GetTextures();
if(textureSet && textureSet.GetTextureCount())
{
- auto texture = textureSet.GetTexture(0);
- if(texture)
+ if(mTextureSize != Vector2::ZERO)
{
- naturalSize.x = texture.GetWidth();
- naturalSize.y = texture.GetHeight();
+ naturalSize = mTextureSize;
return;
}
}
mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
EnablePreMultipliedAlpha(IsPreMultipliedAlphaEnabled());
+
+ if(mMaskingData)
+ {
+ mImpl->mRenderer.RegisterProperty(CROP_TO_MASK_NAME, static_cast<float>(mMaskingData->mCropToMask));
+ }
}
void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection, TextureManager::ReloadPolicy forceReload)
if(mTextures)
{
mImpl->mRenderer.SetTextures(mTextures);
+ ComputeTextureSize();
+ CheckMaskTexture();
if(DevelTexture::IsNative(mTextures.GetTexture(0)))
{
UpdateShader();
TextureSet textureSet = TextureSet::New();
mImpl->mRenderer.SetTextures(textureSet);
+ ComputeTextureSize();
mLoadState = TextureManager::LoadState::NOT_STARTED;
}
map.Insert(Toolkit::ImageVisual::Property::ALPHA_MASK_URL, mMaskingData->mAlphaMaskUrl.GetUrl());
map.Insert(Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE, mMaskingData->mContentScaleFactor);
map.Insert(Toolkit::ImageVisual::Property::CROP_TO_MASK, mMaskingData->mCropToMask);
+ map.Insert(Toolkit::DevelImageVisual::Property::MASKING_TYPE, mMaskingData->mPreappliedMasking ? DevelImageVisual::MaskingType::MASKING_ON_LOADING : DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
}
map.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, mLoadPolicy);
sampler.SetWrapMode(mWrapModeU, mWrapModeV);
textureInformation.textureSet.SetSampler(0u, sampler);
mImpl->mRenderer.SetTextures(textureInformation.textureSet);
+ ComputeTextureSize();
+ CheckMaskTexture();
}
if(actor)
}
}
+void ImageVisual::ComputeTextureSize()
+{
+ if(mImpl->mRenderer)
+ {
+ auto textureSet = mImpl->mRenderer.GetTextures();
+ if(textureSet && textureSet.GetTextureCount())
+ {
+ auto texture = textureSet.GetTexture(0);
+ if(texture)
+ {
+ mTextureSize.x = texture.GetWidth();
+ mTextureSize.y = texture.GetHeight();
+ if(textureSet.GetTextureCount() > 1u && mMaskingData && !mMaskingData->mPreappliedMasking && mMaskingData->mCropToMask)
+ {
+ Texture maskTexture = textureSet.GetTexture(1);
+ if(maskTexture)
+ {
+ mTextureSize.x = std::min(static_cast<uint32_t>(mTextureSize.x * mMaskingData->mContentScaleFactor), maskTexture.GetWidth());
+ mTextureSize.y = std::min(static_cast<uint32_t>(mTextureSize.y * mMaskingData->mContentScaleFactor), maskTexture.GetHeight());
+ }
+ }
+ }
+ }
+ }
+}
+
+Vector2 ImageVisual::ComputeMaskTextureRatio()
+{
+ Vector2 maskTextureRatio;
+ if(mImpl->mRenderer)
+ {
+ auto textureSet = mImpl->mRenderer.GetTextures();
+ if(textureSet && textureSet.GetTextureCount())
+ {
+ auto texture = textureSet.GetTexture(0);
+ if(texture)
+ {
+ if(textureSet.GetTextureCount() > 1u && mMaskingData && !mMaskingData->mPreappliedMasking && mMaskingData->mCropToMask)
+ {
+ Texture maskTexture = textureSet.GetTexture(1);
+ if(maskTexture)
+ {
+ float textureWidth = std::max(static_cast<float>(texture.GetWidth() * mMaskingData->mContentScaleFactor), Dali::Math::MACHINE_EPSILON_1);
+ float textureHeight = std::max(static_cast<float>(texture.GetHeight() * mMaskingData->mContentScaleFactor), Dali::Math::MACHINE_EPSILON_1);
+ maskTextureRatio = Vector2(std::min(static_cast<float>(maskTexture.GetWidth()), textureWidth) / textureWidth,
+ std::min(static_cast<float>(maskTexture.GetHeight()), textureHeight) / textureHeight);
+ }
+ }
+ }
+ }
+ }
+ return maskTextureRatio;
+}
+
Shader ImageVisual::GenerateShader() const
{
Shader shader;
if(useStandardShader)
{
+ bool requiredAlphaMaskingOnRendering = (mMaskingData && !mMaskingData->mMaskImageLoadingFailed) ? !mMaskingData->mPreappliedMasking : false;
// Create and cache the standard shader
shader = mImageVisualShaderFactory.GetShader(
mFactoryCache,
.ApplyDefaultTextureWrapMode(mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE)
.EnableRoundedCorner(IsRoundedCornerRequired())
.EnableBorderline(IsBorderlineRequired())
- .SetTextureForFragmentShaderCheck(useNativeImage ? mTextures.GetTexture(0) : Dali::Texture()));
+ .SetTextureForFragmentShaderCheck(useNativeImage ? mTextures.GetTexture(0) : Dali::Texture())
+ .EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering));
}
else
{
return shader;
}
+void ImageVisual::CheckMaskTexture()
+{
+ if(mMaskingData && !mMaskingData->mPreappliedMasking)
+ {
+ bool maskLoadFailed = true;
+ TextureSet textures = mImpl->mRenderer.GetTextures();
+ if(textures && textures.GetTextureCount() >= TEXTURE_COUNT_FOR_GPU_ALPHA_MASK)
+ {
+ if(mMaskingData->mCropToMask)
+ {
+ mImpl->mRenderer.RegisterProperty(MASK_TEXTURE_RATIO_NAME, ComputeMaskTextureRatio());
+ }
+ maskLoadFailed = false;
+ }
+
+ if(mMaskingData->mMaskImageLoadingFailed != maskLoadFailed)
+ {
+ mMaskingData->mMaskImageLoadingFailed = maskLoadFailed;
+ UpdateShader();
+ }
+ }
+}
+
} // namespace Internal
} // namespace Toolkit
void RemoveTexture();
/**
+ * @brief Compute texture size
+ */
+ void ComputeTextureSize();
+
+ /**
+ * @brief Compute mask texture ratio
+ * @return The Mask Texture Ratio
+ */
+ Vector2 ComputeMaskTextureRatio();
+
+ /**
* Helper method to set individual values by index key.
* @param[in] index The index key of the value
* @param[in] value The value
*/
void DoSetProperty(Property::Index index, const Property::Value& value);
+ /**
+ * @brief Check whether the mask texture is loaded or not.
+ * If MaskingType is MASKING_ON_LOADING and mask texture is failed to load, update shader.
+ */
+ void CheckMaskTexture();
+
private:
Vector4 mPixelArea;
WeakHandle<Actor> mPlacementActor;
Dali::ImageDimensions mDesiredSize;
TextureManager::TextureId mTextureId;
TextureSet mTextures;
+ Vector2 mTextureSize;
ImageVisualShaderFactory& mImageVisualShaderFactory;
IMAGE_SHADER_ROUNDED_CORNER,
IMAGE_SHADER_BORDERLINE,
IMAGE_SHADER_ROUNDED_BORDERLINE,
+ IMAGE_SHADER_MASKING,
+ IMAGE_SHADER_ROUNDED_CORNER_MASKING,
+ IMAGE_SHADER_BORDERLINE_MASKING,
+ IMAGE_SHADER_ROUNDED_BORDERLINE_MASKING,
IMAGE_SHADER_ATLAS_DEFAULT_WRAP,
IMAGE_SHADER_ATLAS_CUSTOM_WRAP,
NATIVE_IMAGE_SHADER,
NATIVE_IMAGE_SHADER_ROUNDED_CORNER,
NATIVE_IMAGE_SHADER_BORDERLINE,
NATIVE_IMAGE_SHADER_ROUNDED_BORDERLINE,
+ NATIVE_IMAGE_SHADER_MASKING,
+ NATIVE_IMAGE_SHADER_ROUNDED_CORNER_MASKING,
+ NATIVE_IMAGE_SHADER_BORDERLINE_MASKING,
+ NATIVE_IMAGE_SHADER_ROUNDED_BORDERLINE_MASKING,
NINE_PATCH_SHADER,
NINE_PATCH_MASK_SHADER,
TEXT_SHADER_MULTI_COLOR_TEXT,
const char* const IMAGE_DESIRED_HEIGHT("desiredHeight");
const char* const ALPHA_MASK_URL("alphaMaskUrl");
const char* const REDRAW_IN_SCALING_DOWN_NAME("redrawInScalingDown");
+const char* const MASKING_TYPE_NAME("maskingType");
+const char* const MASK_TEXTURE_RATIO_NAME("maskTextureRatio");
// Text visual
const char* const TEXT_PROPERTY("text");
extern const char* const IMAGE_DESIRED_HEIGHT;
extern const char* const ALPHA_MASK_URL;
extern const char* const REDRAW_IN_SCALING_DOWN_NAME;
+extern const char* const MASKING_TYPE_NAME;
+extern const char* const MASK_TEXTURE_RATIO_NAME;
// Text visual
extern const char* const TEXT_PROPERTY;
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 24;
+const unsigned int TOOLKIT_MICRO_VERSION = 25;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
* @details Name "cropToMask", type Property::BOOLEAN, True if the image should
* be cropped to match the mask size, or false if the image should remain the same size.
* @SINCE_1_2.60
- * @note Optional.
+ * @note Optional, Default true
* @note If this is false, then the mask is scaled to fit the image before being applied.
*/
CROP_TO_MASK,
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.1.24
+Version: 2.1.25
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT