/**
* @brief Test the function for averaging vertically-adjacent pairs of single-byte-per-pixel pixels on a scanline.
*/
+int UtcDaliImageOperationsAverageScanlines1ExceptTest(void)
+{
+ // Edge cases for averagescanlines1:
+ unsigned char shortEven1[] = {0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x02, 0x03, 0x00, 0x01};
+ unsigned char shortEven2[] = {0x00, 0xff, 0x00, 0xff, 0x01, 0x01, 0xff, 0xfe, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x03, 0x02};
+ unsigned char expectBuffer[] = {0x00, 0x7f, 0x7f, 0xff, 0x80, 0x7f, 0x80, 0x7f, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+ unsigned char outputBuffer[sizeof(shortEven1)];
+
+ AverageScanlines1(shortEven1, shortEven2, outputBuffer, sizeof(shortEven1));
+ for(unsigned i = 0; i < sizeof(shortEven1); ++i)
+ {
+ DALI_TEST_EQUALS(unsigned(outputBuffer[i]), unsigned(expectBuffer[i]), TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
+/**
+ * @brief Test the function for averaging vertically-adjacent pairs of single-byte-per-pixel pixels on a scanline.
+ */
int UtcDaliImageOperationsAverageScanlines1(void)
{
// Red and cyan, averaging to grey:
}
// Longer test reusing RGBA setup/test logic:
- const size_t scanlineLength = 4096u;
- Dali::Vector<uint32_t> scanline1;
- Dali::Vector<uint32_t> scanline2;
- Dali::Vector<uint32_t> reference;
- Dali::Vector<uint32_t> output;
- SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+ {
+ const size_t scanlineLength = 4096u;
+ Dali::Vector<uint32_t> scanline1;
+ Dali::Vector<uint32_t> scanline2;
+ Dali::Vector<uint32_t> reference;
+ Dali::Vector<uint32_t> output;
+ SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+
+ AverageScanlines1((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4);
+
+ // Check the output matches the independently generated reference:
+ size_t numMatches = 0;
+ MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
+ DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ }
- AverageScanlines1((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4);
+ // Longer test reusing RGBA setup/test logic with none-8-divisable length
+ {
+ const size_t scanlineLength = 1003u;
+ Dali::Vector<uint32_t> scanline1;
+ Dali::Vector<uint32_t> scanline2;
+ Dali::Vector<uint32_t> reference;
+ Dali::Vector<uint32_t> output;
+ SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+
+ AverageScanlines1((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4);
+
+ // Check the output matches the independently generated reference:
+ size_t numMatches = 0;
+ MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
+ DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ }
- // Check the output matches the independently generated reference:
- size_t numMatches = 0;
- MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
- DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ // Very short test reusing RGBA setup/test logic with less-than-8 length
+ {
+ const size_t scanlineLength = 1003u;
+ Dali::Vector<uint32_t> scanline1;
+ Dali::Vector<uint32_t> scanline2;
+ Dali::Vector<uint32_t> reference;
+ Dali::Vector<uint32_t> output;
+ SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+
+ AverageScanlines1((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4);
+
+ // Check the output matches the independently generated reference:
+ size_t numMatches = 0;
+ MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
+ DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ }
END_TEST;
}
}
// Longer test reusing RGBA setup/test logic:
- const size_t scanlineLength = 4096u;
- Dali::Vector<uint32_t> scanline1;
- Dali::Vector<uint32_t> scanline2;
- Dali::Vector<uint32_t> reference;
- Dali::Vector<uint32_t> output;
- SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+ {
+ const size_t scanlineLength = 4096u;
+ Dali::Vector<uint32_t> scanline1;
+ Dali::Vector<uint32_t> scanline2;
+ Dali::Vector<uint32_t> reference;
+ Dali::Vector<uint32_t> output;
+ SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+
+ AverageScanlines2((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 2);
+
+ // Check the output matches the independently generated reference:
+ size_t numMatches = 0;
+ MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
+ DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ }
- AverageScanlines2((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 2);
+ // Longer test reusing RGBA setup/test logic with none-8-divisable length
+ {
+ const size_t scanlineLength = 501u;
+ Dali::Vector<uint32_t> scanline1;
+ Dali::Vector<uint32_t> scanline2;
+ Dali::Vector<uint32_t> reference;
+ Dali::Vector<uint32_t> output;
+ SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+
+ AverageScanlines2((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 2);
+
+ // Check the output matches the independently generated reference:
+ size_t numMatches = 0;
+ MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
+ DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ }
- // Check the output matches the independently generated reference:
- size_t numMatches = 0;
- MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
- DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ // Very short test reusing RGBA setup/test logic with less-than-8 length
+ {
+ const size_t scanlineLength = 3u;
+ Dali::Vector<uint32_t> scanline1;
+ Dali::Vector<uint32_t> scanline2;
+ Dali::Vector<uint32_t> reference;
+ Dali::Vector<uint32_t> output;
+ SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+
+ AverageScanlines2((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 2);
+
+ // Check the output matches the independently generated reference:
+ size_t numMatches = 0;
+ MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
+ DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ }
END_TEST;
}
}
// Longer test reusing RGBA setup/test logic:
- const size_t scanlineLength = 3 * 4 * 90u;
- Dali::Vector<uint32_t> scanline1;
- Dali::Vector<uint32_t> scanline2;
- Dali::Vector<uint32_t> reference;
- Dali::Vector<uint32_t> output;
- SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+ {
+ const size_t scanlineLength = 3 * 4 * 90u;
+ Dali::Vector<uint32_t> scanline1;
+ Dali::Vector<uint32_t> scanline2;
+ Dali::Vector<uint32_t> reference;
+ Dali::Vector<uint32_t> output;
+ SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+
+ AverageScanlines3((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4 / 3);
+
+ // Check the output matches the independently generated reference:
+ size_t numMatches = 0;
+ MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
+ DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ }
- AverageScanlines3((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4 / 3);
+ // Longer test reusing RGBA setup/test logic with none-8-divisable length
+ {
+ const size_t scanlineLength = 3 * 501u;
+ Dali::Vector<uint32_t> scanline1;
+ Dali::Vector<uint32_t> scanline2;
+ Dali::Vector<uint32_t> reference;
+ Dali::Vector<uint32_t> output;
+ SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+
+ AverageScanlines3((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4 / 3);
+
+ // Check the output matches the independently generated reference:
+ size_t numMatches = 0;
+ MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
+ DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ }
- // Check the output matches the independently generated reference:
- size_t numMatches = 0;
- MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
- DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ // Very short test reusing RGBA setup/test logic with less-than-8 length
+ {
+ const size_t scanlineLength = 3u;
+ Dali::Vector<uint32_t> scanline1;
+ Dali::Vector<uint32_t> scanline2;
+ Dali::Vector<uint32_t> reference;
+ Dali::Vector<uint32_t> output;
+ SetupScanlinesRGBA8888(scanlineLength, scanline1, scanline2, reference, output);
+
+ AverageScanlines3((const unsigned char*)&scanline1[0], (const unsigned char*)&scanline2[0], (unsigned char*)&output[0], scanlineLength * 4 / 3);
+
+ // Check the output matches the independently generated reference:
+ size_t numMatches = 0;
+ MatchScanlinesRGBA8888(reference, output, numMatches, TEST_LOCATION);
+ DALI_TEST_EQUALS(numMatches, reference.Count(), TEST_LOCATION);
+ }
END_TEST;
}
/**
* @brief Constructs a new BitSet with all bits initialized with bits from the specified integer.
*
+ * This constructor is only available for BitSets with 32-bit capacity. Equivalent to the pseudocode:
+ * @code
+ * for(i = 0; i < 32; ++i) bits[i] = (data >> i) & 0x1;
+ * @endcode
+ *
+ * @param data 32-bit integer with the initial values.
+ */
+ template<std::size_t I = N, typename = std::enable_if_t<(I == N && N == 1u)>>
+ explicit BitSet(std::uint32_t data)
+ {
+ mData[0] = data;
+ }
+
+ /**
+ * @brief Constructs a new BitSet with all bits initialized with bits from the specified integer.
+ *
* This constructor is only available for BitSets with 64-bit capacity. Equivalent to the pseudocode:
* @code
* for(i = 0; i < 64; ++i) bits[i] = (data >> i) & 0x1;
/**
* @brief Obtains a copy of the internal storage serialized as a single integer.
*
+ * This method is only available for BitSets with 32-bit capacity.
+ *
+ * @return A copy of the internal storage.
+ *
+ * @see BitSet::BitSet(std::uint32_t)
+ */
+ template<std::size_t I = N, typename = std::enable_if_t<(I == N && N == 1u)>>
+ std::uint32_t GetRawData32() const
+ {
+ return mData[0];
+ }
+
+ /**
+ * @brief Obtains a copy of the internal storage serialized as a single integer.
+ *
* This method is only available for BitSets with 64-bit capacity.
*
* @return A copy of the internal storage.
// Operators
/**
+ * @copydoc BitSet::operator~() const
+ */
+ EnumBitSet operator~() const
+ {
+ return BitSet<N>::operator~();
+ }
+
+ /**
+ * @copydoc BitSet::operator|(const BitSet&) const
+ */
+ EnumBitSet operator|(const EnumBitSet& other) const
+ {
+ return BitSet<N>::operator|(other);
+ }
+
+ /**
+ * @copydoc BitSet::operator&(const BitSet&) const
+ */
+ EnumBitSet operator&(const EnumBitSet& other) const
+ {
+ return BitSet<N>::operator&(other);
+ }
+
+ /**
+ * @copydoc BitSet::operator^(const BitSet&) const
+ */
+ EnumBitSet operator^(const EnumBitSet& other) const
+ {
+ return BitSet<N>::operator^(other);
+ }
+
+ /**
* @copydoc BitSet::operator[](IndexType) const
*/
bool operator[](Enum index) const
}
private:
+ // For operators '~|&^'
+ EnumBitSet(BitSet<N>&& bitSet)
+ : BitSet<N>(bitSet)
+ {
+ }
+
// No data members (non-virtual destructor)
};
#include <dali/devel-api/adaptor-framework/proxy-accessible.h>
#include <dali/devel-api/adaptor-framework/window-devel.h>
#include <dali/devel-api/atspi-interfaces/accessible.h>
+#include <dali/devel-api/atspi-interfaces/action.h>
+#include <dali/devel-api/atspi-interfaces/application.h>
#include <dali/devel-api/atspi-interfaces/collection.h>
#include <dali/devel-api/atspi-interfaces/component.h>
+#include <dali/devel-api/atspi-interfaces/editable-text.h>
+#include <dali/devel-api/atspi-interfaces/hyperlink.h>
+#include <dali/devel-api/atspi-interfaces/hypertext.h>
+#include <dali/devel-api/atspi-interfaces/selection.h>
+#include <dali/devel-api/atspi-interfaces/text.h>
+#include <dali/devel-api/atspi-interfaces/value.h>
#include <dali/internal/adaptor/common/adaptor-impl.h>
#include <dali/public-api/dali-adaptor-common.h>
return std::string{it->second};
}
+AtspiInterfaces Accessible::GetInterfaces() const
+{
+ if(!mInterfaces)
+ {
+ mInterfaces = DoGetInterfaces();
+ DALI_ASSERT_DEBUG(mInterfaces); // There has to be at least AtspiInterface::ACCESSIBLE
+ }
+
+ return mInterfaces;
+}
+
+std::vector<std::string> Accessible::GetInterfacesAsStrings() const
+{
+ std::vector<std::string> ret;
+ AtspiInterfaces interfaces = GetInterfaces();
+
+ for(std::size_t i = 0u; i < static_cast<std::size_t>(AtspiInterface::MAX_COUNT); ++i)
+ {
+ auto interface = static_cast<AtspiInterface>(i);
+
+ if(interfaces[interface])
+ {
+ auto name = GetInterfaceName(interface);
+
+ DALI_ASSERT_DEBUG(!name.empty());
+ ret.emplace_back(std::move(name));
+ }
+ }
+
+ return ret;
+}
+
+AtspiInterfaces Accessible::DoGetInterfaces() const
+{
+ AtspiInterfaces interfaces;
+
+ interfaces[AtspiInterface::ACCESSIBLE] = true;
+ interfaces[AtspiInterface::ACTION] = dynamic_cast<const Action*>(this);
+ interfaces[AtspiInterface::APPLICATION] = dynamic_cast<const Application*>(this);
+ interfaces[AtspiInterface::COLLECTION] = dynamic_cast<const Collection*>(this);
+ interfaces[AtspiInterface::COMPONENT] = dynamic_cast<const Component*>(this);
+ interfaces[AtspiInterface::EDITABLE_TEXT] = dynamic_cast<const EditableText*>(this);
+ interfaces[AtspiInterface::HYPERLINK] = dynamic_cast<const Hyperlink*>(this);
+ interfaces[AtspiInterface::HYPERTEXT] = dynamic_cast<const Hypertext*>(this);
+ interfaces[AtspiInterface::SELECTION] = dynamic_cast<const Selection*>(this);
+ interfaces[AtspiInterface::TEXT] = dynamic_cast<const Text*>(this);
+ interfaces[AtspiInterface::VALUE] = dynamic_cast<const Value*>(this);
+
+ return interfaces;
+}
+
+std::string Accessible::GetInterfaceName(AtspiInterface interface)
+{
+ static const std::unordered_map<AtspiInterface, std::string_view> interfaceMap{
+ {AtspiInterface::ACCESSIBLE, "org.a11y.atspi.Accessible"},
+ {AtspiInterface::ACTION, "org.a11y.atspi.Action"},
+ {AtspiInterface::APPLICATION, "org.a11y.atspi.Application"},
+ {AtspiInterface::CACHE, "org.a11y.atspi.Cache"},
+ {AtspiInterface::COLLECTION, "org.a11y.atspi.Collection"},
+ {AtspiInterface::COMPONENT, "org.a11y.atspi.Component"},
+ {AtspiInterface::DEVICE_EVENT_CONTROLLER, "org.a11y.atspi.DeviceEventController"},
+ {AtspiInterface::DEVICE_EVENT_LISTENER, "org.a11y.atspi.DeviceEventListener"},
+ {AtspiInterface::DOCUMENT, "org.a11y.atspi.Document"},
+ {AtspiInterface::EDITABLE_TEXT, "org.a11y.atspi.EditableText"},
+ {AtspiInterface::EVENT_DOCUMENT, "org.a11y.atspi.Event.Document"},
+ {AtspiInterface::EVENT_FOCUS, "org.a11y.atspi.Event.Focus"},
+ {AtspiInterface::EVENT_KEYBOARD, "org.a11y.atspi.Event.Keyboard"},
+ {AtspiInterface::EVENT_MOUSE, "org.a11y.atspi.Event.Mouse"},
+ {AtspiInterface::EVENT_OBJECT, "org.a11y.atspi.Event.Object"},
+ {AtspiInterface::EVENT_TERMINAL, "org.a11y.atspi.Event.Terminal"},
+ {AtspiInterface::EVENT_WINDOW, "org.a11y.atspi.Event.Window"},
+ {AtspiInterface::HYPERLINK, "org.a11y.atspi.Hyperlink"},
+ {AtspiInterface::HYPERTEXT, "org.a11y.atspi.Hypertext"},
+ {AtspiInterface::IMAGE, "org.a11y.atspi.Image"},
+ {AtspiInterface::REGISTRY, "org.a11y.atspi.Registry"},
+ {AtspiInterface::SELECTION, "org.a11y.atspi.Selection"},
+ {AtspiInterface::SOCKET, "org.a11y.atspi.Socket"},
+ {AtspiInterface::TABLE, "org.a11y.atspi.Table"},
+ {AtspiInterface::TABLE_CELL, "org.a11y.atspi.TableCell"},
+ {AtspiInterface::TEXT, "org.a11y.atspi.Text"},
+ {AtspiInterface::VALUE, "org.a11y.atspi.Value"},
+ };
+
+ auto it = interfaceMap.find(interface);
+
+ if(it == interfaceMap.end())
+ {
+ return {};
+ }
+
+ return std::string{it->second};
+}
+
Dali::Actor Accessible::GetCurrentlyHighlightedActor()
{
return IsUp() ? Bridge::GetCurrentBridge()->mData->mCurrentlyHighlightedActor : Dali::Actor{};
MAX_COUNT\r
};\r
\r
+/**\r
+ * @brief Enumeration of all AT-SPI interfaces.\r
+ *\r
+ * @see Dali::Accessibility::Accessible::GetInterfaceName()\r
+ * @see Dali::Accessibility::AtspiInterfaceType\r
+ */\r
+enum class AtspiInterface\r
+{\r
+ ACCESSIBLE,\r
+ ACTION,\r
+ APPLICATION,\r
+ CACHE,\r
+ COLLECTION,\r
+ COMPONENT,\r
+ DEVICE_EVENT_CONTROLLER,\r
+ DEVICE_EVENT_LISTENER,\r
+ DOCUMENT,\r
+ EDITABLE_TEXT,\r
+ EVENT_DOCUMENT,\r
+ EVENT_FOCUS,\r
+ EVENT_KEYBOARD,\r
+ EVENT_MOUSE,\r
+ EVENT_OBJECT,\r
+ EVENT_TERMINAL,\r
+ EVENT_WINDOW,\r
+ HYPERLINK,\r
+ HYPERTEXT,\r
+ IMAGE,\r
+ REGISTRY,\r
+ SELECTION,\r
+ SOCKET,\r
+ TABLE,\r
+ TABLE_CELL,\r
+ TEXT,\r
+ VALUE,\r
+ MAX_COUNT\r
+};\r
+\r
+using AtspiInterfaces = EnumBitSet<AtspiInterface, AtspiInterface::MAX_COUNT>;\r
using ReadingInfoTypes = EnumBitSet<ReadingInfoType, ReadingInfoType::MAX_COUNT>;\r
using States = EnumBitSet<State, State::MAX_COUNT>;\r
using Attributes = std::unordered_map<std::string, std::string>;\r
\r
+namespace Internal\r
+{\r
+/*\r
+ * AT-SPI interfaces exposed as native C++ types should specialize this like so:\r
+ *\r
+ * template<>\r
+ * struct AtspiInterfaceTypeHelper<AtspiInterface::ACCESSIBLE>\r
+ * {\r
+ * using Type = Dali::Accessibility::Accessible;\r
+ * };\r
+ */\r
+template<AtspiInterface I>\r
+struct AtspiInterfaceTypeHelper; // no default definition\r
+\r
+} // namespace Internal\r
+\r
+/**\r
+ * @brief Resolves to the native C++ type that represents the given AT-SPI interface.\r
+ *\r
+ * For example, @code AtspiInterfaceType<AtspiInterface::ACCESSIBLE> @endcode is the same as\r
+ * @code Dali::Accessibility::Accessible @endcode. Not all AT-SPI interfaces have native C++\r
+ * representations (in which case, such an expression will not compile).\r
+ *\r
+ * @tparam I Enumeration value indicating the requested AT-SPI interface.\r
+ */\r
+template<AtspiInterface I>\r
+using AtspiInterfaceType = typename Internal::AtspiInterfaceTypeHelper<I>::Type;\r
+\r
/**\r
* @brief Class representing unique object address on accessibility bus\r
* @see Dali::Accessibility::Accessible::GetAddress\r
/**
* @brief Gets all implemented interfaces.
*
- * @return The collection of strings with implemented interfaces
+ * Override DoGetInterfaces() to customize the return value of this method.
+ *
+ * @return The collection of implemented interfaces
+ *
+ * @see DoGetInterfaces()
+ */
+ AtspiInterfaces GetInterfaces() const;
+
+ /**
+ * @brief Gets all implemented interfaces.
+ *
+ * Converts all interfaces returned by GetInterfaces() to their DBus names
+ * using GetInterfaceName().
+ *
+ * @return The collection of names of implemented interfaces
+ *
+ * @see GetInterfaces()
+ * @see GetInterfaceName()
*/
- std::vector<std::string> GetInterfaces() const;
+ std::vector<std::string> GetInterfacesAsStrings() const;
/**
* @brief Checks if object is on root level.
Accessible& operator=(Accessible&&) = delete;
std::shared_ptr<Bridge::Data> GetBridgeData() const;
+ /**
+ * @brief Returns the collection of AT-SPI interfaces implemented by this Accessible.
+ *
+ * This method is called only once and its return value is cached. The default implementation
+ * uses dynamic_cast to determine which interfaces are implemented. Override this if you
+ * conceptually provide fewer interfaces than dynamic_cast can see.
+ *
+ * @return The collection of implemented interfaces
+ *
+ * @see GetInterfaces()
+ * @see GetInterfaceName()
+ */
+ virtual AtspiInterfaces DoGetInterfaces() const;
+
public:
/**
* @brief Gets the highlight actor.
*/
static Accessible* Get(Dali::Actor actor, bool isRoot = false);
+ /**
+ * @brief Obtains the DBus interface name for the specified AT-SPI interface.
+ *
+ * @param interface AT-SPI interface identifier (e.g. AtspiInterface::ACCESSIBLE)
+ * @return AT-SPI interface name (e.g. "org.a11y.atspi.Accessible")
+ */
+ static std::string GetInterfaceName(AtspiInterface interface);
+
+ /**
+ * @brief Downcasts an Accessible pointer to an AT-SPI interface pointer.
+ *
+ * @tparam I Desired AT-SPI interface
+ *
+ * @param obj Object to cast.
+ *
+ * @return Pointer to an AT-SPI interface or null if the interface is not implemented.
+ */
+ template<AtspiInterface I>
+ static AtspiInterfaceType<I>* DownCast(Accessible* obj)
+ {
+ if(!obj || !obj->GetInterfaces()[I])
+ {
+ return nullptr;
+ }
+
+ return dynamic_cast<AtspiInterfaceType<I>*>(obj);
+ }
+
private:
friend class Bridge;
mutable std::weak_ptr<Bridge::Data> mBridgeData;
+ mutable AtspiInterfaces mInterfaces;
bool mIsOnRootLevel = false;
}; // Accessible class
+namespace Internal
+{
+template<>
+struct AtspiInterfaceTypeHelper<AtspiInterface::ACCESSIBLE>
+{
+ using Type = Accessible;
+};
+} // namespace Internal
+
} // namespace Dali::Accessibility
#endif // DALI_ADAPTOR_ATSPI_ACCESSIBLE_H
* @return true on success, false otherwise
*/
virtual bool DoAction(const std::string& name) = 0;
+
+ /**
+ * @brief Downcasts an Accessible to an Action.
+ *
+ * @param obj The Accessible
+ * @return An Action or null
+ *
+ * @see Dali::Accessibility::Accessible::DownCast()
+ */
+ static inline Action* DownCast(Accessible* obj);
};
+namespace Internal
+{
+template<>
+struct AtspiInterfaceTypeHelper<AtspiInterface::ACTION>
+{
+ using Type = Action;
+};
+} // namespace Internal
+
+inline Action* Action::DownCast(Accessible* obj)
+{
+ return Accessible::DownCast<AtspiInterface::ACTION>(obj);
+}
+
} // namespace Dali::Accessibility
#endif // DALI_ADAPTOR_ATSPI_ACTION_H
* @return String with version
*/
virtual std::string GetVersion() const = 0;
+
+ /**
+ * @brief Downcasts an Accessible to an Application.
+ *
+ * @param obj The Accessible
+ * @return An Application or null
+ *
+ * @see Dali::Accessibility::Accessible::DownCast()
+ */
+ static inline Application* DownCast(Accessible* obj);
};
+namespace Internal
+{
+template<>
+struct AtspiInterfaceTypeHelper<AtspiInterface::APPLICATION>
+{
+ using Type = Application;
+};
+} // namespace Internal
+
+inline Application* Application::DownCast(Accessible* obj)
+{
+ return Accessible::DownCast<AtspiInterface::APPLICATION>(obj);
+}
+
} // namespace Dali::Accessibility
#endif // DALI_ADAPTOR_ATSPI_APPLICATION_H
/**
* @brief Interface enabling advanced quering of accessibility objects.
*
- * @note since all mathods can be implemented inside bridge,
- * none methods have to be overrided
+ * @note Since all methods can be implemented inside bridge,
+ * no methods have to be overriden.
*/
class DALI_ADAPTOR_API Collection : public virtual Accessible
{
+ /**
+ * @brief Downcasts an Accessible to a Collection.
+ *
+ * @param obj The Accessible
+ * @return A Collection or null
+ *
+ * @see Dali::Accessibility::Accessible::DownCast()
+ */
+ static inline Collection* DownCast(Accessible* obj);
};
+namespace Internal
+{
+template<>
+struct AtspiInterfaceTypeHelper<AtspiInterface::COLLECTION>
+{
+ using Type = Collection;
+};
+} // namespace Internal
+
+inline Collection* Collection::DownCast(Accessible* obj)
+{
+ return Accessible::DownCast<AtspiInterface::COLLECTION>(obj);
+}
+
} // namespace Dali::Accessibility
#endif // DALI_ADAPTOR_ATSPI_COLLECTION_H
* @see Dali::Accessibility::Point
*/
virtual bool IsAccessibleContainingPoint(Point point, CoordinateType type) const;
+
+ /**
+ * @brief Downcasts an Accessible to a Component.
+ *
+ * @param obj The Accessible
+ * @return A Component or null
+ *
+ * @see Dali::Accessibility::Accessible::DownCast()
+ */
+ static inline Component* DownCast(Accessible* obj);
};
+namespace Internal
+{
+template<>
+struct AtspiInterfaceTypeHelper<AtspiInterface::COMPONENT>
+{
+ using Type = Component;
+};
+} // namespace Internal
+
+inline Component* Component::DownCast(Accessible* obj)
+{
+ return Accessible::DownCast<AtspiInterface::COMPONENT>(obj);
+}
+
} // namespace Dali::Accessibility
#endif // DALI_ADAPTOR_ATSPI_COMPONENT_H
* @return true on success, false otherwise
*/
virtual bool SetTextContents(std::string newContents) = 0;
+
+ /**
+ * @brief Downcasts an Accessible to an EditableText.
+ *
+ * @param obj The Accessible
+ * @return An EditableText or null
+ *
+ * @see Dali::Accessibility::Accessible::DownCast()
+ */
+ static inline EditableText* DownCast(Accessible* obj);
};
+namespace Internal
+{
+template<>
+struct AtspiInterfaceTypeHelper<AtspiInterface::EDITABLE_TEXT>
+{
+ using Type = EditableText;
+};
+} // namespace Internal
+
+inline EditableText* EditableText::DownCast(Accessible* obj)
+{
+ return Accessible::DownCast<AtspiInterface::EDITABLE_TEXT>(obj);
+}
+
} // namespace Dali::Accessibility
#endif // DALI_ADAPTOR_ATSPI_EDITABLE_TEXT_H
* @return True if hyperlink object is valid, false otherwise
*/
virtual bool IsValid() const = 0;
+
+ /**
+ * @brief Downcasts an Accessible to a Hyperlink.
+ *
+ * @param obj The Accessible
+ * @return A Hyperlink or null
+ *
+ * @see Dali::Accessibility::Accessible::DownCast()
+ */
+ static inline Hyperlink* DownCast(Accessible* obj);
};
+namespace Internal
+{
+template<>
+struct AtspiInterfaceTypeHelper<AtspiInterface::HYPERLINK>
+{
+ using Type = Hyperlink;
+};
+} // namespace Internal
+
+inline Hyperlink* Hyperlink::DownCast(Accessible* obj)
+{
+ return Accessible::DownCast<AtspiInterface::HYPERLINK>(obj);
+}
+
} // namespace Dali::Accessibility
#endif // DALI_ADAPTOR_ATSPI_HYPERLINK_H
* @return The number of hyperlinks (zero if none or -1 if the number cannot be determined)
*/
virtual std::int32_t GetLinkCount() const = 0;
+
+ /**
+ * @brief Downcasts an Accessible to a Hypertext.
+ *
+ * @param obj The Accessible
+ * @return A Hypertext or null
+ *
+ * @see Dali::Accessibility::Accessible::DownCast()
+ */
+ static inline Hypertext* DownCast(Accessible* obj);
};
+namespace Internal
+{
+template<>
+struct AtspiInterfaceTypeHelper<AtspiInterface::HYPERTEXT>
+{
+ using Type = Hypertext;
+};
+} // namespace Internal
+
+inline Hypertext* Hypertext::DownCast(Accessible* obj)
+{
+ return Accessible::DownCast<AtspiInterface::HYPERTEXT>(obj);
+}
+
} // namespace Dali::Accessibility
#endif // DALI_ADAPTOR_ATSPI_HYPERTEXT_H
* @see Dali::Accessibility::Selection::DeselectSelectedChild
*/
virtual bool DeselectChild(int childIndex) = 0;
+
+ /**
+ * @brief Downcasts an Accessible to a Selection.
+ *
+ * @param obj The Accessible
+ * @return A Selection or null
+ *
+ * @see Dali::Accessibility::Accessible::DownCast()
+ */
+ static inline Selection* DownCast(Accessible* obj);
};
+namespace Internal
+{
+template<>
+struct AtspiInterfaceTypeHelper<AtspiInterface::SELECTION>
+{
+ using Type = Selection;
+};
+} // namespace Internal
+
+inline Selection* Selection::DownCast(Accessible* obj)
+{
+ return Accessible::DownCast<AtspiInterface::SELECTION>(obj);
+}
+
} // namespace Dali::Accessibility
#endif // DALI_ADAPTOR_ATSPI_SELECTION_H
* @remarks This method is `SetSelection` in DBus method.
*/
virtual bool SetRangeOfSelection(std::size_t selectionIndex, std::size_t startOffset, std::size_t endOffset) = 0;
+
+ /**
+ * @brief Downcasts an Accessible to a Text.
+ *
+ * @param obj The Accessible
+ * @return A Text or null
+ *
+ * @see Dali::Accessibility::Accessible::DownCast()
+ */
+ static inline Text* DownCast(Accessible* obj);
};
+namespace Internal
+{
+template<>
+struct AtspiInterfaceTypeHelper<AtspiInterface::TEXT>
+{
+ using Type = Text;
+};
+} // namespace Internal
+
+inline Text* Text::DownCast(Accessible* obj)
+{
+ return Accessible::DownCast<AtspiInterface::TEXT>(obj);
+}
+
} // namespace Dali::Accessibility
#endif // DALI_ADAPTOR_ATSPI_TEXT_H
* @return The lowest increment
*/
virtual double GetMinimumIncrement() const = 0;
+
+ /**
+ * @brief Downcasts an Accessible to a Value.
+ *
+ * @param obj The Accessible
+ * @return A Value or null
+ *
+ * @see Dali::Accessibility::Accessible::DownCast()
+ */
+ static inline Value* DownCast(Accessible* obj);
+};
+
+namespace Internal
+{
+template<>
+struct AtspiInterfaceTypeHelper<AtspiInterface::VALUE>
+{
+ using Type = Value;
};
+} // namespace Internal
+
+inline Value* Value::DownCast(Accessible* obj)
+{
+ return Accessible::DownCast<AtspiInterface::VALUE>(obj);
+}
} // namespace Dali::Accessibility
#include <dali/internal/accessibility/bridge/dbus.h>
#include <dali/public-api/dali-adaptor-common.h>
-/* DBus Interfaces */
+// DBus names
#define A11yDbusName "org.a11y.Bus"
-#define A11yDbusPath "/org/a11y/bus"
#define A11yDbusStatusInterface "org.a11y.Status"
#define AtspiDbusNameRegistry "org.a11y.atspi.Registry"
+#define DirectReadingDBusName "org.tizen.ScreenReader"
+#define DirectReadingDBusInterface "org.tizen.DirectReading"
+
+// DBus paths
+
+#define A11yDbusPath "/org/a11y/bus"
+#define AtspiDbusPathCache "/org/a11y/atspi/cache"
+#define AtspiDbusPathDec "/org/a11y/atspi/registry/deviceeventcontroller"
#define AtspiDbusPathRegistry "/org/a11y/atspi/registry"
-#define AtspiDbusInterfaceRegistry "org.a11y.atspi.Registry"
#define AtspiDbusPathRoot "/org/a11y/atspi/accessible/root"
-#define AtspiDbusInterfaceSocket "org.a11y.atspi.Socket"
#define AtspiPath "/org/a11y/atspi/accessible"
-#define AtspiDbusInterfaceAccessible "org.a11y.atspi.Accessible"
-#define AtspiDbusInterfaceAction "org.a11y.atspi.Action"
-#define AtspiDbusInterfaceApplication "org.a11y.atspi.Application"
-#define AtspiDbusInterfaceCache "org.a11y.atspi.Cache"
-#define AtspiDbusPathCache "/org/a11y/atspi/cache"
-#define AtspiDbusInterfaceCollection "org.a11y.atspi.Collection"
-#define AtspiDbusInterfaceComponent "org.a11y.atspi.Component"
-#define AtspiDbusInterfaceDocument "org.a11y.atspi.Document"
-#define AtspiDbusInterfaceEditableText "org.a11y.atspi.EditableText"
-#define AtspiDbusInterfaceEventKeyboard "org.a11y.atspi.Event.Keyboard"
-#define AtspiDbusInterfaceEventMouse "org.a11y.atspi.Event.Mouse"
-#define AtspiDbusInterfaceEventObject "org.a11y.atspi.Event.Object"
-#define AtspiDbusInterfaceHyperlink "org.a11y.atspi.Hyperlink"
-#define AtspiDbusInterfaceHypertext "org.a11y.atspi.Hypertext"
-#define AtspiDbusInterfaceImage "org.a11y.atspi.Image"
-#define AtspiDbusInterfaceSelection "org.a11y.atspi.Selection"
-#define AtspiDbusInterfaceTable "org.a11y.atspi.Table"
-#define AtspiDbusInterfaceTableCell "org.a11y.atspi.TableCell"
-#define AtspiDbusInterfaceText "org.a11y.atspi.Text"
-#define AtspiDbusInterfaceValue "org.a11y.atspi.Value"
-#define AtspiDbusInterfaceSocket "org.a11y.atspi.Socket"
-#define AtspiDbusInterfaceEventWindow "org.a11y.atspi.Event.Window"
-
-#define AtspiDbusPathDec "/org/a11y/atspi/registry/deviceeventcontroller"
-#define AtspiDbusInterfaceDec "org.a11y.atspi.DeviceEventController"
-#define AtspiDbusInterfaceDeviceEventListener "org.a11y.atspi.DeviceEventListener"
-
-#define DirectReadingDBusName "org.tizen.ScreenReader"
#define DirectReadingDBusPath "/org/tizen/DirectReading"
-#define DirectReadingDBusInterface "org.tizen.DirectReading"
struct ObjectPath;
//INTERNAL INCLUDES
#include <dali/devel-api/atspi-interfaces/accessible.h>
-#include <dali/devel-api/atspi-interfaces/action.h>
-#include <dali/devel-api/atspi-interfaces/application.h>
-#include <dali/devel-api/atspi-interfaces/collection.h>
-#include <dali/devel-api/atspi-interfaces/component.h>
-#include <dali/devel-api/atspi-interfaces/editable-text.h>
-#include <dali/devel-api/atspi-interfaces/hyperlink.h>
-#include <dali/devel-api/atspi-interfaces/hypertext.h>
-#include <dali/devel-api/atspi-interfaces/selection.h>
-#include <dali/devel-api/atspi-interfaces/text.h>
-#include <dali/devel-api/atspi-interfaces/value.h>
#include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
#include <dali/internal/accessibility/bridge/accessibility-common.h>
#include <third-party/libunibreak/linebreak.h>
using namespace Dali::Accessibility;
-std::vector<std::string> Accessible::GetInterfaces() const
-{
- std::vector<std::string> tmp;
- tmp.push_back(AtspiDbusInterfaceAccessible);
- if(dynamic_cast<const Collection*>(this))
- {
- tmp.push_back(AtspiDbusInterfaceCollection);
- }
- if(dynamic_cast<const Text*>(this))
- {
- tmp.push_back(AtspiDbusInterfaceText);
- }
- if(dynamic_cast<const EditableText*>(this))
- {
- tmp.push_back(AtspiDbusInterfaceEditableText);
- }
- if(dynamic_cast<const Value*>(this))
- {
- tmp.push_back(AtspiDbusInterfaceValue);
- }
- if(dynamic_cast<const Component*>(this))
- {
- tmp.push_back(AtspiDbusInterfaceComponent);
- }
- if(auto action = dynamic_cast<const Action*>(this))
- {
- if(action->GetActionCount() > 0)
- {
- tmp.push_back(AtspiDbusInterfaceAction);
- }
- }
- if(dynamic_cast<const Selection*>(this))
- {
- tmp.push_back(AtspiDbusInterfaceSelection);
- }
- if(dynamic_cast<const Hypertext*>(this))
- {
- tmp.push_back(AtspiDbusInterfaceHypertext);
- }
- if(dynamic_cast<const Hyperlink*>(this))
- {
- tmp.push_back(AtspiDbusInterfaceHyperlink);
- }
- return tmp;
-}
-
Accessible::Accessible()
{
}
void BridgeAccessible::RegisterInterfaces()
{
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceAccessible};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::ACCESSIBLE)};
AddGetPropertyToInterface(desc, "ChildCount", &BridgeAccessible::GetChildCount);
AddGetPropertyToInterface(desc, "Name", &BridgeAccessible::GetName);
AddGetPropertyToInterface(desc, "Description", &BridgeAccessible::GetDescription);
AddFunctionToInterface(desc, "GetLocalizedRoleName", &BridgeAccessible::GetLocalizedRoleName);
AddFunctionToInterface(desc, "GetState", &BridgeAccessible::GetStates);
AddFunctionToInterface(desc, "GetAttributes", &BridgeAccessible::GetAttributes);
- AddFunctionToInterface(desc, "GetInterfaces", &BridgeAccessible::GetInterfaces);
+ AddFunctionToInterface(desc, "GetInterfaces", &BridgeAccessible::GetInterfacesAsStrings);
AddFunctionToInterface(desc, "GetChildAtIndex", &BridgeAccessible::GetChildAtIndex);
AddFunctionToInterface(desc, "GetChildren", &BridgeAccessible::GetChildren);
AddFunctionToInterface(desc, "GetIndexInParent", &BridgeAccessible::GetIndexInParent);
mDbusServer.addInterface("/", desc, true);
}
+Accessible* BridgeAccessible::FindSelf() const
+{
+ return FindCurrentObject();
+}
+
Component* BridgeAccessible::GetObjectInRelation(Accessible* obj, RelationType relationType)
{
if(!obj)
double minimumIncrement = 0.0;
double maximumValue = 0.0;
double minimumValue = 0.0;
- auto* valueInterface = dynamic_cast<Dali::Accessibility::Value*>(self);
+ auto* valueInterface = Value::DownCast(self);
if(valueInterface)
{
currentValue = valueInterface->GetCurrent();
int32_t firstSelectedChildIndex = -1;
int32_t selectedChildCount = 0;
- auto* selfSelectionInterface = dynamic_cast<Dali::Accessibility::Selection*>(self);
+ auto* selfSelectionInterface = Selection::DownCast(self);
if(selfSelectionInterface)
{
selectedChildCount = selfSelectionInterface->GetSelectedChildrenCount();
listChildrenCount = GetItemCountOfFirstDescendantContainer(self, Role::POPUP_MENU, Role::MENU_ITEM, false);
}
- auto* textInterface = dynamic_cast<Dali::Accessibility::Text*>(self);
+ auto* textInterface = Text::DownCast(self);
std::string nameFromTextInterface = "";
if(textInterface)
{
auto parentChildCount = parent ? static_cast<int32_t>(parent->GetChildCount()) : 0;
auto parentStateSet = parent ? parent->GetStates() : States{};
bool isSelectedInParent = false;
- auto* parentSelectionInterface = dynamic_cast<Dali::Accessibility::Selection*>(parent);
+ auto* parentSelectionInterface = Selection::DownCast(parent);
if(parentSelectionInterface)
{
isSelectedInParent = parentSelectionInterface->IsChildSelected(indexInParent);
return attributes;
}
-DBus::ValueOrError<std::vector<std::string>> BridgeAccessible::GetInterfaces()
+DBus::ValueOrError<std::vector<std::string>> BridgeAccessible::GetInterfacesAsStrings()
{
- return FindSelf()->GetInterfaces();
+ return FindSelf()->GetInterfacesAsStrings();
}
int BridgeAccessible::GetChildCount()
*/
void RegisterInterfaces();
+ /**
+ * @brief Returns the Accessible object of the currently executed DBus method call.
+ *
+ * @return The Accessible object
+ */
+ Dali::Accessibility::Accessible* FindSelf() const;
+
public:
/**
* @brief Enumeration for NeighborSearchMode.
DBus::ValueOrError<std::unordered_map<std::string, std::string>> GetAttributes();
/**
- * @copydoc Dali::Accessibility::Accessible::GetInterfaces()
+ * @copydoc Dali::Accessibility::Accessible::GetInterfacesAsStrings()
*/
- DBus::ValueOrError<std::vector<std::string>> GetInterfaces();
+ DBus::ValueOrError<std::vector<std::string>> GetInterfacesAsStrings();
/**
* @brief Gets Accessible object on which surface lies the point with given coordinates.
// CLASS HEADER
#include <dali/internal/accessibility/bridge/bridge-action.h>
-// EXTERNAL INCLUDES
-#include <iostream>
-
using namespace Dali::Accessibility;
void BridgeAction::RegisterInterfaces()
{
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceAction};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::ACTION)};
AddGetPropertyToInterface(desc, "NActions", &BridgeAction::GetActionCount);
Action* BridgeAction::FindSelf() const
{
- auto self = BridgeBase::FindSelf();
- assert(self);
- auto actionInterface = dynamic_cast<Action*>(self);
- if(!actionInterface)
- {
- throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have Action interface"};
- }
- return actionInterface;
+ return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::ACTION>();
}
DBus::ValueOrError<std::string> BridgeAction::GetActionName(int32_t index)
void BridgeApplication::RegisterInterfaces()
{
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceApplication};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::APPLICATION)};
AddGetPropertyToInterface(desc, "ToolkitName", &BridgeApplication::GetToolkitName);
AddGetPropertyToInterface(desc, "Version", &BridgeApplication::GetVersion);
mDbusServer.addInterface("/", desc, true);
Application* BridgeApplication::FindSelf() const
{
- auto self = BridgeBase::FindSelf();
- assert(self);
- auto appInterface = dynamic_cast<Application*>(self);
- if(!appInterface)
- {
- throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have Application interface"};
- }
- return appInterface;
+ return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::APPLICATION>();
}
std::string BridgeApplication::GetToolkitName()
mDbusServer = {mConnectionPtr};
{
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceCache};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::CACHE)};
AddFunctionToInterface(desc, "GetItems", &BridgeBase::GetItems);
mDbusServer.addInterface(AtspiDbusPathCache, desc);
}
{
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceApplication};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::APPLICATION)};
AddGetSetPropertyToInterface(desc, "Id", &BridgeBase::GetId, &BridgeBase::SetId);
mDbusServer.addInterface(AtspiPath, desc);
}
- mRegistry = {AtspiDbusNameRegistry, AtspiDbusPathRegistry, AtspiDbusInterfaceRegistry, mConnectionPtr};
+ mRegistry = {AtspiDbusNameRegistry, AtspiDbusPathRegistry, Accessible::GetInterfaceName(AtspiInterface::REGISTRY), mConnectionPtr};
UpdateRegisteredEvents();
return Find(ptr.GetPath());
}
-Accessible* BridgeBase::FindSelf() const
+Accessible* BridgeBase::FindCurrentObject() const
{
auto path = DBus::DBusServer::getCurrentObjectPath();
auto size = strlen(AtspiPath);
root->GetAddress(),
parent ? parent->GetAddress() : Address{},
children,
- item->GetInterfaces(),
+ item->GetInterfacesAsStrings(),
item->GetName(),
item->GetRole(),
item->GetDescription(),
/**
* @brief Returns the target object of the currently executed DBus method call.
*
- * And any subclasses redefine `FindSelf` with a different return type as a convenient wrapper around dynamic_cast.
* @return The Accessible object
* @note When a DBus method is called on some object, this target object (`currentObject`) is temporarily saved by the bridge,
* because DBus handles the invocation target separately from the method arguments.
* We then use the saved object inside the 'glue' method (e.g. BridgeValue::GetMinimum)
* to call the equivalent method on the respective C++ object (this could be ScrollBar::AccessibleImpl::GetMinimum in the example given).
*/
- Dali::Accessibility::Accessible* FindSelf() const;
+ Dali::Accessibility::Accessible* FindCurrentObject() const;
+
+ /**
+ * @brief Returns the target object of the currently executed DBus method call.
+ *
+ * This method tries to downcast the return value of FindCurrentObject() to the requested type,
+ * issuing an error reply to the DBus caller if the requested type is not implemented. Whether
+ * a given type is implemented is decided based on the return value of Accessible::GetInterfaces()
+ * for the current object.
+ *
+ * @tparam I The requested AT-SPI interface
+ * @return The Accessible object (cast to a more derived type)
+ *
+ * @see FindCurrentObject()
+ * @see Dali::Accessibility::AtspiInterface
+ * @see Dali::Accessibility::AtspiInterfaceType
+ * @see Dali::Accessibility::Accessible::GetInterfaces()
+ */
+ template<Dali::Accessibility::AtspiInterface I>
+ auto* FindCurrentObjectWithInterface() const
+ {
+ using Type = Dali::Accessibility::AtspiInterfaceType<I>;
+
+ Type* result;
+ auto* currentObject = FindCurrentObject();
+ DALI_ASSERT_DEBUG(currentObject); // FindCurrentObject() throws domain_error
+
+ if(!(result = Dali::Accessibility::Accessible::DownCast<I>(currentObject)))
+ {
+ std::stringstream s;
+
+ s << "Object " << currentObject->GetAddress().ToString();
+ s << " does not implement ";
+ s << Dali::Accessibility::Accessible::GetInterfaceName(I);
+
+ throw std::domain_error{s.str()};
+ }
+
+ return result;
+ }
/**
* @copydoc Dali::Accessibility::Bridge::FindByPath()
// EXTERNAL INCLUDES
#include <algorithm>
-#include <iostream>
#include <unordered_set>
#include <vector>
void BridgeCollection::RegisterInterfaces()
{
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceCollection};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::COLLECTION)};
AddFunctionToInterface(desc, "GetMatches", &BridgeCollection::GetMatches);
mDbusServer.addInterface("/", desc, true);
}
Collection* BridgeCollection::FindSelf() const
{
- auto self = BridgeBase::FindSelf();
- assert(self);
- auto collectionInterface = dynamic_cast<Collection*>(self);
- if(!collectionInterface)
- {
- throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have Collection interface"};
- }
- return collectionInterface;
+ return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::COLLECTION>();
}
/**
void Update(Accessible* obj)
{
mObject.clear();
- for(auto& interface : obj->GetInterfaces())
+ for(auto& interface : obj->GetInterfacesAsStrings())
{
mObject.insert(std::move(interface));
}
DBus::ValueOrError<std::vector<Accessible*> > BridgeCollection::GetMatches(MatchRule rule, uint32_t sortBy, int32_t count, bool traverse)
{
std::vector<Accessible*> res;
- auto self = BridgeBase::FindSelf();
+ auto self = BridgeBase::FindCurrentObject();
auto matcher = Comparer{&rule};
VisitNodes(self, res, matcher, count);
// CLASS HEADER
#include <dali/internal/accessibility/bridge/bridge-component.h>
-// EXTERNAL INCLUDES
-#include <iostream>
-
#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
using namespace Dali::Accessibility;
// Screen Reader will call the methods with the exact names as specified in the AT-SPI Component interface:
// https://gitlab.gnome.org/GNOME/at-spi2-core/-/blob/master/xml/Component.xml
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceComponent};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::COMPONENT)};
AddFunctionToInterface(desc, "Contains", &BridgeComponent::IsAccessibleContainingPoint);
AddFunctionToInterface(desc, "GetAccessibleAtPoint", &BridgeComponent::GetAccessibleAtPoint);
AddFunctionToInterface(desc, "GetExtents", &BridgeComponent::GetExtents);
Component* BridgeComponent::FindSelf() const
{
- auto self = BridgeBase::FindSelf();
- assert(self);
- auto componentInterface = dynamic_cast<Component*>(self);
- if(!componentInterface)
- {
- throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have Component interface"};
- }
- return componentInterface;
+ return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::COMPONENT>();
}
DBus::ValueOrError<bool> BridgeComponent::IsAccessibleContainingPoint(int32_t x, int32_t y, uint32_t coordType)
void BridgeEditableText::RegisterInterfaces()
{
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceEditableText};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::EDITABLE_TEXT)};
AddFunctionToInterface(desc, "CopyText", &BridgeEditableText::CopyText);
AddFunctionToInterface(desc, "CutText", &BridgeEditableText::CutText);
AddFunctionToInterface(desc, "DeleteText", &BridgeEditableText::DeleteText);
EditableText* BridgeEditableText::FindSelf() const
{
- auto self = BridgeBase::FindSelf();
- assert(self);
- auto editableTextInterface = dynamic_cast<EditableText*>(self);
- if(!editableTextInterface)
- {
- throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have Text interface"};
- }
- return editableTextInterface;
+ return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::EDITABLE_TEXT>();
}
DBus::ValueOrError<bool> BridgeEditableText::CopyText(int32_t startPosition, int32_t endPosition)
void BridgeHyperlink::RegisterInterfaces()
{
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceHyperlink};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::HYPERLINK)};
AddGetPropertyToInterface(desc, "NAnchors", &BridgeHyperlink::GetAnchorCount);
AddGetPropertyToInterface(desc, "StartIndex", &BridgeHyperlink::GetStartIndex);
AddGetPropertyToInterface(desc, "EndIndex", &BridgeHyperlink::GetEndIndex);
Hyperlink* BridgeHyperlink::FindSelf() const
{
- auto self = BridgeBase::FindSelf();
- assert(self);
- auto hyperlinkInterface = dynamic_cast<Hyperlink*>(self);
- if(!hyperlinkInterface)
- {
- throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have Hyperlink interface"};
- }
- return hyperlinkInterface;
+ return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::HYPERLINK>();
}
DBus::ValueOrError<int32_t> BridgeHyperlink::GetEndIndex()
void BridgeHypertext::RegisterInterfaces()
{
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceHypertext};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::HYPERTEXT)};
AddFunctionToInterface(desc, "GetNLinks", &BridgeHypertext::GetLinkCount);
AddFunctionToInterface(desc, "GetLink", &BridgeHypertext::GetLink);
AddFunctionToInterface(desc, "GetLinkIndex", &BridgeHypertext::GetLinkIndex);
Hypertext* BridgeHypertext::FindSelf() const
{
- auto self = BridgeBase::FindSelf();
- assert(self);
- auto hypertextInterface = dynamic_cast<Hypertext*>(self);
- if(!hypertextInterface)
- {
- throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have Hypertext interface"};
- }
- return hypertextInterface;
+ return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::HYPERTEXT>();
}
DBus::ValueOrError<int32_t> BridgeHypertext::GetLinkCount()
RegisterOnBridge(&mApplication);
- mRegistryClient = {AtspiDbusNameRegistry, AtspiDbusPathDec, AtspiDbusInterfaceDec, mConnectionPtr};
+ mRegistryClient = {AtspiDbusNameRegistry, AtspiDbusPathDec, Accessible::GetInterfaceName(AtspiInterface::DEVICE_EVENT_CONTROLLER), mConnectionPtr};
mDirectReadingClient = DBus::DBusClient{DirectReadingDBusName, DirectReadingDBusPath, DirectReadingDBusInterface, mConnectionPtr};
mDirectReadingClient.addSignal<void(int32_t, std::string)>("ReadingStateChanged", [=](int32_t id, std::string readingState) {
}
});
- auto proxy = DBus::DBusClient{AtspiDbusNameRegistry, AtspiDbusPathRoot, AtspiDbusInterfaceSocket, mConnectionPtr};
+ auto proxy = DBus::DBusClient{AtspiDbusNameRegistry, AtspiDbusPathRoot, Accessible::GetInterfaceName(AtspiInterface::SOCKET), mConnectionPtr};
Address root{"", "root"};
auto res = proxy.method<Address(Address)>("Embed").call(root);
if(!res)
void BridgeObject::RegisterInterfaces()
{
- // DBus::DBusInterfaceDescription desc{ AtspiDbusInterfaceEventObject };
+ // DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT)};
// mStateChanged = addSignal<std::string, int, int, DBus::EldbusVariant<int>, Accessible*>(desc, "StateChanged");
// mDbusServer.addInterface("/", desc, true);
}
mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<Address>, Address>(
GetAccessiblePath(obj),
- AtspiDbusInterfaceEventObject,
+ Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
"ActiveDescendantChanged",
"",
index,
{
mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
GetAccessiblePath(obj),
- AtspiDbusInterfaceEventObject,
+ Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
"PropertyChange",
std::string{eventName->second},
0,
{
mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
GetAccessiblePath(obj),
- AtspiDbusInterfaceEventWindow,
+ Accessible::GetInterfaceName(AtspiInterface::EVENT_WINDOW),
std::string{eventName->second},
"",
detail,
{
mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
GetAccessiblePath(obj),
- AtspiDbusInterfaceEventObject,
+ Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
"StateChanged",
std::string{stateName->second},
newValue,
AddFilteredEvent(FilteredEvents::BOUNDS_CHANGED, obj, 1.0f, [=]() {
mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> >, Address>(
GetAccessiblePath(obj),
- AtspiDbusInterfaceEventObject,
+ Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
"BoundsChanged",
"",
0,
mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
GetAccessiblePath(obj),
- AtspiDbusInterfaceEventObject,
+ Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
"TextCaretMoved",
"",
cursorPosition,
{
mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::string>, Address>(
GetAccessiblePath(obj),
- AtspiDbusInterfaceEventObject,
+ Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
"TextChanged",
std::string{stateName->second},
position,
mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
GetAccessiblePath(obj),
- AtspiDbusInterfaceEventObject,
+ Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
"MoveOuted",
"",
static_cast<int>(type),
void BridgeSelection::RegisterInterfaces()
{
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceSelection};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::SELECTION)};
AddGetPropertyToInterface(desc, "NSelectedChildren", &BridgeSelection::GetSelectedChildrenCount);
AddFunctionToInterface(desc, "GetSelectedChild", &BridgeSelection::GetSelectedChild);
AddFunctionToInterface(desc, "SelectChild", &BridgeSelection::SelectChild);
Selection* BridgeSelection::FindSelf() const
{
- auto self = BridgeBase::FindSelf();
- assert(self);
- auto selectionInterface = dynamic_cast<Selection*>(self);
- if(!selectionInterface)
- {
- throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have Selection interface"};
- }
- return selectionInterface;
+ return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::SELECTION>();
}
DBus::ValueOrError<int32_t> BridgeSelection::GetSelectedChildrenCount()
// Screen Reader will call the methods with the exact names as specified in the AT-SPI Text interface:
// https://gitlab.gnome.org/GNOME/at-spi2-core/-/blob/master/xml/Text.xml
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceText};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::TEXT)};
AddFunctionToInterface(desc, "GetText", &BridgeText::GetText);
AddGetPropertyToInterface(desc, "CharacterCount", &BridgeText::GetCharacterCount);
AddGetPropertyToInterface(desc, "CaretOffset", &BridgeText::GetCursorOffset);
Text* BridgeText::FindSelf() const
{
- auto self = BridgeBase::FindSelf();
- assert(self);
- auto textInterface = dynamic_cast<Text*>(self);
- if(!textInterface)
- {
- throw std::domain_error{"Object " + self->GetAddress().ToString() + " doesn't have Text interface"};
- }
- return textInterface;
+ return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::TEXT>();
}
DBus::ValueOrError<std::string> BridgeText::GetText(int startOffset, int endOffset)
// CLASS HEADER
#include <dali/internal/accessibility/bridge/bridge-value.h>
-// EXTERNAL INCLUDES
-#include <iostream>
-
using namespace Dali::Accessibility;
BridgeValue::BridgeValue()
void BridgeValue::RegisterInterfaces()
{
- DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceValue};
+ DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::VALUE)};
AddGetSetPropertyToInterface(desc, "CurrentValue", &BridgeValue::GetCurrentValue, &BridgeValue::SetCurrentValue);
AddGetPropertyToInterface(desc, "MaximumValue", &BridgeValue::GetMaximumValue);
AddGetPropertyToInterface(desc, "MinimumIncrement", &BridgeValue::GetMinimumIncrement);
Value* BridgeValue::FindSelf() const
{
- auto self = BridgeBase::FindSelf();
- assert(self);
- auto valueInterface = dynamic_cast<Value*>(self);
- if(!valueInterface)
- {
- throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have Value interface"};
- }
- return valueInterface;
+ return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::VALUE>();
}
double BridgeValue::GetCurrentValue()
/*
- * 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.
int srcOffset = 0;
int destOffset = 0;
- float srcAlphaValue = 1.0f;
-
// if image is premultiplied, the other channels of the image need to multiply by alpha.
if(buffer.IsAlphaPreMultiplied())
{
- for(unsigned int row = 0; row < buffer.GetHeight(); ++row)
+ // Collect all valid channel list before lookup whole buffer
+ std::vector<Channel> validChannelList;
+ for(const Channel& channel : {Adaptor::RED, Adaptor::GREEN, Adaptor::BLUE, Adaptor::LUMINANCE, Adaptor::ALPHA})
{
- for(unsigned int col = 0; col < buffer.GetWidth(); ++col)
+ if(HasChannel(destPixelFormat, channel))
{
- auto srcAlpha = ReadChannel(srcBuffer + srcOffset, srcPixelFormat, Adaptor::ALPHA);
- auto destRed = ReadChannel(destBuffer + destOffset, destPixelFormat, Adaptor::RED);
- auto destGreen = ReadChannel(destBuffer + destOffset, destPixelFormat, Adaptor::GREEN);
- auto destBlue = ReadChannel(destBuffer + destOffset, destPixelFormat, Adaptor::BLUE);
- auto destLuminance = ReadChannel(destBuffer + destOffset, destPixelFormat, Adaptor::LUMINANCE);
- auto destAlpha = ReadChannel(destBuffer + destOffset, destPixelFormat, Adaptor::ALPHA);
-
- WriteChannel(destBuffer + destOffset, destPixelFormat, Adaptor::RED, destRed * srcAlpha / 255);
- WriteChannel(destBuffer + destOffset, destPixelFormat, Adaptor::GREEN, destGreen * srcAlpha / 255);
- WriteChannel(destBuffer + destOffset, destPixelFormat, Adaptor::BLUE, destBlue * srcAlpha / 255);
- WriteChannel(destBuffer + destOffset, destPixelFormat, Adaptor::LUMINANCE, destLuminance * srcAlpha / 255);
- WriteChannel(destBuffer + destOffset, destPixelFormat, Adaptor::ALPHA, destAlpha * srcAlpha / 255);
-
- srcOffset += srcBytesPerPixel;
- destOffset += destBytesPerPixel;
+ validChannelList.emplace_back(channel);
+ }
+ }
+ if(DALI_LIKELY(!validChannelList.empty()))
+ {
+ for(unsigned int row = 0; row < buffer.GetHeight(); ++row)
+ {
+ for(unsigned int col = 0; col < buffer.GetWidth(); ++col)
+ {
+ auto srcAlpha = srcBuffer[srcOffset + srcAlphaByteOffset] & srcAlphaMask;
+ if(srcAlpha < 255)
+ {
+ // If alpha is 255, we don't need to change color. Skip current pixel
+ // But if alpha is not 255, we should change color.
+ if(srcAlpha > 0)
+ {
+ for(const Channel& channel : validChannelList)
+ {
+ auto color = ReadChannel(destBuffer + destOffset, destPixelFormat, channel);
+ WriteChannel(destBuffer + destOffset, destPixelFormat, channel, color * srcAlpha / 255);
+ }
+ }
+ else
+ {
+ // If alpha is 0, just set all pixel as zero.
+ memset(destBuffer + destOffset, 0, destBytesPerPixel);
+ }
+ }
+
+ srcOffset += srcBytesPerPixel;
+ destOffset += destBytesPerPixel;
+ }
}
}
}
{
for(unsigned int col = 0; col < buffer.GetWidth(); ++col)
{
- unsigned char alpha = srcBuffer[srcOffset + srcAlphaByteOffset] & srcAlphaMask;
- srcAlphaValue = float(alpha) / 255.0f;
+ unsigned char srcAlpha = srcBuffer[srcOffset + srcAlphaByteOffset] & srcAlphaMask;
+ unsigned char destAlpha = destBuffer[destOffset + destAlphaByteOffset] & destAlphaMask;
+
+ destAlpha = (static_cast<std::uint16_t>(destAlpha) * static_cast<std::uint16_t>(srcAlpha)) / 255;
- unsigned char destAlpha = destBuffer[destOffset + destAlphaByteOffset] & destAlphaMask;
- float destAlphaValue = Clamp(float(destAlpha) * srcAlphaValue, 0.0f, 255.0f);
- destAlpha = destAlphaValue;
destBuffer[destOffset + destAlphaByteOffset] &= ~destAlphaMask;
destBuffer[destOffset + destAlphaByteOffset] |= (destAlpha & destAlphaMask);
int destOffset = 0;
bool hasAlpha = Dali::Pixel::HasAlpha(buffer.GetPixelFormat());
- float srcAlphaValue = 1.0f;
- unsigned char destAlpha = 0;
+ unsigned char destAlpha = 0;
for(unsigned int row = 0; row < buffer.GetHeight(); ++row)
{
for(unsigned int col = 0; col < buffer.GetWidth(); ++col)
{
- unsigned char alpha = srcBuffer[srcAlphaOffset + srcAlphaByteOffset] & srcAlphaMask;
- srcAlphaValue = float(alpha) / 255.0f;
+ unsigned char srcAlpha = srcBuffer[srcAlphaOffset + srcAlphaByteOffset] & srcAlphaMask;
ConvertColorChannelsToRGBA8888(oldBuffer, srcColorOffset, srcColorPixelFormat, destBuffer, destOffset);
if(hasAlpha)
{
- destAlpha = ConvertAlphaChannelToA8(oldBuffer, srcColorOffset, srcColorPixelFormat);
- float destAlphaValue = Clamp(float(destAlpha) * srcAlphaValue, 0.0f, 255.0f);
- destAlpha = destAlphaValue;
+ destAlpha = ConvertAlphaChannelToA8(oldBuffer, srcColorOffset, srcColorPixelFormat);
+ destAlpha = (static_cast<std::uint16_t>(destAlpha) * static_cast<std::uint16_t>(srcAlpha)) / 255;
}
else
{
- destAlpha = floorf(Clamp(srcAlphaValue * 255.0f, 0.0f, 255.0f));
+ destAlpha = srcAlpha;
}
destBuffer[destOffset + destAlphaByteOffset] &= ~destAlphaMask;
#define DALI_INTERNAL_ADAPTOR_ALPHA_MASK_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.
namespace Adaptor
{
/**
- * Apply the mask to a buffer's alpha channel
+ * @brief Apply the mask to a buffer's alpha channel
+ * @note It works well only if mask's alpha mask is 8bit
* @param[in] buffer The buffer to apply the mask to
* @param[in] mask The mask to apply
*/
void ApplyMaskToAlphaChannel(PixelBuffer& buffer, const PixelBuffer& mask);
/**
- * Create a new PixelBuffer with an alpha channel large enough to handle the alpha from
+ * @brief Create a new PixelBuffer with an alpha channel large enough to handle the alpha from
* the mask, converting the color values to the new size, and either multiplying the mask's
* alpha into the existing alpha value, or writing the mask's alpha value directly into
* the new buffer's alpha channel.
+ * @note It works well only if mask's alpha mask is 8bit
*
* @param[in] buffer The buffer to apply the mask to
* @param[in] mask The mask to apply
}
}
+// AverageScanline
+
+namespace
+{
/**
- * @ToDo: Optimise for ARM using a 4 bytes at a time loop wrapped around the single ARMV6 instruction: UHADD8 R4, R0, R5. Note, this is not neon. It runs in the normal integer pipeline so there is no downside like a stall moving between integer and copro, or extra power for clocking-up the idle copro.
- * if (widthInComponents >= 7) { word32* aligned1 = scanline1 + 3 & 3; word32* aligned1_end = scanline1 + widthInPixels & 3; while(aligned1 < aligned1_end) { UHADD8 *aligned1++, *aligned2++, *alignedoutput++ } .. + 0 to 3 spare pixels at each end.
+ * @copydoc AverageScanlines1
+ * @note This API average eight components in one operation.
+ * It will give performance benifit.
*/
+inline void AverageScanlinesWithEightComponents(
+ const unsigned char* const scanline1,
+ const unsigned char* const __restrict__ scanline2,
+ unsigned char* const outputScanline,
+ const unsigned int totalComponentCount)
+{
+ unsigned int component = 0;
+ if(DALI_LIKELY(totalComponentCount >= 8))
+ {
+ // Jump 8 components in one step
+ const std::uint64_t* const scanline18Step = reinterpret_cast<const std::uint64_t* const>(scanline1);
+ const std::uint64_t* const scanline28Step = reinterpret_cast<const std::uint64_t* const>(scanline2);
+ std::uint64_t* const output8step = reinterpret_cast<std::uint64_t* const>(outputScanline);
+
+ const std::uint32_t totalStepCount = (totalComponentCount) >> 3;
+ component = totalStepCount << 3;
+
+ // and for each step, calculate average of 8 bytes.
+ for(std::uint32_t i = 0; i < totalStepCount; ++i)
+ {
+ const auto& c1 = *(scanline18Step + i);
+ const auto& c2 = *(scanline28Step + i);
+ *(output8step + i) = static_cast<std::uint64_t>((((c1 ^ c2) & 0xfefefefefefefefeull) >> 1) + (c1 & c2));
+ }
+ }
+ // remaining components calculate
+ for(; component < totalComponentCount; ++component)
+ {
+ const auto& c1 = scanline1[component];
+ const auto& c2 = scanline2[component];
+ outputScanline[component] = static_cast<std::uint8_t>(((c1 ^ c2) >> 1) + (c1 & c2));
+ }
+}
+
+} // namespace
+
void AverageScanlines1(const unsigned char* const scanline1,
const unsigned char* const __restrict__ scanline2,
unsigned char* const outputScanline,
{
DebugAssertDualScanlineParameters(scanline1, scanline2, outputScanline, width);
- for(unsigned int component = 0; component < width; ++component)
- {
- outputScanline[component] = static_cast<unsigned char>(AverageComponent(scanline1[component], scanline2[component]));
- }
+ /**
+ * @code
+ * for(unsigned int component = 0; component < width; ++component)
+ * {
+ * outputScanline[component] = static_cast<unsigned char>(AverageComponent(scanline1[component], scanline2[component]));
+ * }
+ * @endcode
+ */
+ AverageScanlinesWithEightComponents(scanline1, scanline2, outputScanline, width);
}
void AverageScanlines2(const unsigned char* const scanline1,
{
DebugAssertDualScanlineParameters(scanline1, scanline2, outputScanline, width * 2);
- for(unsigned int component = 0; component < width * 2; ++component)
- {
- outputScanline[component] = static_cast<unsigned char>(AverageComponent(scanline1[component], scanline2[component]));
- }
+ /**
+ * @code
+ * for(unsigned int component = 0; component < width * 2; ++component)
+ * {
+ * outputScanline[component] = static_cast<unsigned char>(AverageComponent(scanline1[component], scanline2[component]));
+ * }
+ * @endcode
+ */
+ AverageScanlinesWithEightComponents(scanline1, scanline2, outputScanline, width * 2);
}
void AverageScanlines3(const unsigned char* const scanline1,
{
DebugAssertDualScanlineParameters(scanline1, scanline2, outputScanline, width * 3);
- for(unsigned int component = 0; component < width * 3; ++component)
- {
- outputScanline[component] = static_cast<unsigned char>(AverageComponent(scanline1[component], scanline2[component]));
- }
+ /**
+ * @code
+ * for(unsigned int component = 0; component < width * 3; ++component)
+ * {
+ * outputScanline[component] = static_cast<unsigned char>(AverageComponent(scanline1[component], scanline2[component]));
+ * }
+ * @endcode
+ */
+ AverageScanlinesWithEightComponents(scanline1, scanline2, outputScanline, width * 3);
}
void AverageScanlinesRGBA8888(const unsigned char* const scanline1,
{
const BoxDimensionTest dimensionTest = DimensionTestForScalingMode(fittingMode);
- if(pixelFormat == Pixel::RGBA8888)
- {
- Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, inputWidth, inputHeight, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight);
- }
- else if(pixelFormat == Pixel::RGB888)
- {
- Internal::Platform::DownscaleInPlacePow2RGB888(pixels, inputWidth, inputHeight, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight);
- }
- else if(pixelFormat == Pixel::RGB565)
- {
- Internal::Platform::DownscaleInPlacePow2RGB565(pixels, inputWidth, inputHeight, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight);
- }
- else if(pixelFormat == Pixel::LA88)
- {
- Internal::Platform::DownscaleInPlacePow2ComponentPair(pixels, inputWidth, inputHeight, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight);
- }
- else if(pixelFormat == Pixel::L8 || pixelFormat == Pixel::A8)
+ switch(pixelFormat)
{
- Internal::Platform::DownscaleInPlacePow2SingleBytePerPixel(pixels, inputWidth, inputHeight, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight);
- }
- else
- {
- DALI_ASSERT_DEBUG(false && "Inner branch conditions don't match outer branch.");
+ case Pixel::RGBA8888:
+ {
+ Internal::Platform::DownscaleInPlacePow2RGBA8888(pixels, inputWidth, inputHeight, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight);
+ break;
+ }
+ case Pixel::RGB888:
+ {
+ Internal::Platform::DownscaleInPlacePow2RGB888(pixels, inputWidth, inputHeight, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight);
+ break;
+ }
+ case Pixel::RGB565:
+ {
+ Internal::Platform::DownscaleInPlacePow2RGB565(pixels, inputWidth, inputHeight, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight);
+ break;
+ }
+ case Pixel::LA88:
+ {
+ Internal::Platform::DownscaleInPlacePow2ComponentPair(pixels, inputWidth, inputHeight, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight);
+ break;
+ }
+ case Pixel::L8:
+ case Pixel::A8:
+ {
+ Internal::Platform::DownscaleInPlacePow2SingleBytePerPixel(pixels, inputWidth, inputHeight, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight);
+ break;
+ }
+ default:
+ {
+ DALI_ASSERT_DEBUG(false && "Inner branch conditions don't match outer branch.");
+ }
}
}
}
DownscaleInPlacePow2Generic<1, HalveScanlineInPlace1Byte, AverageScanlines1>(pixels, inputWidth, inputHeight, desiredWidth, desiredHeight, dimensionTest, outWidth, outHeight);
}
+// Point sampling group below
+
namespace
{
/**
// Check the pixel format is one that is supported:
if(pixelFormat == Pixel::RGBA8888 || pixelFormat == Pixel::RGB888 || pixelFormat == Pixel::RGB565 || pixelFormat == Pixel::LA88 || pixelFormat == Pixel::L8 || pixelFormat == Pixel::A8)
{
- if(pixelFormat == Pixel::RGB888)
+ switch(pixelFormat)
{
- PointSample3BPP(inPixels, inputWidth, inputHeight, outPixels, desiredWidth, desiredHeight);
- }
- else if(pixelFormat == Pixel::RGBA8888)
- {
- PointSample4BPP(inPixels, inputWidth, inputHeight, outPixels, desiredWidth, desiredHeight);
- }
- else if(pixelFormat == Pixel::RGB565 || pixelFormat == Pixel::LA88)
- {
- PointSample2BPP(inPixels, inputWidth, inputHeight, outPixels, desiredWidth, desiredHeight);
- }
- else if(pixelFormat == Pixel::L8 || pixelFormat == Pixel::A8)
- {
- PointSample1BPP(inPixels, inputWidth, inputHeight, outPixels, desiredWidth, desiredHeight);
- }
- else
- {
- DALI_ASSERT_DEBUG(0 == "Inner branch conditions don't match outer branch.");
+ case Pixel::RGB888:
+ {
+ PointSample3BPP(inPixels, inputWidth, inputHeight, outPixels, desiredWidth, desiredHeight);
+ break;
+ }
+ case Pixel::RGBA8888:
+ {
+ PointSample4BPP(inPixels, inputWidth, inputHeight, outPixels, desiredWidth, desiredHeight);
+ break;
+ }
+ case Pixel::RGB565:
+ case Pixel::LA88:
+ {
+ PointSample2BPP(inPixels, inputWidth, inputHeight, outPixels, desiredWidth, desiredHeight);
+ break;
+ }
+ case Pixel::L8:
+ case Pixel::A8:
+ {
+ PointSample1BPP(inPixels, inputWidth, inputHeight, outPixels, desiredWidth, desiredHeight);
+ break;
+ }
+ default:
+ {
+ DALI_ASSERT_DEBUG(0 == "Inner branch conditions don't match outer branch.");
+ }
}
}
else
// Check the pixel format is one that is supported:
if(pixelFormat == Pixel::RGB888 || pixelFormat == Pixel::RGBA8888 || pixelFormat == Pixel::L8 || pixelFormat == Pixel::A8 || pixelFormat == Pixel::LA88 || pixelFormat == Pixel::RGB565)
{
- if(pixelFormat == Pixel::RGB888)
- {
- LinearSample3BPP(inPixels, inDimensions, outPixels, outDimensions);
- }
- else if(pixelFormat == Pixel::RGBA8888)
- {
- LinearSample4BPP(inPixels, inDimensions, outPixels, outDimensions);
- }
- else if(pixelFormat == Pixel::L8 || pixelFormat == Pixel::A8)
- {
- LinearSample1BPP(inPixels, inDimensions, outPixels, outDimensions);
- }
- else if(pixelFormat == Pixel::LA88)
+ switch(pixelFormat)
{
- LinearSample2BPP(inPixels, inDimensions, outPixels, outDimensions);
- }
- else if(pixelFormat == Pixel::RGB565)
- {
- LinearSampleRGB565(inPixels, inDimensions, outPixels, outDimensions);
- }
- else
- {
- DALI_ASSERT_DEBUG(0 == "Inner branch conditions don't match outer branch.");
+ case Pixel::RGB888:
+ {
+ LinearSample3BPP(inPixels, inDimensions, outPixels, outDimensions);
+ break;
+ }
+ case Pixel::RGBA8888:
+ {
+ LinearSample4BPP(inPixels, inDimensions, outPixels, outDimensions);
+ break;
+ }
+ case Pixel::L8:
+ case Pixel::A8:
+ {
+ LinearSample1BPP(inPixels, inDimensions, outPixels, outDimensions);
+ break;
+ }
+ case Pixel::LA88:
+ {
+ LinearSample2BPP(inPixels, inDimensions, outPixels, outDimensions);
+ break;
+ }
+ case Pixel::RGB565:
+ {
+ LinearSampleRGB565(inPixels, inDimensions, outPixels, outDimensions);
+ break;
+ }
+ default:
+ {
+ DALI_ASSERT_DEBUG(0 == "Inner branch conditions don't match outer branch.");
+ }
}
}
else
inline unsigned int WeightedBlendIntToFixed1616(unsigned int a, unsigned int b, unsigned int fractBlend)
{
DALI_ASSERT_DEBUG(fractBlend <= 65535u && "Factor should be in 0.16 fixed-point.");
- const unsigned int weightedAFixed = a * (65535u - fractBlend);
- const unsigned int weightedBFixed = b * fractBlend;
- const unsigned blended = (weightedAFixed + weightedBFixed);
+ /**
+ * @code
+ * const unsigned int weightedAFixed = a * (65535u - fractBlend);
+ * const unsigned int weightedBFixed = b * fractBlend;
+ * const unsigned blended = (weightedAFixed + weightedBFixed);
+ * @endcode
+ */
+ const unsigned int blended = (a << 16) - a + (static_cast<int32_t>(b) - static_cast<int32_t>(a)) * fractBlend;
return blended;
}
inline uint64_t WeightedBlendFixed1616ToFixed1632(unsigned int a, unsigned int b, unsigned int fractBlend)
{
DALI_ASSERT_DEBUG(fractBlend <= 65535u && "Factor should be in 0.16 fixed-point.");
- // Blend while promoting intermediates to 16.32 fixed point:
- const uint64_t weightedAFixed = uint64_t(a) * (65535u - fractBlend);
- const uint64_t weightedBFixed = uint64_t(b) * fractBlend;
- const uint64_t blended = (weightedAFixed + weightedBFixed);
+ /**
+ * @code
+ * // Blend while promoting intermediates to 16.32 fixed point:
+ * const uint64_t weightedAFixed = uint64_t(a) * (65535u - fractBlend);
+ * const uint64_t weightedBFixed = uint64_t(b) * fractBlend;
+ * const uint64_t blended = (weightedAFixed + weightedBFixed);
+ * @endcode
+ */
+ const uint64_t blended = (static_cast<uint64_t>(a) << 16) - a + (static_cast<int64_t>(b) - static_cast<int64_t>(a)) * fractBlend;
return blended;
}
DALI_ASSERT_DEBUG(fractBlendHorizontal <= 65535u && "Factor should be in 0.16 fixed-point.");
DALI_ASSERT_DEBUG(fractBlendVertical <= 65535u && "Factor should be in 0.16 fixed-point.");
- const unsigned int topBlend = WeightedBlendIntToFixed1616(tl, tr, fractBlendHorizontal);
- const unsigned int botBlend = WeightedBlendIntToFixed1616(bl, br, fractBlendHorizontal);
- const uint64_t blended2x2 = WeightedBlendFixed1616ToFixed1632(topBlend, botBlend, fractBlendVertical);
+ /**
+ * @code
+ * const unsigned int topBlend = WeightedBlendIntToFixed1616(tl, tr, fractBlendHorizontal);
+ * const unsigned int botBlend = WeightedBlendIntToFixed1616(bl, br, fractBlendHorizontal);
+ * const uint64_t blended2x2 = WeightedBlendFixed1616ToFixed1632(topBlend, botBlend, fractBlendVertical);
+ * const unsigned int rounded = (blended2x2 + (1u << 31u)) >> 32u;
+ * @endcode
+ */
+
+ /**
+ * Hard-coding optimize!
+ *
+ * Let p = 65536, s.t we can optimze it as << 16.
+ * Let x = fractBlendHorizontal, y = fractBlendVertical.
+ * topBlend = (tl*p - tl - tl*x + tr*x)
+ * botBlend = (bl*p - bl - bl*x + br*x)
+ * blended2x2 = topBlend*p - topBlend - topBlend*y + botBlend*y
+ *
+ * And now we can split all values.
+ * tl*p*p - tl*p - tl*x*p + tr*x*p - tl*p + tl + tl*x - tr*x - tl*y*p + tl*y + tl*x*y - tr*x*y + bl*y*p - bl*y - bl*x*y + br*x*y;
+ * --> (collect by p, x, and y)
+ * (tl)*p*p + (-2tl + (-tl + tr)*x + (-tl+bl)*y)*p + tl + (tl - tr)*x + (tl - bl)*y + (tl - tr - bl + br)*x*y
+ *
+ * A = (tl - tr) * x;
+ * B = (tl - bl) * y;
+ * C = (tl - tr - bl + br) * x * y;
+ * D = (2*tl + A + B)
+ * -->
+ * (tl << 32) - (D << 16) + tl + A + B + C
+ *
+ * Becareful of overflow and negative value.
+ */
+ const int32_t A = (static_cast<int32_t>(tl) - static_cast<int32_t>(tr)) * static_cast<int32_t>(fractBlendHorizontal);
+ const int32_t B = (static_cast<int32_t>(tl) - static_cast<int32_t>(bl)) * static_cast<int32_t>(fractBlendVertical);
+ const int64_t C = (static_cast<int64_t>(tl) - static_cast<int64_t>(tr) - static_cast<int64_t>(bl) + static_cast<int64_t>(br)) * static_cast<int64_t>(fractBlendHorizontal) * static_cast<int64_t>(fractBlendVertical);
+ const int64_t D = ((static_cast<int64_t>(tl) << 1) + A + B);
+
+ const uint64_t blended2x2 = (static_cast<int64_t>(tl) << 32u) - (D << 16u) + tl + A + B + C;
const unsigned int rounded = (blended2x2 + (1u << 31u)) >> 32u;
return rounded;
}
unsigned char* pixel = mBuffer;
const unsigned int bufferSize = mWidth * mHeight;
- for(unsigned int i = 0; i < bufferSize; ++i)
+ // Collect all valid channel list before lookup whole buffer
+ std::vector<Channel> validChannelList;
+ for(const Channel& channel : {Adaptor::RED, Adaptor::GREEN, Adaptor::BLUE, Adaptor::LUMINANCE})
{
- unsigned int alpha = ReadChannel(pixel, mPixelFormat, Adaptor::ALPHA);
- if(alpha < 255)
+ if(HasChannel(mPixelFormat, channel))
{
- // If alpha is 255, we don't need to change color. Skip current pixel
- // But if alpha is not 255, we should change color.
- if(alpha > 0)
- {
- auto red = ReadChannel(pixel, mPixelFormat, Adaptor::RED);
- auto green = ReadChannel(pixel, mPixelFormat, Adaptor::GREEN);
- auto blue = ReadChannel(pixel, mPixelFormat, Adaptor::BLUE);
- auto luminance = ReadChannel(pixel, mPixelFormat, Adaptor::LUMINANCE);
- WriteChannel(pixel, mPixelFormat, Adaptor::RED, red * alpha / 255);
- WriteChannel(pixel, mPixelFormat, Adaptor::GREEN, green * alpha / 255);
- WriteChannel(pixel, mPixelFormat, Adaptor::BLUE, blue * alpha / 255);
- WriteChannel(pixel, mPixelFormat, Adaptor::LUMINANCE, luminance * alpha / 255);
- }
- else
+ validChannelList.emplace_back(channel);
+ }
+ }
+
+ if(DALI_LIKELY(!validChannelList.empty()))
+ {
+ for(unsigned int i = 0; i < bufferSize; ++i)
+ {
+ unsigned int alpha = ReadChannel(pixel, mPixelFormat, Adaptor::ALPHA);
+ if(alpha < 255)
{
- // If alpha is 0, just set all pixel as zero.
- memset(pixel, 0, bytesPerPixel);
+ // If alpha is 255, we don't need to change color. Skip current pixel
+ // But if alpha is not 255, we should change color.
+ if(alpha > 0)
+ {
+ for(const Channel& channel : validChannelList)
+ {
+ auto color = ReadChannel(pixel, mPixelFormat, channel);
+ WriteChannel(pixel, mPixelFormat, channel, color * alpha / 255);
+ }
+ }
+ else
+ {
+ // If alpha is 0, just set all pixel as zero.
+ memset(pixel, 0, bytesPerPixel);
+ }
}
+ pixel += bytesPerPixel;
}
- pixel += bytesPerPixel;
}
}
mPreMultiplied = true;
/*
- * 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.
{
namespace
{
-constexpr Channel ALPHA_CHANNEL_ONLY[] = {ALPHA};
-constexpr Channel LUMINANCE_CHANNEL_ONLY[] = {LUMINANCE};
-constexpr Channel LUMINANCE_ALPHA_CHANNELS[] = {LUMINANCE, ALPHA};
-constexpr Channel RGB_CHANNELS[] = {RED, GREEN, BLUE};
-constexpr Channel BGR_CHANNELS[] = {BLUE, GREEN, RED};
-constexpr Channel RGBA_CHANNELS[] = {RED, GREEN, BLUE, ALPHA};
-constexpr Channel BGRA_CHANNELS[] = {BLUE, GREEN, RED, ALPHA};
+// clang-format off
+/**
+ * @brief Pre-defined offset tables for each Channel.
+ * If invalid channel, return -1. else, return the offset bytes.
+ */
+// | LUMINANCE | RED | GREEN | BLUE | ALPHA | DEPTH | STENCIL |
+constexpr std::int8_t ALPHA_ONLY_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { -1 , -1 , -1 , -1 , 0 , -1 , -1 };
+constexpr std::int8_t LUMINANCE_ONLY_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { 0 , -1 , -1 , -1 , -1 , -1 , -1 };
+constexpr std::int8_t LUMINANCE_ALPHA_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { 0 , -1 , -1 , -1 , 1 , -1 , -1 };
+constexpr std::int8_t RGB_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { -1 , 0 , 1 , 2 , -1 , -1 , -1 };
+constexpr std::int8_t BGR_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { -1 , 2 , 1 , 0 , -1 , -1 , -1 };
+constexpr std::int8_t RGBA_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { -1 , 0 , 1 , 2 , 3 , -1 , -1 };
+constexpr std::int8_t BGRA_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = { -1 , 2 , 1 , 0 , 3 , -1 , -1 };
+// clang-format on
/**
* @brief Template to Read from a buffer with pixel formats that have one byte per channel.
* @tparam NumberOfChannels The number of channels to check
* @param pixelData The pixel data to retrieve the value from
* @param channel The channel we're after
- * @param channels The array of channels in the pixel format
+ * @param offsetTable The array of offset bytes for each channels in the pixel format
* @return The value of the required channel
*/
-template<size_t NumberOfChannels>
-unsigned int ReadChannel(unsigned char* pixelData, Channel channel, const Channel (&channels)[NumberOfChannels])
+unsigned int ReadChannelTable(unsigned char* pixelData, Channel channel, const std::int8_t (&offsetTable)[MAX_NUMBER_OF_CHANNELS])
{
- auto num = 0u;
auto retVal = 0u;
- for(auto current : channels)
+ if(offsetTable[channel] >= 0)
{
- if(channel == current)
- {
- retVal = static_cast<unsigned int>(*(pixelData + num));
- break;
- }
- ++num;
+ retVal = static_cast<unsigned int>(*(pixelData + offsetTable[channel]));
}
return retVal;
}
* @param pixelData The pixel data to write the value to
* @param channel The channel we're after
* @param channelValue The value of the channel to set
- * @param channels The array of channels in the pixel format
+ * @param offsetTable The array of offset bytes for each channels in the pixel format
*/
-template<size_t NumberOfChannels>
-void WriteChannel(unsigned char* pixelData, Channel channel, unsigned int channelValue, const Channel (&channels)[NumberOfChannels])
+void WriteChannelTable(unsigned char* pixelData, Channel channel, unsigned int channelValue, const std::int8_t (&offsetTable)[MAX_NUMBER_OF_CHANNELS])
{
- auto num = 0u;
- for(auto current : channels)
+ if(offsetTable[channel] >= 0)
{
- if(channel == current)
- {
- *(pixelData + num) = static_cast<unsigned char>(channelValue & 0xFF);
- break;
- }
- ++num;
+ *(pixelData + offsetTable[channel]) = static_cast<unsigned char>(channelValue & 0xFF);
}
}
{
case Dali::Pixel::A8:
{
- return ReadChannel(pixelData, channel, ALPHA_CHANNEL_ONLY);
+ return ReadChannelTable(pixelData, channel, ALPHA_ONLY_OFFSET_TABLE);
}
case Dali::Pixel::L8:
{
- return ReadChannel(pixelData, channel, LUMINANCE_CHANNEL_ONLY);
+ return ReadChannelTable(pixelData, channel, LUMINANCE_ONLY_OFFSET_TABLE);
}
case Dali::Pixel::LA88:
{
- return ReadChannel(pixelData, channel, LUMINANCE_ALPHA_CHANNELS);
+ return ReadChannelTable(pixelData, channel, LUMINANCE_ALPHA_OFFSET_TABLE);
}
case Dali::Pixel::RGB565:
{
case Dali::Pixel::RGB888:
case Dali::Pixel::RGB8888:
{
- return ReadChannel(pixelData, channel, RGB_CHANNELS);
+ return ReadChannelTable(pixelData, channel, RGB_OFFSET_TABLE);
}
case Dali::Pixel::BGR8888:
{
- return ReadChannel(pixelData, channel, BGR_CHANNELS);
+ return ReadChannelTable(pixelData, channel, BGR_OFFSET_TABLE);
}
case Dali::Pixel::RGBA8888:
{
- return ReadChannel(pixelData, channel, RGBA_CHANNELS);
+ return ReadChannelTable(pixelData, channel, RGBA_OFFSET_TABLE);
}
case Dali::Pixel::BGRA8888:
{
- return ReadChannel(pixelData, channel, BGRA_CHANNELS);
+ return ReadChannelTable(pixelData, channel, BGRA_OFFSET_TABLE);
}
case Dali::Pixel::RGBA4444:
{
case Dali::Pixel::A8:
{
- WriteChannel(pixelData, channel, channelValue, ALPHA_CHANNEL_ONLY);
+ WriteChannelTable(pixelData, channel, channelValue, ALPHA_ONLY_OFFSET_TABLE);
break;
}
case Dali::Pixel::L8:
{
- WriteChannel(pixelData, channel, channelValue, LUMINANCE_CHANNEL_ONLY);
+ WriteChannelTable(pixelData, channel, channelValue, LUMINANCE_ONLY_OFFSET_TABLE);
break;
}
case Dali::Pixel::LA88:
{
- WriteChannel(pixelData, channel, channelValue, LUMINANCE_ALPHA_CHANNELS);
+ WriteChannelTable(pixelData, channel, channelValue, LUMINANCE_ALPHA_OFFSET_TABLE);
break;
}
case Dali::Pixel::RGB565:
case Dali::Pixel::RGB888:
case Dali::Pixel::RGB8888:
{
- WriteChannel(pixelData, channel, channelValue, RGB_CHANNELS);
+ WriteChannelTable(pixelData, channel, channelValue, RGB_OFFSET_TABLE);
break;
}
case Dali::Pixel::BGR8888:
{
- WriteChannel(pixelData, channel, channelValue, BGR_CHANNELS);
+ WriteChannelTable(pixelData, channel, channelValue, BGR_OFFSET_TABLE);
break;
}
case Dali::Pixel::RGBA8888:
{
- WriteChannel(pixelData, channel, channelValue, RGBA_CHANNELS);
+ WriteChannelTable(pixelData, channel, channelValue, RGBA_OFFSET_TABLE);
break;
}
case Dali::Pixel::BGRA8888:
{
- WriteChannel(pixelData, channel, channelValue, BGRA_CHANNELS);
+ WriteChannelTable(pixelData, channel, channelValue, BGRA_OFFSET_TABLE);
break;
}
{
const unsigned int ADAPTOR_MAJOR_VERSION = 2;
const unsigned int ADAPTOR_MINOR_VERSION = 1;
-const unsigned int ADAPTOR_MICRO_VERSION = 11;
+const unsigned int ADAPTOR_MICRO_VERSION = 12;
const char* const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-adaptor
Summary: The DALi Tizen Adaptor
-Version: 2.1.11
+Version: 2.1.12
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT