mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Typeface: Implement platform typefaces using Harfbuzz hb_font_t
This commit is contained in:
parent
080ac6e7e7
commit
0d2e34f34c
56 changed files with 8359 additions and 2985 deletions
|
|
@ -430,8 +430,10 @@ struct AndroidDocument::Utils
|
|||
|
||||
std::unique_ptr<InputStream> createInputStream() const override
|
||||
{
|
||||
auto result = std::make_unique<AndroidContentUriInputStream> (uri);
|
||||
return result->openedSuccessfully() ? std::move (result) : nullptr;
|
||||
if (auto opened = AndroidContentUriInputStream::fromUri (uri))
|
||||
return std::make_unique<AndroidContentUriInputStream> (std::move (*opened));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<OutputStream> createOutputStream() const override
|
||||
|
|
|
|||
|
|
@ -584,14 +584,33 @@ struct AndroidStreamHelpers
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
struct AndroidContentUriInputStream final : public InputStream
|
||||
class AndroidInputStreamWrapper final : public InputStream
|
||||
{
|
||||
explicit AndroidContentUriInputStream (const GlobalRef& uriIn)
|
||||
: uri (uriIn),
|
||||
stream (AndroidStreamHelpers::createStream (uri, AndroidStreamHelpers::StreamKind::input))
|
||||
{}
|
||||
public:
|
||||
explicit AndroidInputStreamWrapper (jobject streamIn)
|
||||
: stream (LocalRef<jobject> { streamIn })
|
||||
{
|
||||
}
|
||||
|
||||
~AndroidContentUriInputStream() override
|
||||
AndroidInputStreamWrapper (AndroidInputStreamWrapper&& other) noexcept
|
||||
: byteArray (std::exchange (other.byteArray, {})),
|
||||
stream (std::exchange (other.stream, {})),
|
||||
pos (std::exchange (other.pos, {})),
|
||||
exhausted (std::exchange (other.exhausted, {}))
|
||||
{
|
||||
}
|
||||
|
||||
AndroidInputStreamWrapper (const AndroidInputStreamWrapper&) = delete;
|
||||
|
||||
AndroidInputStreamWrapper& operator= (AndroidInputStreamWrapper&& other) noexcept
|
||||
{
|
||||
std::swap (*this, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AndroidInputStreamWrapper& operator= (const AndroidInputStreamWrapper&) = delete;
|
||||
|
||||
~AndroidInputStreamWrapper() override
|
||||
{
|
||||
getEnv()->CallVoidMethod (stream.get(), AndroidInputStream.close);
|
||||
jniCheckHasExceptionOccurredAndClear();
|
||||
|
|
@ -625,16 +644,9 @@ struct AndroidContentUriInputStream final : public InputStream
|
|||
return result;
|
||||
}
|
||||
|
||||
bool setPosition (int64 newPos) override
|
||||
bool setPosition (int64) override
|
||||
{
|
||||
if (newPos == pos)
|
||||
return true;
|
||||
|
||||
if (pos < newPos)
|
||||
return skipImpl (newPos - pos);
|
||||
|
||||
AndroidContentUriInputStream (uri).swap (*this);
|
||||
return skipImpl (newPos);
|
||||
return false;
|
||||
}
|
||||
|
||||
int64 getPosition() override
|
||||
|
|
@ -642,8 +654,6 @@ struct AndroidContentUriInputStream final : public InputStream
|
|||
return pos;
|
||||
}
|
||||
|
||||
bool openedSuccessfully() const { return stream != nullptr; }
|
||||
|
||||
void skipNextBytes (int64 num) override
|
||||
{
|
||||
skipImpl (num);
|
||||
|
|
@ -664,21 +674,107 @@ private:
|
|||
return skipped == num;
|
||||
}
|
||||
|
||||
auto tie() { return std::tie (uri, byteArray, stream, pos, exhausted); }
|
||||
|
||||
void swap (AndroidContentUriInputStream& other) noexcept
|
||||
{
|
||||
auto toSwap = other.tie();
|
||||
tie().swap (toSwap);
|
||||
}
|
||||
|
||||
GlobalRef uri;
|
||||
CachedByteArray byteArray;
|
||||
GlobalRef stream;
|
||||
int64 pos = 0;
|
||||
bool exhausted = false;
|
||||
};
|
||||
|
||||
std::unique_ptr<InputStream> makeAndroidInputStreamWrapper (jobject stream);
|
||||
std::unique_ptr<InputStream> makeAndroidInputStreamWrapper (jobject stream)
|
||||
{
|
||||
return std::make_unique<AndroidInputStreamWrapper> (stream);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct AndroidContentUriInputStream final : public InputStream
|
||||
{
|
||||
AndroidContentUriInputStream (AndroidContentUriInputStream&& other) noexcept
|
||||
: stream (std::move (other.stream)),
|
||||
uri (std::exchange (other.uri, {}))
|
||||
{
|
||||
}
|
||||
|
||||
AndroidContentUriInputStream (const AndroidContentUriInputStream&) = delete;
|
||||
|
||||
AndroidContentUriInputStream& operator= (AndroidContentUriInputStream&& other) noexcept
|
||||
{
|
||||
std::swap (*this, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AndroidContentUriInputStream& operator= (const AndroidContentUriInputStream&) = delete;
|
||||
|
||||
int64 getTotalLength() override
|
||||
{
|
||||
return stream.getTotalLength();
|
||||
}
|
||||
|
||||
bool isExhausted() override
|
||||
{
|
||||
return stream.isExhausted();
|
||||
}
|
||||
|
||||
int read (void* destBuffer, int maxBytesToRead) override
|
||||
{
|
||||
return stream.read (destBuffer, maxBytesToRead);
|
||||
}
|
||||
|
||||
bool setPosition (int64 newPos) override
|
||||
{
|
||||
if (newPos == getPosition())
|
||||
return true;
|
||||
|
||||
if (getPosition() < newPos)
|
||||
return skipImpl (newPos - getPosition());
|
||||
|
||||
auto newStream = fromUri (uri);
|
||||
|
||||
if (! newStream.has_value())
|
||||
return false;
|
||||
|
||||
*this = std::move (*newStream);
|
||||
return skipImpl (newPos);
|
||||
}
|
||||
|
||||
int64 getPosition() override
|
||||
{
|
||||
return stream.getPosition();
|
||||
}
|
||||
|
||||
void skipNextBytes (int64 num) override
|
||||
{
|
||||
stream.skipNextBytes (num);
|
||||
}
|
||||
|
||||
static std::optional<AndroidContentUriInputStream> fromUri (const GlobalRef& uriIn)
|
||||
{
|
||||
const auto nativeStream = AndroidStreamHelpers::createStream (uriIn, AndroidStreamHelpers::StreamKind::input);
|
||||
|
||||
if (nativeStream == nullptr)
|
||||
return {};
|
||||
|
||||
return AndroidContentUriInputStream { AndroidInputStreamWrapper { nativeStream }, uriIn };
|
||||
}
|
||||
|
||||
private:
|
||||
AndroidContentUriInputStream (AndroidInputStreamWrapper streamIn, const GlobalRef& uriIn)
|
||||
: stream (std::move (streamIn)),
|
||||
uri (uriIn)
|
||||
{
|
||||
}
|
||||
|
||||
bool skipImpl (int64 num)
|
||||
{
|
||||
const auto oldPosition = getPosition();
|
||||
skipNextBytes (num);
|
||||
return getPosition() == oldPosition + num;
|
||||
}
|
||||
|
||||
AndroidInputStreamWrapper stream;
|
||||
GlobalRef uri;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class MediaScannerConnectionClient : public AndroidInterfaceImplementer
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue