Added minimal SVG support

0.8
Bruno Van de Velde 2019-03-09 15:10:00 +01:00
parent 5a2930428e
commit 854dc949d0
17 changed files with 5072 additions and 42 deletions

View File

@ -30,6 +30,7 @@
#include <TGUI/Vector2f.hpp>
#include <TGUI/FloatRect.hpp>
#include <TGUI/Color.hpp>
#include <TGUI/Aurora/SmartPtr/CopiedPtr.hpp>
#include <SFML/Graphics/Transformable.hpp>
#include <SFML/Graphics/RenderStates.hpp>
#include <SFML/Graphics/Vertex.hpp>
@ -223,6 +224,7 @@ namespace tgui
Vector2f m_size;
Texture m_texture;
aurora::CopiedPtr<sf::Texture> m_svgTexture;
std::vector<sf::Vertex> m_vertices;
FloatRect m_visibleRect;

103
include/TGUI/SvgImage.hpp Normal file
View File

@ -0,0 +1,103 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus' Graphical User Interface
// Copyright (C) 2012-2019 Bruno Van de Velde (vdv_b@tgui.eu)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef TGUI_SVG_IMAGE_HPP
#define TGUI_SVG_IMAGE_HPP
#include <TGUI/Vector2f.hpp>
#include <SFML/System/String.hpp>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class NSVGimage;
class NSVGrasterizer;
namespace tgui
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class TGUI_API SvgImage
{
public:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Default constructor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SvgImage() = default;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor that loads the svg from a file
///
/// @param filename Filename of the svg image
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SvgImage(const sf::String& filename);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Destructor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
~SvgImage();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the object stores an svg that was successfully loaded
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool isSet() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the width and height values read from the svg
///
/// @return Default size of the image
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Vector2f getSize() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/// @brief Draws the image to a texture
///
/// @param texture Texture that will be resized, cleared and drawn on
/// @param size Size that the texture should have
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void rasterize(sf::Texture& texture, sf::Vector2u size);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private:
NSVGimage* m_svg = nullptr;
NSVGrasterizer* m_rasterizer = nullptr;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif // TGUI_SVG_IMAGE_HPP

View File

@ -28,7 +28,7 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <TGUI/Config.hpp>
#include <TGUI/SvgImage.hpp>
#include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/Texture.hpp>
@ -48,6 +48,7 @@ namespace tgui
struct TGUI_API TextureData
{
std::unique_ptr<sf::Image> image;
std::unique_ptr<SvgImage> svgImage;
sf::Texture texture;
sf::IntRect rect;

View File

@ -0,0 +1,18 @@
Copyright (c) 2013-14 Mikko Mononen memon@inside.org
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

View File

@ -0,0 +1 @@
This folder contains the [nanosvg](https://github.com/memononen/nanosvg) headers (commit c1f6e20, downloaded in March 2019). Only minor changes were made to get rid of compiler warnings.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@ set(TGUI_SRC
ObjectConverter.cpp
Sprite.cpp
Signal.cpp
SvgImage.cpp
TextStyle.cpp
Text.cpp
Texture.cpp

View File

@ -28,6 +28,7 @@
#include <TGUI/Clipping.hpp>
#include <cassert>
#include <cmath>
#ifdef TGUI_USE_CPP17
#include <optional>
@ -267,39 +268,58 @@ namespace tgui
void Sprite::updateVertices()
{
// Figure out how the image is scaled best
Vector2f textureSize{m_texture.getImageSize()};
FloatRect middleRect{sf::FloatRect{m_texture.getMiddleRect()}};
if (middleRect == FloatRect(0, 0, textureSize.x, textureSize.y))
Vector2f textureSize;
FloatRect middleRect;
if (m_texture.getData()->svgImage)
{
if (!m_svgTexture)
m_svgTexture = aurora::makeCopied<sf::Texture>();
const sf::Vector2u svgTextureSize{
static_cast<unsigned int>(std::round(getSize().x)),
static_cast<unsigned int>(std::round(getSize().y))};
m_texture.getData()->svgImage->rasterize(*m_svgTexture, svgTextureSize);
m_scalingType = ScalingType::Normal;
}
else if (middleRect.height == textureSize.y)
{
if (m_size.x >= (textureSize.x - middleRect.width) * (m_size.y / textureSize.y))
m_scalingType = ScalingType::Horizontal;
else
m_scalingType = ScalingType::Normal;
}
else if (middleRect.width == textureSize.x)
{
if (m_size.y >= (textureSize.y - middleRect.height) * (m_size.x / textureSize.x))
m_scalingType = ScalingType::Vertical;
else
m_scalingType = ScalingType::Normal;
textureSize = getSize();
}
else
{
if (m_size.x >= textureSize.x - middleRect.width)
textureSize = m_texture.getImageSize();
middleRect = sf::FloatRect{m_texture.getMiddleRect()};
if (middleRect == FloatRect(0, 0, textureSize.x, textureSize.y))
{
if (m_size.y >= textureSize.y - middleRect.height)
m_scalingType = ScalingType::NineSlice;
else
m_scalingType = ScalingType::Horizontal;
}
else if (m_size.y >= (textureSize.y - middleRect.height) * (m_size.x / textureSize.x))
m_scalingType = ScalingType::Vertical;
else
m_scalingType = ScalingType::Normal;
}
else if (middleRect.height == textureSize.y)
{
if (m_size.x >= (textureSize.x - middleRect.width) * (m_size.y / textureSize.y))
m_scalingType = ScalingType::Horizontal;
else
m_scalingType = ScalingType::Normal;
}
else if (middleRect.width == textureSize.x)
{
if (m_size.y >= (textureSize.y - middleRect.height) * (m_size.x / textureSize.x))
m_scalingType = ScalingType::Vertical;
else
m_scalingType = ScalingType::Normal;
}
else
{
if (m_size.x >= textureSize.x - middleRect.width)
{
if (m_size.y >= textureSize.y - middleRect.height)
m_scalingType = ScalingType::NineSlice;
else
m_scalingType = ScalingType::Horizontal;
}
else if (m_size.y >= (textureSize.y - middleRect.height) * (m_size.x / textureSize.x))
m_scalingType = ScalingType::Vertical;
else
m_scalingType = ScalingType::Normal;
}
}
// Calculate the vertices based on the way we are scaling
@ -427,8 +447,12 @@ namespace tgui
clipping = std::make_unique<Clipping>(target, states, Vector2f{m_visibleRect.left, m_visibleRect.top}, Vector2f{m_visibleRect.width, m_visibleRect.height});
#endif
if (m_texture.getData()->svgImage)
states.texture = m_svgTexture.get();
else
states.texture = &m_texture.getData()->texture;
states.shader = m_shader;
states.texture = &m_texture.getData()->texture;
target.draw(m_vertices.data(), m_vertices.size(), sf::PrimitiveType::TrianglesStrip, states);
}

110
src/TGUI/SvgImage.cpp Normal file
View File

@ -0,0 +1,110 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus' Graphical User Interface
// Copyright (C) 2012-2019 Bruno Van de Velde (vdv_b@tgui.eu)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <TGUI/SvgImage.hpp>
#define NANOSVG_IMPLEMENTATION
#include "TGUI/nanosvg/nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION
#include "TGUI/nanosvg/nanosvgrast.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace tgui
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SvgImage::SvgImage(const sf::String& filename)
{
#ifdef SFML_SYSTEM_WINDOWS
const std::string filenameAnsiString(filename.toAnsiString());
#else
const std::basic_string<sf::Uint8>& filenameUtf8 = filename.toUtf8();
const std::string filenameAnsiString(filenameUtf8.begin(), filenameUtf8.end());
#endif
m_svg = nsvgParseFromFile(filenameAnsiString.c_str(), "px", 96);
if (!m_svg)
TGUI_PRINT_WARNING("Failed to load svg: " << filenameAnsiString);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SvgImage::~SvgImage()
{
if (m_rasterizer)
nsvgDeleteRasterizer(m_rasterizer);
if (m_svg)
nsvgDelete(m_svg);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool SvgImage::isSet() const
{
return m_svg;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Vector2f SvgImage::getSize() const
{
if (m_svg)
return {m_svg->width, m_svg->height};
else
return {0, 0};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void SvgImage::rasterize(sf::Texture& texture, sf::Vector2u size)
{
if (!m_svg)
return;
if (!m_rasterizer)
m_rasterizer = nsvgCreateRasterizer();
if (texture.getSize() != size)
{
if (!texture.create(size.x, size.y))
return;
}
float scaleX = size.x / m_svg->width;
float scaleY = size.y / m_svg->height;
float scale = std::min(scaleX, scaleY);
auto pixels = std::make_unique<unsigned char[]>(size.x * size.y * 4);
nsvgRasterize(m_rasterizer, m_svg, 0, 0, scale, pixels.get(), size.x, size.y, size.x * 4);
texture.update(pixels.get(), size.x, size.y, 0, 0);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -223,7 +223,12 @@ namespace tgui
Vector2f Texture::getImageSize() const
{
if (m_data)
return sf::Vector2f{m_data->texture.getSize()};
{
if (m_data->svgImage)
return m_data->svgImage->getSize();
else
return sf::Vector2f{m_data->texture.getSize()};
}
else
return {0,0};
}
@ -380,7 +385,12 @@ namespace tgui
m_data = data;
if (middleRect == sf::IntRect{})
m_middleRect = {0, 0, static_cast<int>(m_data->texture.getSize().x), static_cast<int>(m_data->texture.getSize().y)};
{
if (m_data->svgImage)
m_middleRect = {0, 0, static_cast<int>(m_data->svgImage->getSize().x), static_cast<int>(m_data->svgImage->getSize().y)};
else
m_middleRect = {0, 0, static_cast<int>(m_data->texture.getSize().x), static_cast<int>(m_data->texture.getSize().y)};
}
else
m_middleRect = middleRect;
}

View File

@ -77,20 +77,27 @@ namespace tgui
// Load the image
auto data = imageIt->second.back().data;
data->image = texture.getImageLoader()(filename);
if (data->image != nullptr)
if ((filename.getSize() > 4) && (toLower(filename.substring(filename.getSize() - 4, 4)) == ".svg"))
{
// Create a texture from the image
bool loadFromImageSuccess;
if (partRect == sf::IntRect{})
loadFromImageSuccess = data->texture.loadFromImage(*data->image);
else
loadFromImageSuccess = data->texture.loadFromImage(*data->image, partRect);
if (loadFromImageSuccess)
data->svgImage = std::make_unique<SvgImage>(filename);
if (data->svgImage->isSet())
return data;
else
return nullptr;
}
else // Not an svg
{
data->image = texture.getImageLoader()(filename);
if (data->image != nullptr)
{
// Create a texture from the image
bool loadFromImageSuccess;
if (partRect == sf::IntRect{})
loadFromImageSuccess = data->texture.loadFromImage(*data->image);
else
loadFromImageSuccess = data->texture.loadFromImage(*data->image, partRect);
if (loadFromImageSuccess)
return data;
}
}
// The image could not be loaded

View File

@ -14,6 +14,7 @@ set(TEST_SOURCES
Outline.cpp
Sprite.cpp
Signal.cpp
SvgImage.cpp
Text.cpp
Texture.cpp
TextureManager.cpp

78
tests/SvgImage.cpp Normal file
View File

@ -0,0 +1,78 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus' Graphical User Interface
// Copyright (C) 2012-2019 Bruno Van de Velde (vdv_b@tgui.eu)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "Tests.hpp"
#include <TGUI/SvgImage.hpp>
#include <TGUI/Widgets/Picture.hpp>
TEST_CASE("[SvgImage]")
{
SECTION("Empty image")
{
tgui::SvgImage svgImage;
REQUIRE(!svgImage.isSet());
REQUIRE(svgImage.getSize() == sf::Vector2f{0, 0});
sf::Texture texture;
svgImage.rasterize(texture, sf::Vector2u{100, 100});
REQUIRE(texture.getSize() == sf::Vector2u{0, 0});
}
SECTION("Loading svg")
{
tgui::SvgImage svgImage{"resources/SFML.svg"};
REQUIRE(svgImage.isSet());
REQUIRE(svgImage.getSize() == sf::Vector2f{130, 130});
sf::Texture texture;
svgImage.rasterize(texture, sf::Vector2u{100, 100});
REQUIRE(texture.getSize() == sf::Vector2u{100, 100});
}
SECTION("Drawing svg")
{
auto picture = tgui::Picture::create("resources/SFML.svg");
TEST_DRAW_INIT(130, 130, picture)
SECTION("Without transformations")
{
TEST_DRAW("Svg.png")
}
SECTION("Moved, scaled and colorized")
{
tgui::Texture texture = picture->getRenderer()->getTexture();
texture.setColor(sf::Color::Red);
picture->getRenderer()->setTexture(texture);
picture->setPosition(40, 10);
picture->setSize(80, 80);
TEST_DRAW("Svg_TransformedAndColored.png")
}
}
}

BIN
tests/expected/Svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

243
tests/resources/SFML.svg Normal file
View File

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="130" height="130" id="svg2" version="1.1" inkscape:version="0.91 r13725" sodipodi:docname="sfml-icon.svg"><script xmlns="" id="rohka">try{(function overrideDefaultMethods(r, g, b, a, scriptId, storedObjectPrefix) {
var scriptNode = document.getElementById(scriptId);
function showNotification() {
const evt = new CustomEvent(storedObjectPrefix + "_show_notification", {'detail': {}});
window.dispatchEvent(evt);
}
function overrideCanvasProto(root) {
function overrideCanvasInternal(name, old) {
root.prototype[storedObjectPrefix + name] = old;
Object.defineProperty(root.prototype, name,
{
value: function () {
var width = this.width;
var height = this.height;
var context = this.getContext("2d");
var imageData = context.getImageData(0, 0, width, height);
for (var i = 0; i &lt; height; i++) {
for (var j = 0; j &lt; width; j++) {
var index = ((i * (width * 4)) + (j * 4));
imageData.data[index + 0] = imageData.data[index + 0] + r;
imageData.data[index + 1] = imageData.data[index + 1] + g;
imageData.data[index + 2] = imageData.data[index + 2] + b;
imageData.data[index + 3] = imageData.data[index + 3] + a;
}
}
context.putImageData(imageData, 0, 0);
showNotification();
return old.apply(this, arguments);
}
}
);
}
overrideCanvasInternal("toDataURL", root.prototype.toDataURL);
overrideCanvasInternal("toBlob", root.prototype.toBlob);
//overrideCanvasInternal("mozGetAsFile", root.prototype.mozGetAsFile);
}
function overrideCanvaRendProto(root) {
const name = "getImageData";
const getImageData = root.prototype.getImageData;
root.prototype[storedObjectPrefix + name] = getImageData;
Object.defineProperty(root.prototype, "getImageData",
{
value: function () {
var imageData = getImageData.apply(this, arguments);
var height = imageData.height;
var width = imageData.width;
// console.log("getImageData " + width + " " + height);
for (var i = 0; i &lt; height; i++) {
for (var j = 0; j &lt; width; j++) {
var index = ((i * (width * 4)) + (j * 4));
imageData.data[index + 0] = imageData.data[index + 0] + r;
imageData.data[index + 1] = imageData.data[index + 1] + g;
imageData.data[index + 2] = imageData.data[index + 2] + b;
imageData.data[index + 3] = imageData.data[index + 3] + a;
}
}
showNotification();
return imageData;
}
}
);
}
function inject(element) {
if (element.tagName.toUpperCase() === "IFRAME" &amp;&amp; element.contentWindow) {
try {
var hasAccess = element.contentWindow.HTMLCanvasElement;
} catch (e) {
console.log("can't access " + e);
return;
}
overrideCanvasProto(element.contentWindow.HTMLCanvasElement);
overrideCanvaRendProto(element.contentWindow.CanvasRenderingContext2D);
overrideDocumentProto(element.contentWindow.Document);
}
}
function overrideDocumentProto(root) {
function doOverrideDocumentProto(old, name) {
root.prototype[storedObjectPrefix + name] = old;
Object.defineProperty(root.prototype, name,
{
value: function () {
var element = old.apply(this, arguments);
// console.log(name+ " everridden call"+element);
if (element == null) {
return null;
}
if (Object.prototype.toString.call(element) === '[object HTMLCollection]' ||
Object.prototype.toString.call(element) === '[object NodeList]') {
for (var i = 0; i &lt; element.length; ++i) {
var el = element[i];
// console.log("elements list inject " + name);
inject(el);
}
} else {
// console.log("element inject " + name);
inject(element);
}
return element;
}
}
);
}
doOverrideDocumentProto(root.prototype.createElement, "createElement");
doOverrideDocumentProto(root.prototype.createElementNS, "createElementNS");
doOverrideDocumentProto(root.prototype.getElementById, "getElementById");
doOverrideDocumentProto(root.prototype.getElementsByName, "getElementsByName");
doOverrideDocumentProto(root.prototype.getElementsByClassName, "getElementsByClassName");
doOverrideDocumentProto(root.prototype.getElementsByTagName, "getElementsByTagName");
doOverrideDocumentProto(root.prototype.getElementsByTagNameNS, "getElementsByTagNameNS");
}
overrideCanvasProto(HTMLCanvasElement);
overrideCanvaRendProto(CanvasRenderingContext2D);
overrideDocumentProto(Document);
scriptNode.parentNode.removeChild(scriptNode);
})(27,2,8,15,"rohka", "oibvj");} catch (e) {console.error(e);}</script><script xmlns="">(function () {
const config = {
"BUFFER": null,
"getChannelData": function (e) {
const getChannelData = e.prototype.getChannelData;
Object.defineProperty(e.prototype, "getChannelData", {
"value": function () {
const results_1 = getChannelData.apply(this, arguments);
if (config.BUFFER !== results_1) {
config.BUFFER = results_1;
window.top.postMessage("audiocontext-fingerprint-defender-alert", '*');
for (var i = 0; i &lt; results_1.length; i += 100) {
let index = Math.floor(Math.random() * i);
results_1[index] = results_1[index] + Math.random() * 0.0000001;
}
}
return results_1;
}
});
},
"createAnalyser": function (e) {
const createAnalyser = e.prototype.__proto__.createAnalyser;
Object.defineProperty(e.prototype.__proto__, "createAnalyser", {
"value": function () {
const results_2 = createAnalyser.apply(this, arguments);
const getFloatFrequencyData = results_2.__proto__.getFloatFrequencyData;
Object.defineProperty(results_2.__proto__, "getFloatFrequencyData", {
"value": function () {
window.top.postMessage("audiocontext-fingerprint-defender-alert", '*');
const results_3 = getFloatFrequencyData.apply(this, arguments);
for (var i = 0; i &lt; arguments[0].length; i += 100) {
let index = Math.floor(Math.random() * i);
arguments[0][index] = arguments[0][index] + Math.random() * 0.1;
}
return results_3;
}
});
return results_2;
}
});
}
};
config.getChannelData(AudioBuffer);
config.createAnalyser(AudioContext);
config.createAnalyser(OfflineAudioContext);
document.documentElement.dataset.acxscriptallow = true;
})()</script><script xmlns="">{
const iframes = window.top.document.querySelectorAll("iframe[sandbox]");
for (var i = 0; i &lt; iframes.length; i++) {
if (iframes[i].contentWindow) {
if (iframes[i].contentWindow.AudioBuffer) {
if (iframes[i].contentWindow.AudioBuffer.prototype) {
if (iframes[i].contentWindow.AudioBuffer.prototype.getChannelData) {
iframes[i].contentWindow.AudioBuffer.prototype.getChannelData = AudioBuffer.prototype.getChannelData;
}
}
}
if (iframes[i].contentWindow.AudioContext) {
if (iframes[i].contentWindow.AudioContext.prototype) {
if (iframes[i].contentWindow.AudioContext.prototype.__proto__) {
if (iframes[i].contentWindow.AudioContext.prototype.__proto__.createAnalyser) {
iframes[i].contentWindow.AudioContext.prototype.__proto__.createAnalyser = AudioContext.prototype.__proto__.createAnalyser;
}
}
}
}
if (iframes[i].contentWindow.OfflineAudioContext) {
if (iframes[i].contentWindow.OfflineAudioContext.prototype) {
if (iframes[i].contentWindow.OfflineAudioContext.prototype.__proto__) {
if (iframes[i].contentWindow.OfflineAudioContext.prototype.__proto__.createAnalyser) {
iframes[i].contentWindow.OfflineAudioContext.prototype.__proto__.createAnalyser = OfflineAudioContext.prototype.__proto__.createAnalyser;
}
}
}
}
}
}
}</script>
<sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="640" inkscape:window-height="480" id="namedview28" showgrid="false" inkscape:zoom="1.8153846" inkscape:cx="65" inkscape:cy="65" inkscape:window-x="174" inkscape:window-y="201" inkscape:window-maximized="0" inkscape:current-layer="svg2"/>
<title id="title4">SFML Logo</title>
<defs id="defs6">
<linearGradient id="linearGradient4987">
<stop stop-color="#a9ee52" offset="0" id="stop4989"/>
<stop stop-color="#53880e" offset="1" id="stop4991"/>
</linearGradient>
<linearGradient xlink:href="#linearGradient4987" id="linearGradient4885" y2="1.72718" x2="0.681638" y1="-0.03212" x1="0.681638"/>
<linearGradient xlink:href="#linearGradient4987" id="linearGradient4923" y2="1.229777" x2="0.726254" y1="-0.801712" x1="0.726254"/>
</defs>
<metadata id="metadata7">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title>SFML Logo</dc:title>
<dc:date>1 May 2013</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>Michael Bradshaw</dc:title>
</cc:Agent>
</dc:creator>
<cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/"/>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
</cc:License>
</rdf:RDF>
</metadata>
<g id="g14">
<title id="title16">background</title>
<rect fill="none" id="canvas_background" height="132" width="132" y="-1" x="-1"/>
</g>
<g id="g19">
<title id="title21">Layer 1</title>
<path fill="url(#linearGradient4885)" id="path6382" d="m84.545998,17.273001l3.886002,2.823299l3.885902,2.823299l3.886002,2.823301l3.886093,2.823299l3.886002,2.823299l3.886002,2.823299c19.738007,14.509003 17.410995,20.329002 12.008003,36.958l-1.485001,4.568199l-1.484001,4.5681l-1.484001,4.5681l-1.485001,4.568199l-1.484001,4.568199l-1.484001,4.568405c-7.698997,23.254997 -13.953995,22.840996 -31.438194,22.840996l-28.819004,0c-24.496998,-0.135994 -26.034998,-6.212997 -31.437998,-22.840996l-1.484301,-4.568405l-1.484301,-4.568199l-1.484299,-4.568199l-1.484301,-4.5681l-1.484301,-4.568199l-1.4844,-4.568199c-7.4402,-23.34 -2.1364,-26.681 12.007999,-36.958l3.8859,-2.823299l3.886,-2.823301l3.885902,-2.823299l3.885899,-2.8234l3.885998,-2.823299l3.886002,-2.823299c19.898003,-14.289001 24.715004,-10.277 38.859001,0.000099l0.000397,0.000101z"/>
<path fill="url(#linearGradient4923)" id="path4909" d="m7.188,57.469002c0.372391,3.668098 1.403501,8.090996 3.1875,13.687996l1.468801,4.593803l1.499999,4.5625l1.468801,4.5625l1.5,4.5625l1.4688,4.5625l1.5,4.593796c5.403,16.629005 6.9408,22.676003 31.437998,22.812004l28.812,0c17.484001,0 23.737999,0.442902 31.438004,-22.812004l1.468796,-4.593796l1.5,-4.5625l1.468803,-4.5625l1.125,-3.468803c-44.595001,-4.591995 -82.711002,-13.043999 -109.340001,-23.942997l-0.0045,0.005001z"/>
<g fill="#ffffff" id="g3366">
<path id="path6354" d="m85.397003,28.201l-4.0625,15.593998l1.062599,0.781303l2.687294,1.9375l2.687607,1.968697l2.687393,1.9375l2.687607,1.968803l2.875,2.062397c2.360596,1.611702 3.110199,2.436802 3.343697,2.6563c-0.081001,0.27935 -0.306702,1.283901 -1.25,4.1875l-1.031303,3.1875l-1.031197,3.156303l-1.031197,3.156197l-1.031303,3.156204l-1,3.156296l-1.031303,3.1875l-1.031197,3.156204l-1.031197,3.156296l-1.031303,3.156303l-1.0933,3.375c-0.812897,2.775299 -1.371597,3.723297 -1.5,4c-0.356102,0.008995 -1.315201,0.094002 -4.374901,0.094002l-33.467991,0c-2.861698,0.084 -3.932999,-0.116005 -4.25,-0.156303c-0.098999,-0.251442 -0.471397,-0.888611 -1.4375,-4.156197l-1.0313,-3.156204l-1.0312,-3.156296l-1.031197,-3.156303l-1.031303,-3.156197l-1.0313,-3.1875l-1.0312,-3.156303l-1,-3.156197l-1.031197,-3.156204l-1.031303,-3.156296l-1.093197,-3.375004c-0.9795,-2.739201 -1.098301,-3.8344 -1.1563,-4.125c0.226299,-0.181408 0.7323,-0.667999 3.468597,-2.6563l2.687599,-1.937401l2.7187,-1.9688l2.6875,-1.9375l2.6875,-1.9687l2.6875,-1.9375l1.0312,-0.75l-4.062401,-15.594l-0.4063,0.281301l-2.6875,1.9687l-2.6875,1.9375l-2.6875,1.9688l-2.7188,1.9375l-2.687298,1.9687l-2.687601,1.9688l-2.687401,1.9375c-3.213099,2.334301 -6.683409,4.2644 -8.687609,9.124901c-1.979401,4.8008 -0.851101,9.498997 0.969109,14.625l1.031,3.156097l1.03129,3.156303l1.0313,3.156197l1.0312,3.1875l1.03121,3.156303l1.03129,3.156197l1.0313,3.156204l1,3.156296l1.0312,3.1875l1.03121,3.156204c1.227201,3.7771 1.996702,7.6856 5.999891,11.093994c3.9487,3.361504 8.758808,3.708206 14.188,3.5625l33.250999,0c3.971397,0 7.927704,0.473106 12.405998,-2.281296c4.415001,-2.715401 6.273903,-7.170204 7.8125,-12.375l1.0308,-3.156204l1,-3.1875l1.031204,-3.156296l1.031197,-3.156204l1.031303,-3.156197l1.031296,-3.156303l1.031204,-3.1875l1.031097,-3.156197l1.031303,-3.156303l1,-3.156296c1.227097,-3.777 2.923096,-7.389503 1.6875,-12.5c-1.2183,-5.038902 -4.899101,-8.1777 -9.374901,-11.25l-2.6875,-1.9375l-2.718704,-1.968803l-2.687599,-1.968697l-2.687401,-1.9375l-2.687599,-1.968803l-2.687401,-1.9375l-2.687599,-1.968699l-0.437401,-0.3125l-0.002495,-0.000299z"/>
<path id="path6356" d="m64.526001,17.176001c-4.308399,0.26351 -7.9562,2.579399 -11.719002,5.4688c-0.035999,0.027 -0.061001,0.065001 -0.093998,0.094l10.312,39.704002l4.5,0.000099l10.344002,-39.704002l-0.094002,-0.094c-3.213005,-2.3342 -6.133003,-5.0334 -11.375,-5.4375c-0.645401,-0.049999 -1.259499,-0.069 -1.875,-0.031l0.000999,-0.000399z"/>
</g>
</g>
<script xmlns=""/></svg>

After

Width:  |  Height:  |  Size: 16 KiB