Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions examples/graphics/data/svg/mozilla2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions examples/graphics/data/svg/pulpitrock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 96 additions & 7 deletions examples/graphics/source/examples/Svg.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,17 @@ class SvgDemo : public yup::Component
SvgDemo()
{
updateListOfSvgFiles();
loadDemoFont();

parseSvgFile (currentSvgFileIndex);
}

void resized() override
{
//drawable.setBounds (getLocalBounds());
}

void mouseDown (const yup::MouseEvent& event) override
{
++currentSvgFileIndex;
if (event.isLeftButtonDown())
++currentSvgFileIndex;
else if (event.isRightButtonDown())
--currentSvgFileIndex;

parseSvgFile (currentSvgFileIndex);
}
Expand All @@ -59,12 +58,17 @@ class SvgDemo : public yup::Component
.getParentDirectory()
.getParentDirectory();

dataDirectory = riveBasePath.getChildFile ("data");

auto files = riveBasePath.getChildFile ("data/svg").findChildFiles (yup::File::findFiles, false, "*.svg");
if (files.isEmpty())
return;

for (const auto& svgFile : files)
{
//if (svgFile.getFileName() == "mozilla2.svg")
svgFiles.add (svgFile);
}
}

void parseSvgFile (int index)
Expand All @@ -83,12 +87,97 @@ class SvgDemo : public yup::Component
YUP_DBG ("Showing " << svgFiles[currentSvgFileIndex].getFullPathName());

drawable.clear();
drawable.parseSVG (svgFiles[currentSvgFileIndex]);
drawable.parseSVG (svgFiles[currentSvgFileIndex], createParseOptions (svgFiles[currentSvgFileIndex]));

repaint();
}

void loadDemoFont()
{
yup::Font font;
if (font.loadFromFile (dataDirectory.getChildFile ("RobotoFlex-VariableFont.ttf")).wasOk())
demoFont = std::move (font);
}

std::optional<yup::Image> fetchHttpImage (const yup::String& href)
{
if (! href.startsWithIgnoreCase ("http:") && ! href.startsWithIgnoreCase ("https:"))
return std::nullopt;

if (httpImageCache.contains (href))
return httpImageCache[href];

yup::MemoryBlock imageData;
int statusCode = 0;

auto streamOptions = yup::URL::InputStreamOptions (yup::URL::ParameterHandling::inAddress)
.withConnectionTimeoutMs (5000)
.withNumRedirectsToFollow (5)
.withStatusCode (&statusCode)
.withExtraHeaders ("User-Agent: YUP SVG Demo\r\nAccept: image/*\r\n");

auto stream = yup::URL (href).createInputStream (streamOptions);
if (stream == nullptr)
{
YUP_DBG ("Unable to fetch SVG image href: " << href);
return std::nullopt;
}

stream->readIntoMemoryBlock (imageData);

if ((statusCode != 0 && (statusCode < 200 || statusCode >= 300)) || imageData.isEmpty())
{
YUP_DBG ("Unable to fetch SVG image href: " << href << " status: " << statusCode);
return std::nullopt;
}

auto imageResult = yup::Image::loadFromData (imageData.asBytes());
if (imageResult.failed())
{
YUP_DBG ("Unable to decode SVG image href: " << href << " error: " << imageResult.getErrorMessage());
return std::nullopt;
}

auto image = imageResult.getValue();
httpImageCache.set (href, image);
return image;
}

yup::Drawable::ParseOptions createParseOptions (const yup::File& svgFile)
{
yup::Drawable::ParseOptions options;
options.baseDirectory = svgFile.getParentDirectory();
options.imageResolver = [this] (yup::StringRef href, const yup::File&) -> std::optional<yup::Image>
{
return fetchHttpImage (yup::String (href.text));
};

options.fontResolver = [this] (yup::StringRef, float fontSize, int weight, bool italic) -> std::optional<yup::Font>
{
if (demoFont)
{
auto font = *demoFont;
font.setAxisValue ("wght", static_cast<float> (weight));
if (italic)
font.setAxisValue ("slnt", -10.0f);
else
font.setAxisValue ("slnt", 0.0f);
return font.withHeight (fontSize);
}

if (auto theme = yup::ApplicationTheme::getGlobalTheme())
return theme->getDefaultFont().withHeight (fontSize);

return std::nullopt;
};

return options;
}

yup::Drawable drawable;
yup::Array<yup::File> svgFiles;
yup::File dataDirectory;
std::optional<yup::Font> demoFont;
yup::HashMap<yup::String, yup::Image> httpImageCache;
int currentSvgFileIndex = 0;
};
27 changes: 16 additions & 11 deletions modules/yup_audio_basics/sources/yup_BufferingAudioSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,12 @@ void BufferingAudioSource::releaseResources()

buffer.setSize (numberOfChannels, 0);

// MSVC2017 seems to need this if statement to not generate a warning during linking.
// As source is set in the constructor, there is no way that source could
// ever equal this, but it seems to make MSVC2017 happy.
if (source != this)
source->releaseResources();
source->releaseResources();
}

void BufferingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info)
{
const auto bufferRange = getValidBufferRange (info.numSamples);
auto [playPos, bufferRange] = getValidBufferRangeAndAdvance (info.numSamples);

if (bufferRange.isEmpty())
{
Expand All @@ -143,8 +139,8 @@ void BufferingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info
{
jassert (buffer.getNumSamples() > 0);

const auto startBufferIndex = (int) ((validStart + nextPlayPos) % buffer.getNumSamples());
const auto endBufferIndex = (int) ((validEnd + nextPlayPos) % buffer.getNumSamples());
const auto startBufferIndex = (int) ((validStart + playPos) % buffer.getNumSamples());
const auto endBufferIndex = (int) ((validEnd + playPos) % buffer.getNumSamples());

if (startBufferIndex < endBufferIndex)
{
Expand All @@ -155,13 +151,10 @@ void BufferingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info
const auto initialSize = buffer.getNumSamples() - startBufferIndex;

info.buffer->copyFrom (chan, info.startSample + validStart, buffer, chan, startBufferIndex, initialSize);

info.buffer->copyFrom (chan, info.startSample + validStart + initialSize, buffer, chan, 0, (validEnd - validStart) - initialSize);
}
}
}

nextPlayPos += info.numSamples;
}

bool BufferingAudioSource::waitForNextAudioBlockReady (const AudioSourceChannelInfo& info, uint32 timeout)
Expand Down Expand Up @@ -235,6 +228,18 @@ Range<int> BufferingAudioSource::getValidBufferRange (int numSamples) const
(int) (jlimit (bufferValidStart, bufferValidEnd, pos + numSamples) - pos) };
}

std::tuple<int64, Range<int>> BufferingAudioSource::getValidBufferRangeAndAdvance (int numSamples)
{
const ScopedLock sl (bufferRangeLock);

const auto pos = nextPlayPos.load();

nextPlayPos = pos + numSamples;

return std::make_tuple (
pos, Range<int> { (int) (jlimit (bufferValidStart, bufferValidEnd, pos) - pos), (int) (jlimit (bufferValidStart, bufferValidEnd, pos + numSamples) - pos) });
}

bool BufferingAudioSource::readNextBufferChunk()
{
int64 newBVS, newBVE, sectionToReadStart, sectionToReadEnd;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class YUP_API BufferingAudioSource : public PositionableAudioSource
private:
//==============================================================================
Range<int> getValidBufferRange (int numSamples) const;
std::tuple<int64, Range<int>> getValidBufferRangeAndAdvance (int numSamples);
bool readNextBufferChunk();
void readBufferSection (int64 start, int length, int bufferOffset);
int useTimeSlice() override;
Expand Down
25 changes: 21 additions & 4 deletions modules/yup_core/containers/yup_HashMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,18 +134,35 @@ class HashMap

public:
//==============================================================================
/** Creates an empty hash-map.
*/
HashMap()
: HashMap (defaultHashTableSize, HashFunctionType())
{
}

/** Creates an empty hash-map.

@param numberOfSlots Specifies the number of hash entries the map will use. This will be
the "upperLimit" parameter that is passed to your generateHash()
function. The number of hash slots will grow automatically if necessary,
or it can be remapped manually using remapTable().
*/
explicit HashMap (int numberOfSlots)
: HashMap (numberOfSlots, HashFunctionType())
{
}

/** Creates an empty hash-map.

@param numberOfSlots Specifies the number of hash entries the map will use. This will be
the "upperLimit" parameter that is passed to your generateHash()
function. The number of hash slots will grow automatically if necessary,
or it can be remapped manually using remapTable().
@param hashFunction An instance of HashFunctionType, which will be copied and
stored to use with the HashMap. This parameter can be omitted
if HashFunctionType has a default constructor.
stored to use with the HashMap.
*/
explicit HashMap (int numberOfSlots = defaultHashTableSize,
HashFunctionType hashFunction = HashFunctionType())
HashMap (int numberOfSlots, HashFunctionType hashFunction)
: hashFunctionToUse (hashFunction)
{
hashSlots.insertMultiple (0, nullptr, numberOfSlots);
Expand Down
2 changes: 1 addition & 1 deletion modules/yup_core/files/yup_File.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class YUP_API File final
On the Mac/Linux, the path can include "~" notation for referring to
user home directories.
*/
File (const String& absolutePath);
explicit File (const String& absolutePath);

/** Creates a copy of another file object. */
File (const File&);
Expand Down
2 changes: 1 addition & 1 deletion modules/yup_core/files/yup_FileSearchPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void FileSearchPath::removeRedundantPaths()
{
const auto checkedIsChildOf = [&] (const auto& a, const auto& b)
{
return File::isAbsolutePath (a) && File::isAbsolutePath (b) && File (a).isAChildOf (b);
return File::isAbsolutePath (a) && File::isAbsolutePath (b) && File (a).isAChildOf (File (b));
};

const auto fContainsDirectory = [&] (const auto& f)
Expand Down
10 changes: 5 additions & 5 deletions modules/yup_core/native/yup_Files_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,12 @@ File AndroidContentUriResolver::getLocalFileFromContentUri (const URL& url)
if (type == "image")
type = "images";

return getCursorDataColumn (URL ("content://media/external/" + type + "/media"),
"_id=?",
StringArray { mediaId });
return File (getCursorDataColumn (URL ("content://media/external/" + type + "/media"),
"_id=?",
StringArray { mediaId }));
}

return getCursorDataColumn (url);
return File (getCursorDataColumn (url));
}

String AndroidContentUriResolver::getFileNameFromContentUri (const URL& url)
Expand Down Expand Up @@ -745,7 +745,7 @@ static File getAppDataDir (bool dataDir)
LocalRef<jobject> applicationInfo (env->CallObjectMethod (getAppContext().get(), AndroidContext.getApplicationInfo));
LocalRef<jobject> jString (env->GetObjectField (applicationInfo.get(), dataDir ? AndroidApplicationInfo.dataDir : AndroidApplicationInfo.publicSourceDir));

return { yupString ((jstring) jString.get()) };
return File (yupString ((jstring) jString.get()));
}

File File::getSpecialLocation (const SpecialLocationType type)
Expand Down
Loading
Loading