mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Misc cleanups and modernisation
This commit is contained in:
parent
0f94dbbf96
commit
dee78f29f6
29 changed files with 266 additions and 275 deletions
|
|
@ -296,7 +296,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This typedef can be used to get the type of the heapblock's elements. */
|
/** This typedef can be used to get the type of the heapblock's elements. */
|
||||||
typedef ElementType Type;
|
using Type = ElementType;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
typedef HeapBlock<char, true> HeapBlockType;
|
using HeapBlockType = HeapBlock<char, true>;
|
||||||
HeapBlockType data;
|
HeapBlockType data;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ public:
|
||||||
JUCE_DECLARE_NON_COPYABLE (SharedPointer)
|
JUCE_DECLARE_NON_COPYABLE (SharedPointer)
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ReferenceCountedObjectPtr<SharedPointer> SharedRef;
|
using SharedRef = ReferenceCountedObjectPtr<SharedPointer>;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ public:
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Function type of runtime permission request callbacks. */
|
/** Function type of runtime permission request callbacks. */
|
||||||
typedef std::function<void (bool)> Callback;
|
using Callback = std::function<void (bool)>;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Call this method to request a runtime permission.
|
/** Call this method to request a runtime permission.
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ static NSRect makeNSRect (const RectangleType& r) noexcept
|
||||||
template <typename ReturnValue, typename... Params>
|
template <typename ReturnValue, typename... Params>
|
||||||
static inline ReturnValue ObjCMsgSendSuper (struct objc_super* s, SEL sel, Params... params)
|
static inline ReturnValue ObjCMsgSendSuper (struct objc_super* s, SEL sel, Params... params)
|
||||||
{
|
{
|
||||||
typedef ReturnValue (*SuperFn)(struct objc_super*, SEL, Params...);
|
using SuperFn = ReturnValue (*)(struct objc_super*, SEL, Params...);
|
||||||
SuperFn fn = reinterpret_cast<SuperFn> (objc_msgSendSuper);
|
SuperFn fn = reinterpret_cast<SuperFn> (objc_msgSendSuper);
|
||||||
return fn (s, sel, params...);
|
return fn (s, sel, params...);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -260,11 +260,11 @@ static void addAddress (const sockaddr_in6* addr_in, Array<IPAddress>& result)
|
||||||
{
|
{
|
||||||
in6_addr addr = addr_in->sin6_addr;
|
in6_addr addr = addr_in->sin6_addr;
|
||||||
|
|
||||||
typedef union
|
union ByteUnion
|
||||||
{
|
{
|
||||||
uint16 combined;
|
uint16 combined;
|
||||||
uint8 split[2];
|
uint8 split[2];
|
||||||
} ByteUnion;
|
};
|
||||||
|
|
||||||
ByteUnion temp;
|
ByteUnion temp;
|
||||||
uint16 arr[8];
|
uint16 arr[8];
|
||||||
|
|
|
||||||
|
|
@ -97,14 +97,14 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Union used to split a 16-bit unsigned integer into 2 8-bit unsigned integers or vice-versa */
|
/** Union used to split a 16-bit unsigned integer into 2 8-bit unsigned integers or vice-versa */
|
||||||
typedef union
|
union ByteUnion
|
||||||
{
|
{
|
||||||
uint16 combined;
|
uint16 combined;
|
||||||
uint8 split[2];
|
uint8 split[2];
|
||||||
} ByteUnion;
|
};
|
||||||
|
|
||||||
/** Method used to zero the remaining bytes of the address array when creating IPv4 addresses */
|
/** Method used to zero the remaining bytes of the address array when creating IPv4 addresses */
|
||||||
void zeroUnusedBytes()
|
void zeroUnusedBytes() noexcept
|
||||||
{
|
{
|
||||||
for (int i = 4; i < 16; ++i)
|
for (int i = 4; i < 16; ++i)
|
||||||
address[i] = 0;
|
address[i] = 0;
|
||||||
|
|
|
||||||
|
|
@ -61,10 +61,10 @@ struct FallbackDownloadTask : public URL::DownloadTask,
|
||||||
if (listener != nullptr)
|
if (listener != nullptr)
|
||||||
listener->progress (this, downloaded, contentLength);
|
listener->progress (this, downloaded, contentLength);
|
||||||
|
|
||||||
const int max = jmin ((int) bufferSize, contentLength < 0 ? std::numeric_limits<int>::max()
|
auto max = jmin ((int) bufferSize, contentLength < 0 ? std::numeric_limits<int>::max()
|
||||||
: static_cast<int> (contentLength - downloaded));
|
: static_cast<int> (contentLength - downloaded));
|
||||||
|
|
||||||
const int actual = stream->read (buffer.get(), max);
|
auto actual = stream->read (buffer.get(), max);
|
||||||
|
|
||||||
if (actual < 0 || threadShouldExit() || stream->isError())
|
if (actual < 0 || threadShouldExit() || stream->isError())
|
||||||
break;
|
break;
|
||||||
|
|
@ -186,8 +186,8 @@ void URL::init()
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
const int nextAmp = url.indexOfChar (i + 1, '&');
|
auto nextAmp = url.indexOfChar (i + 1, '&');
|
||||||
const int equalsPos = url.indexOfChar (i + 1, '=');
|
auto equalsPos = url.indexOfChar (i + 1, '=');
|
||||||
|
|
||||||
if (nextAmp < 0)
|
if (nextAmp < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -324,7 +324,7 @@ void URL::addParameter (const String& name, const String& value)
|
||||||
parameterValues.add (value);
|
parameterValues.add (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
String URL::toString (const bool includeGetParameters) const
|
String URL::toString (bool includeGetParameters) const
|
||||||
{
|
{
|
||||||
if (includeGetParameters && parameterNames.size() > 0)
|
if (includeGetParameters && parameterNames.size() > 0)
|
||||||
return url + "?" + URLHelpers::getMangledParameters (*this);
|
return url + "?" + URLHelpers::getMangledParameters (*this);
|
||||||
|
|
@ -653,14 +653,14 @@ private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
InputStream* URL::createInputStream (const bool usePostCommand,
|
InputStream* URL::createInputStream (bool usePostCommand,
|
||||||
OpenStreamProgressCallback* const progressCallback,
|
OpenStreamProgressCallback* progressCallback,
|
||||||
void* const progressCallbackContext,
|
void* progressCallbackContext,
|
||||||
String headers,
|
String headers,
|
||||||
const int timeOutMs,
|
int timeOutMs,
|
||||||
StringPairArray* const responseHeaders,
|
StringPairArray* responseHeaders,
|
||||||
int* statusCode,
|
int* statusCode,
|
||||||
const int numRedirectsToFollow,
|
int numRedirectsToFollow,
|
||||||
String httpRequestCmd) const
|
String httpRequestCmd) const
|
||||||
{
|
{
|
||||||
if (isLocalFile())
|
if (isLocalFile())
|
||||||
|
|
@ -684,10 +684,10 @@ InputStream* URL::createInputStream (const bool usePostCommand,
|
||||||
|
|
||||||
bool postDataSendProgress (WebInputStream&, int bytesSent, int totalBytes) override
|
bool postDataSendProgress (WebInputStream&, int bytesSent, int totalBytes) override
|
||||||
{
|
{
|
||||||
return callback(data, bytesSent, totalBytes);
|
return callback (data, bytesSent, totalBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenStreamProgressCallback* const callback;
|
OpenStreamProgressCallback* callback;
|
||||||
void* const data;
|
void* const data;
|
||||||
|
|
||||||
// workaround a MSVC 2013 compiler warning
|
// workaround a MSVC 2013 compiler warning
|
||||||
|
|
@ -858,8 +858,8 @@ String URL::removeEscapeChars (const String& s)
|
||||||
{
|
{
|
||||||
if (utf8.getUnchecked(i) == '%')
|
if (utf8.getUnchecked(i) == '%')
|
||||||
{
|
{
|
||||||
const int hexDigit1 = CharacterFunctions::getHexDigitValue ((juce_wchar) (uint8) utf8 [i + 1]);
|
auto hexDigit1 = CharacterFunctions::getHexDigitValue ((juce_wchar) (uint8) utf8 [i + 1]);
|
||||||
const int hexDigit2 = CharacterFunctions::getHexDigitValue ((juce_wchar) (uint8) utf8 [i + 2]);
|
auto hexDigit2 = CharacterFunctions::getHexDigitValue ((juce_wchar) (uint8) utf8 [i + 2]);
|
||||||
|
|
||||||
if (hexDigit1 >= 0 && hexDigit2 >= 0)
|
if (hexDigit1 >= 0 && hexDigit2 >= 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@ public:
|
||||||
It allows your app to receive progress updates during a lengthy POST operation. If you
|
It allows your app to receive progress updates during a lengthy POST operation. If you
|
||||||
want to continue the operation, this should return true, or false to abort.
|
want to continue the operation, this should return true, or false to abort.
|
||||||
*/
|
*/
|
||||||
typedef bool (OpenStreamProgressCallback) (void* context, int bytesSent, int totalBytes);
|
using OpenStreamProgressCallback = bool (void* context, int bytesSent, int totalBytes);
|
||||||
|
|
||||||
/** Attempts to open a stream that can read from this URL.
|
/** Attempts to open a stream that can read from this URL.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,7 @@ public:
|
||||||
/** A function type for use in setApplicationCrashHandler(). The parameter will contain
|
/** A function type for use in setApplicationCrashHandler(). The parameter will contain
|
||||||
platform-specific data about the crash.
|
platform-specific data about the crash.
|
||||||
*/
|
*/
|
||||||
typedef void (*CrashHandlerFunction) (void*);
|
using CrashHandlerFunction = void (*) (void*);
|
||||||
|
|
||||||
/** Sets up a global callback function that will be called if the application
|
/** Sets up a global callback function that will be called if the application
|
||||||
executes some kind of illegal instruction.
|
executes some kind of illegal instruction.
|
||||||
|
|
|
||||||
|
|
@ -2047,7 +2047,7 @@ struct StringEncodingConverter
|
||||||
{
|
{
|
||||||
auto& source = const_cast<String&> (s);
|
auto& source = const_cast<String&> (s);
|
||||||
|
|
||||||
typedef typename CharPointerType_Dest::CharType DestChar;
|
using DestChar = typename CharPointerType_Dest::CharType;
|
||||||
|
|
||||||
if (source.isEmpty())
|
if (source.isEmpty())
|
||||||
return CharPointerType_Dest (reinterpret_cast<const DestChar*> (&emptyChar));
|
return CharPointerType_Dest (reinterpret_cast<const DestChar*> (&emptyChar));
|
||||||
|
|
|
||||||
|
|
@ -153,11 +153,11 @@ public:
|
||||||
toUTF32() methods let you access the string's content in any of the other formats.
|
toUTF32() methods let you access the string's content in any of the other formats.
|
||||||
*/
|
*/
|
||||||
#if (JUCE_STRING_UTF_TYPE == 32)
|
#if (JUCE_STRING_UTF_TYPE == 32)
|
||||||
typedef CharPointer_UTF32 CharPointerType;
|
using CharPointerType = CharPointer_UTF32;
|
||||||
#elif (JUCE_STRING_UTF_TYPE == 16)
|
#elif (JUCE_STRING_UTF_TYPE == 16)
|
||||||
typedef CharPointer_UTF16 CharPointerType;
|
using CharPointerType = CharPointer_UTF16;
|
||||||
#elif (DOXYGEN || JUCE_STRING_UTF_TYPE == 8)
|
#elif (DOXYGEN || JUCE_STRING_UTF_TYPE == 8)
|
||||||
typedef CharPointer_UTF8 CharPointerType;
|
using CharPointerType = CharPointer_UTF8;
|
||||||
#else
|
#else
|
||||||
#error "You must set the value of JUCE_STRING_UTF_TYPE to be either 8, 16, or 32!"
|
#error "You must set the value of JUCE_STRING_UTF_TYPE to be either 8, 16, or 32!"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -90,13 +90,13 @@ public:
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Provides the type of scoped lock to use with a CriticalSection. */
|
/** Provides the type of scoped lock to use with a CriticalSection. */
|
||||||
typedef GenericScopedLock <CriticalSection> ScopedLockType;
|
using ScopedLockType = GenericScopedLock<CriticalSection>;
|
||||||
|
|
||||||
/** Provides the type of scoped unlocker to use with a CriticalSection. */
|
/** Provides the type of scoped unlocker to use with a CriticalSection. */
|
||||||
typedef GenericScopedUnlock <CriticalSection> ScopedUnlockType;
|
using ScopedUnlockType = GenericScopedUnlock<CriticalSection>;
|
||||||
|
|
||||||
/** Provides the type of scoped try-locker to use with a CriticalSection. */
|
/** Provides the type of scoped try-locker to use with a CriticalSection. */
|
||||||
typedef GenericScopedTryLock <CriticalSection> ScopedTryLockType;
|
using ScopedTryLockType = GenericScopedTryLock<CriticalSection>;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -148,7 +148,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A dummy scoped-unlocker type to use with a dummy critical section. */
|
/** A dummy scoped-unlocker type to use with a dummy critical section. */
|
||||||
typedef ScopedLockType ScopedUnlockType;
|
using ScopedUnlockType = ScopedLockType;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JUCE_DECLARE_NON_COPYABLE (DummyCriticalSection)
|
JUCE_DECLARE_NON_COPYABLE (DummyCriticalSection)
|
||||||
|
|
|
||||||
|
|
@ -70,10 +70,10 @@ public:
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Provides the type of scoped lock to use for locking a SpinLock. */
|
/** Provides the type of scoped lock to use for locking a SpinLock. */
|
||||||
typedef GenericScopedLock <SpinLock> ScopedLockType;
|
using ScopedLockType = GenericScopedLock<SpinLock>;
|
||||||
|
|
||||||
/** Provides the type of scoped unlocker to use with a SpinLock. */
|
/** Provides the type of scoped unlocker to use with a SpinLock. */
|
||||||
typedef GenericScopedUnlock <SpinLock> ScopedUnlockType;
|
using ScopedUnlockType = GenericScopedUnlock<SpinLock>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,7 @@ public:
|
||||||
/** A value type used for thread IDs.
|
/** A value type used for thread IDs.
|
||||||
@see getCurrentThreadId(), getThreadId()
|
@see getCurrentThreadId(), getThreadId()
|
||||||
*/
|
*/
|
||||||
typedef void* ThreadID;
|
using ThreadID = void*;
|
||||||
|
|
||||||
/** Returns an id that identifies the caller thread.
|
/** Returns an id that identifies the caller thread.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,11 +94,11 @@ namespace TimeHelpers
|
||||||
static inline String formatString (const String& format, const std::tm* const tm)
|
static inline String formatString (const String& format, const std::tm* const tm)
|
||||||
{
|
{
|
||||||
#if JUCE_ANDROID
|
#if JUCE_ANDROID
|
||||||
typedef CharPointer_UTF8 StringType;
|
using StringType = CharPointer_UTF8;
|
||||||
#elif JUCE_WINDOWS
|
#elif JUCE_WINDOWS
|
||||||
typedef CharPointer_UTF16 StringType;
|
using StringType = CharPointer_UTF16;
|
||||||
#else
|
#else
|
||||||
typedef CharPointer_UTF32 StringType;
|
using StringType = CharPointer_UTF32;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JUCE_MSVC
|
#ifdef JUCE_MSVC
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ public:
|
||||||
static int main (int argc, const char* argv[]);
|
static int main (int argc, const char* argv[]);
|
||||||
|
|
||||||
static void appWillTerminateByForce();
|
static void appWillTerminateByForce();
|
||||||
typedef JUCEApplicationBase* (*CreateInstanceFunction)();
|
using CreateInstanceFunction = JUCEApplicationBase* (*)();
|
||||||
static CreateInstanceFunction createInstance;
|
static CreateInstanceFunction createInstance;
|
||||||
|
|
||||||
#if JUCE_IOS
|
#if JUCE_IOS
|
||||||
|
|
|
||||||
|
|
@ -280,13 +280,13 @@ public:
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Provides the type of scoped lock to use with a CriticalSection. */
|
/** Provides the type of scoped lock to use with a CriticalSection. */
|
||||||
typedef GenericScopedLock<Lock> ScopedLockType;
|
using ScopedLockType = GenericScopedLock<Lock>;
|
||||||
|
|
||||||
/** Provides the type of scoped unlocker to use with a CriticalSection. */
|
/** Provides the type of scoped unlocker to use with a CriticalSection. */
|
||||||
typedef GenericScopedUnlock<Lock> ScopedUnlockType;
|
using ScopedUnlockType = GenericScopedUnlock<Lock>;
|
||||||
|
|
||||||
/** Provides the type of scoped try-locker to use with a CriticalSection. */
|
/** Provides the type of scoped try-locker to use with a CriticalSection. */
|
||||||
typedef GenericScopedTryLock<Lock> ScopedTryLockType;
|
using ScopedTryLockType = GenericScopedTryLock<Lock>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct BlockingMessage;
|
struct BlockingMessage;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class Timer::TimerThread : private Thread,
|
||||||
private AsyncUpdater
|
private AsyncUpdater
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef CriticalSection LockType; // (mysteriously, using a SpinLock here causes problems on some XP machines..)
|
using LockType = CriticalSection; // (mysteriously, using a SpinLock here causes problems on some XP machines..)
|
||||||
|
|
||||||
TimerThread() : Thread ("JUCE Timer")
|
TimerThread() : Thread ("JUCE Timer")
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ public:
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** This type will be double if the Point's type is double, otherwise it will be float. */
|
/** This type will be double if the Point's type is double, otherwise it will be float. */
|
||||||
typedef typename TypeHelpers::SmallestFloatType<ValueType>::type FloatType;
|
using FloatType = typename TypeHelpers::SmallestFloatType<ValueType>::type;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Returns the straight-line distance between this point and the origin. */
|
/** Returns the straight-line distance between this point and the origin. */
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ template <typename ValueType>
|
||||||
class RectangleList final
|
class RectangleList final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Rectangle<ValueType> RectangleType;
|
using RectangleType = Rectangle<ValueType>;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Creates an empty RectangleList */
|
/** Creates an empty RectangleList */
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
namespace juce
|
namespace juce
|
||||||
{
|
{
|
||||||
|
|
||||||
ImagePixelData::ImagePixelData (const Image::PixelFormat format, const int w, const int h)
|
ImagePixelData::ImagePixelData (Image::PixelFormat format, int w, int h)
|
||||||
: pixelFormat (format), width (w), height (h)
|
: pixelFormat (format), width (w), height (h)
|
||||||
{
|
{
|
||||||
jassert (format == Image::RGB || format == Image::ARGB || format == Image::SingleChannel);
|
jassert (format == Image::RGB || format == Image::ARGB || format == Image::SingleChannel);
|
||||||
|
|
@ -82,9 +82,9 @@ Image ImageType::convert (const Image& source) const
|
||||||
class SoftwarePixelData : public ImagePixelData
|
class SoftwarePixelData : public ImagePixelData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SoftwarePixelData (const Image::PixelFormat format_, const int w, const int h, const bool clearImage)
|
SoftwarePixelData (Image::PixelFormat formatToUse, int w, int h, bool clearImage)
|
||||||
: ImagePixelData (format_, w, h),
|
: ImagePixelData (formatToUse, w, h),
|
||||||
pixelStride (format_ == Image::RGB ? 3 : ((format_ == Image::ARGB) ? 4 : 1)),
|
pixelStride (formatToUse == Image::RGB ? 3 : ((formatToUse == Image::ARGB) ? 4 : 1)),
|
||||||
lineStride ((pixelStride * jmax (1, w) + 3) & ~3)
|
lineStride ((pixelStride * jmax (1, w) + 3) & ~3)
|
||||||
{
|
{
|
||||||
imageData.allocate ((size_t) lineStride * (size_t) jmax (1, h), clearImage);
|
imageData.allocate ((size_t) lineStride * (size_t) jmax (1, h), clearImage);
|
||||||
|
|
@ -156,7 +156,7 @@ ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int widt
|
||||||
class SubsectionPixelData : public ImagePixelData
|
class SubsectionPixelData : public ImagePixelData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SubsectionPixelData (ImagePixelData* const im, const Rectangle<int>& r)
|
SubsectionPixelData (ImagePixelData* im, Rectangle<int> r)
|
||||||
: ImagePixelData (im->pixelFormat, r.getWidth(), r.getHeight()),
|
: ImagePixelData (im->pixelFormat, r.getWidth(), r.getHeight()),
|
||||||
sourceImage (im), area (r)
|
sourceImage (im), area (r)
|
||||||
{
|
{
|
||||||
|
|
@ -211,8 +211,12 @@ Image Image::getClippedImage (const Rectangle<int>& area) const
|
||||||
if (area.contains (getBounds()))
|
if (area.contains (getBounds()))
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
const Rectangle<int> validArea (area.getIntersection (getBounds()));
|
auto validArea = area.getIntersection (getBounds());
|
||||||
return Image (validArea.isEmpty() ? nullptr : new SubsectionPixelData (image, validArea));
|
|
||||||
|
if (validArea.isEmpty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return Image (new SubsectionPixelData (image, validArea));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -221,17 +225,17 @@ Image::Image() noexcept
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::Image (ImagePixelData* const instance) noexcept
|
Image::Image (ImagePixelData* instance) noexcept
|
||||||
: image (instance)
|
: image (instance)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::Image (const PixelFormat format, int width, int height, bool clearImage)
|
Image::Image (PixelFormat format, int width, int height, bool clearImage)
|
||||||
: image (NativeImageType().create (format, width, height, clearImage))
|
: image (NativeImageType().create (format, width, height, clearImage))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::Image (const PixelFormat format, int width, int height, bool clearImage, const ImageType& type)
|
Image::Image (PixelFormat format, int width, int height, bool clearImage, const ImageType& type)
|
||||||
: image (type.create (format, width, height, clearImage))
|
: image (type.create (format, width, height, clearImage))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -290,10 +294,10 @@ Image Image::createCopy() const
|
||||||
if (image != nullptr)
|
if (image != nullptr)
|
||||||
return Image (image->clone());
|
return Image (image->clone());
|
||||||
|
|
||||||
return Image();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Image Image::rescaled (const int newWidth, const int newHeight, const Graphics::ResamplingQuality quality) const
|
Image Image::rescaled (int newWidth, int newHeight, Graphics::ResamplingQuality quality) const
|
||||||
{
|
{
|
||||||
if (image == nullptr || (image->width == newWidth && image->height == newHeight))
|
if (image == nullptr || (image->width == newWidth && image->height == newHeight))
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -313,7 +317,7 @@ Image Image::convertedToFormat (PixelFormat newFormat) const
|
||||||
if (image == nullptr || newFormat == image->pixelFormat)
|
if (image == nullptr || newFormat == image->pixelFormat)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
const int w = image->width, h = image->height;
|
auto w = image->width, h = image->height;
|
||||||
|
|
||||||
const std::unique_ptr<ImageType> type (image->createType());
|
const std::unique_ptr<ImageType> type (image->createType());
|
||||||
Image newImage (type->create (newFormat, w, h, false));
|
Image newImage (type->create (newFormat, w, h, false));
|
||||||
|
|
@ -331,8 +335,8 @@ Image Image::convertedToFormat (PixelFormat newFormat) const
|
||||||
|
|
||||||
for (int y = 0; y < h; ++y)
|
for (int y = 0; y < h; ++y)
|
||||||
{
|
{
|
||||||
const PixelARGB* const src = (const PixelARGB*) srcData.getLinePointer (y);
|
auto src = reinterpret_cast<const PixelARGB*> (srcData.getLinePointer (y));
|
||||||
uint8* const dst = destData.getLinePointer (y);
|
auto dst = destData.getLinePointer (y);
|
||||||
|
|
||||||
for (int x = 0; x < w; ++x)
|
for (int x = 0; x < w; ++x)
|
||||||
dst[x] = src[x].getAlpha();
|
dst[x] = src[x].getAlpha();
|
||||||
|
|
@ -346,8 +350,8 @@ Image Image::convertedToFormat (PixelFormat newFormat) const
|
||||||
|
|
||||||
for (int y = 0; y < h; ++y)
|
for (int y = 0; y < h; ++y)
|
||||||
{
|
{
|
||||||
const PixelAlpha* const src = (const PixelAlpha*) srcData.getLinePointer (y);
|
auto src = reinterpret_cast<const PixelAlpha*> (srcData.getLinePointer (y));
|
||||||
PixelARGB* const dst = (PixelARGB*) destData.getLinePointer (y);
|
auto dst = reinterpret_cast<PixelARGB*> (destData.getLinePointer (y));
|
||||||
|
|
||||||
for (int x = 0; x < w; ++x)
|
for (int x = 0; x < w; ++x)
|
||||||
dst[x].set (src[x]);
|
dst[x].set (src[x]);
|
||||||
|
|
@ -371,7 +375,7 @@ NamedValueSet* Image::getProperties() const
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
Image::BitmapData::BitmapData (Image& im, const int x, const int y, const int w, const int h, BitmapData::ReadWriteMode mode)
|
Image::BitmapData::BitmapData (Image& im, int x, int y, int w, int h, BitmapData::ReadWriteMode mode)
|
||||||
: width (w), height (h)
|
: width (w), height (h)
|
||||||
{
|
{
|
||||||
// The BitmapData class must be given a valid image, and a valid rectangle within it!
|
// The BitmapData class must be given a valid image, and a valid rectangle within it!
|
||||||
|
|
@ -382,7 +386,7 @@ Image::BitmapData::BitmapData (Image& im, const int x, const int y, const int w,
|
||||||
jassert (data != nullptr && pixelStride > 0 && lineStride != 0);
|
jassert (data != nullptr && pixelStride > 0 && lineStride != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::BitmapData::BitmapData (const Image& im, const int x, const int y, const int w, const int h)
|
Image::BitmapData::BitmapData (const Image& im, int x, int y, int w, int h)
|
||||||
: width (w), height (h)
|
: width (w), height (h)
|
||||||
{
|
{
|
||||||
// The BitmapData class must be given a valid image, and a valid rectangle within it!
|
// The BitmapData class must be given a valid image, and a valid rectangle within it!
|
||||||
|
|
@ -408,11 +412,11 @@ Image::BitmapData::~BitmapData()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Colour Image::BitmapData::getPixelColour (const int x, const int y) const noexcept
|
Colour Image::BitmapData::getPixelColour (int x, int y) const noexcept
|
||||||
{
|
{
|
||||||
jassert (isPositiveAndBelow (x, width) && isPositiveAndBelow (y, height));
|
jassert (isPositiveAndBelow (x, width) && isPositiveAndBelow (y, height));
|
||||||
|
|
||||||
const uint8* const pixel = getPixelPointer (x, y);
|
auto pixel = getPixelPointer (x, y);
|
||||||
|
|
||||||
switch (pixelFormat)
|
switch (pixelFormat)
|
||||||
{
|
{
|
||||||
|
|
@ -422,15 +426,15 @@ Colour Image::BitmapData::getPixelColour (const int x, const int y) const noexce
|
||||||
default: jassertfalse; break;
|
default: jassertfalse; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Colour();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::BitmapData::setPixelColour (const int x, const int y, Colour colour) const noexcept
|
void Image::BitmapData::setPixelColour (int x, int y, Colour colour) const noexcept
|
||||||
{
|
{
|
||||||
jassert (isPositiveAndBelow (x, width) && isPositiveAndBelow (y, height));
|
jassert (isPositiveAndBelow (x, width) && isPositiveAndBelow (y, height));
|
||||||
|
|
||||||
uint8* const pixel = getPixelPointer (x, y);
|
auto pixel = getPixelPointer (x, y);
|
||||||
const PixelARGB col (colour.getPixelARGB());
|
auto col = colour.getPixelARGB();
|
||||||
|
|
||||||
switch (pixelFormat)
|
switch (pixelFormat)
|
||||||
{
|
{
|
||||||
|
|
@ -453,7 +457,7 @@ void Image::clear (const Rectangle<int>& area, Colour colourToClearTo)
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
Colour Image::getPixelAt (const int x, const int y) const
|
Colour Image::getPixelAt (int x, int y) const
|
||||||
{
|
{
|
||||||
if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight()))
|
if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight()))
|
||||||
{
|
{
|
||||||
|
|
@ -461,10 +465,10 @@ Colour Image::getPixelAt (const int x, const int y) const
|
||||||
return srcData.getPixelColour (0, 0);
|
return srcData.getPixelColour (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Colour();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::setPixelAt (const int x, const int y, Colour colour)
|
void Image::setPixelAt (int x, int y, Colour colour)
|
||||||
{
|
{
|
||||||
if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight()))
|
if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight()))
|
||||||
{
|
{
|
||||||
|
|
@ -473,7 +477,7 @@ void Image::setPixelAt (const int x, const int y, Colour colour)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::multiplyAlphaAt (const int x, const int y, const float multiplier)
|
void Image::multiplyAlphaAt (int x, int y, float multiplier)
|
||||||
{
|
{
|
||||||
if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight())
|
if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight())
|
||||||
&& hasAlphaChannel())
|
&& hasAlphaChannel())
|
||||||
|
|
@ -481,7 +485,7 @@ void Image::multiplyAlphaAt (const int x, const int y, const float multiplier)
|
||||||
const BitmapData destData (*this, x, y, 1, 1, BitmapData::readWrite);
|
const BitmapData destData (*this, x, y, 1, 1, BitmapData::readWrite);
|
||||||
|
|
||||||
if (isARGB())
|
if (isARGB())
|
||||||
((PixelARGB*) destData.data)->multiplyAlpha (multiplier);
|
reinterpret_cast<PixelARGB*> (destData.data)->multiplyAlpha (multiplier);
|
||||||
else
|
else
|
||||||
*(destData.data) = (uint8) (*(destData.data) * multiplier);
|
*(destData.data) = (uint8) (*(destData.data) * multiplier);
|
||||||
}
|
}
|
||||||
|
|
@ -495,11 +499,11 @@ struct PixelIterator
|
||||||
{
|
{
|
||||||
for (int y = 0; y < data.height; ++y)
|
for (int y = 0; y < data.height; ++y)
|
||||||
{
|
{
|
||||||
uint8* p = data.getLinePointer (y);
|
auto p = data.getLinePointer (y);
|
||||||
|
|
||||||
for (int x = 0; x < data.width; ++x)
|
for (int x = 0; x < data.width; ++x)
|
||||||
{
|
{
|
||||||
pixelOp (*(PixelType*) p);
|
pixelOp (*reinterpret_cast<PixelType*> (p));
|
||||||
p += data.pixelStride;
|
p += data.pixelStride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -529,7 +533,7 @@ struct AlphaMultiplyOp
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Image::multiplyAllAlphas (const float amountToMultiplyBy)
|
void Image::multiplyAllAlphas (float amountToMultiplyBy)
|
||||||
{
|
{
|
||||||
jassert (hasAlphaChannel());
|
jassert (hasAlphaChannel());
|
||||||
|
|
||||||
|
|
@ -555,11 +559,11 @@ void Image::desaturate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::createSolidAreaMask (RectangleList<int>& result, const float alphaThreshold) const
|
void Image::createSolidAreaMask (RectangleList<int>& result, float alphaThreshold) const
|
||||||
{
|
{
|
||||||
if (hasAlphaChannel())
|
if (hasAlphaChannel())
|
||||||
{
|
{
|
||||||
const uint8 threshold = (uint8) jlimit (0, 255, roundToInt (alphaThreshold * 255.0f));
|
auto threshold = (uint8) jlimit (0, 255, roundToInt (alphaThreshold * 255.0f));
|
||||||
SparseSet<int> pixelsOnRow;
|
SparseSet<int> pixelsOnRow;
|
||||||
|
|
||||||
const BitmapData srcData (*this, 0, 0, getWidth(), getHeight());
|
const BitmapData srcData (*this, 0, 0, getWidth(), getHeight());
|
||||||
|
|
@ -567,13 +571,13 @@ void Image::createSolidAreaMask (RectangleList<int>& result, const float alphaTh
|
||||||
for (int y = 0; y < srcData.height; ++y)
|
for (int y = 0; y < srcData.height; ++y)
|
||||||
{
|
{
|
||||||
pixelsOnRow.clear();
|
pixelsOnRow.clear();
|
||||||
const uint8* lineData = srcData.getLinePointer (y);
|
auto lineData = srcData.getLinePointer (y);
|
||||||
|
|
||||||
if (isARGB())
|
if (isARGB())
|
||||||
{
|
{
|
||||||
for (int x = 0; x < srcData.width; ++x)
|
for (int x = 0; x < srcData.width; ++x)
|
||||||
{
|
{
|
||||||
if (((const PixelARGB*) lineData)->getAlpha() >= threshold)
|
if (reinterpret_cast<const PixelARGB*> (lineData)->getAlpha() >= threshold)
|
||||||
pixelsOnRow.addRange (Range<int> (x, x + 1));
|
pixelsOnRow.addRange (Range<int> (x, x + 1));
|
||||||
|
|
||||||
lineData += srcData.pixelStride;
|
lineData += srcData.pixelStride;
|
||||||
|
|
@ -592,7 +596,7 @@ void Image::createSolidAreaMask (RectangleList<int>& result, const float alphaTh
|
||||||
|
|
||||||
for (int i = 0; i < pixelsOnRow.getNumRanges(); ++i)
|
for (int i = 0; i < pixelsOnRow.getNumRanges(); ++i)
|
||||||
{
|
{
|
||||||
const Range<int> range (pixelsOnRow.getRange (i));
|
auto range = pixelsOnRow.getRange (i);
|
||||||
result.add (Rectangle<int> (range.getStart(), y, range.getLength(), 1));
|
result.add (Rectangle<int> (range.getStart(), y, range.getLength(), 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -645,15 +649,15 @@ void Image::moveImageSection (int dx, int dy,
|
||||||
|
|
||||||
if (w > 0 && h > 0)
|
if (w > 0 && h > 0)
|
||||||
{
|
{
|
||||||
const int maxX = jmax (dx, sx) + w;
|
auto maxX = jmax (dx, sx) + w;
|
||||||
const int maxY = jmax (dy, sy) + h;
|
auto maxY = jmax (dy, sy) + h;
|
||||||
|
|
||||||
const BitmapData destData (*this, minX, minY, maxX - minX, maxY - minY, BitmapData::readWrite);
|
const BitmapData destData (*this, minX, minY, maxX - minX, maxY - minY, BitmapData::readWrite);
|
||||||
|
|
||||||
uint8* dst = destData.getPixelPointer (dx - minX, dy - minY);
|
auto dst = destData.getPixelPointer (dx - minX, dy - minY);
|
||||||
const uint8* src = destData.getPixelPointer (sx - minX, sy - minY);
|
auto src = destData.getPixelPointer (sx - minX, sy - minY);
|
||||||
|
|
||||||
const size_t lineSize = (size_t) (destData.pixelStride * w);
|
auto lineSize = (size_t) (destData.pixelStride * w);
|
||||||
|
|
||||||
if (dy > sy)
|
if (dy > sy)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,13 @@
|
||||||
namespace juce
|
namespace juce
|
||||||
{
|
{
|
||||||
|
|
||||||
struct FTLibWrapper : public ReferenceCountedObject
|
struct FTLibWrapper : public ReferenceCountedObject
|
||||||
{
|
{
|
||||||
FTLibWrapper() : library (0)
|
FTLibWrapper()
|
||||||
{
|
{
|
||||||
if (FT_Init_FreeType (&library) != 0)
|
if (FT_Init_FreeType (&library) != 0)
|
||||||
{
|
{
|
||||||
library = 0;
|
library = {};
|
||||||
DBG ("Failed to initialize FreeType");
|
DBG ("Failed to initialize FreeType");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +44,7 @@ struct FTLibWrapper : public ReferenceCountedObject
|
||||||
FT_Done_FreeType (library);
|
FT_Done_FreeType (library);
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Library library;
|
FT_Library library = {};
|
||||||
|
|
||||||
using Ptr = ReferenceCountedObjectPtr<FTLibWrapper>;
|
using Ptr = ReferenceCountedObjectPtr<FTLibWrapper>;
|
||||||
|
|
||||||
|
|
@ -55,18 +55,18 @@ struct FTLibWrapper : public ReferenceCountedObject
|
||||||
struct FTFaceWrapper : public ReferenceCountedObject
|
struct FTFaceWrapper : public ReferenceCountedObject
|
||||||
{
|
{
|
||||||
FTFaceWrapper (const FTLibWrapper::Ptr& ftLib, const File& file, int faceIndex)
|
FTFaceWrapper (const FTLibWrapper::Ptr& ftLib, const File& file, int faceIndex)
|
||||||
: face (0), library (ftLib)
|
: library (ftLib)
|
||||||
{
|
{
|
||||||
if (FT_New_Face (ftLib->library, file.getFullPathName().toUTF8(), faceIndex, &face) != 0)
|
if (FT_New_Face (ftLib->library, file.getFullPathName().toUTF8(), faceIndex, &face) != 0)
|
||||||
face = 0;
|
face = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
FTFaceWrapper (const FTLibWrapper::Ptr& ftLib, const void* data, size_t dataSize, int faceIndex)
|
FTFaceWrapper (const FTLibWrapper::Ptr& ftLib, const void* data, size_t dataSize, int faceIndex)
|
||||||
: face (0), library (ftLib), savedFaceData (data, dataSize)
|
: library (ftLib), savedFaceData (data, dataSize)
|
||||||
{
|
{
|
||||||
if (FT_New_Memory_Face (ftLib->library, (const FT_Byte*) savedFaceData.getData(),
|
if (FT_New_Memory_Face (ftLib->library, (const FT_Byte*) savedFaceData.getData(),
|
||||||
(FT_Long) savedFaceData.getSize(), faceIndex, &face) != 0)
|
(FT_Long) savedFaceData.getSize(), faceIndex, &face) != 0)
|
||||||
face = 0;
|
face = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
~FTFaceWrapper()
|
~FTFaceWrapper()
|
||||||
|
|
@ -75,7 +75,7 @@ struct FTFaceWrapper : public ReferenceCountedObject
|
||||||
FT_Done_Face (face);
|
FT_Done_Face (face);
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Face face;
|
FT_Face face = {};
|
||||||
FTLibWrapper::Ptr library;
|
FTLibWrapper::Ptr library;
|
||||||
MemoryBlock savedFaceData;
|
MemoryBlock savedFaceData;
|
||||||
|
|
||||||
|
|
@ -101,7 +101,7 @@ public:
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
struct KnownTypeface
|
struct KnownTypeface
|
||||||
{
|
{
|
||||||
KnownTypeface (const File& f, const int index, const FTFaceWrapper& face)
|
KnownTypeface (const File& f, int index, const FTFaceWrapper& face)
|
||||||
: file (f),
|
: file (f),
|
||||||
family (face.face->family_name),
|
family (face.face->family_name),
|
||||||
style (face.face->style_name),
|
style (face.face->style_name),
|
||||||
|
|
@ -141,10 +141,10 @@ public:
|
||||||
|
|
||||||
FTFaceWrapper::Ptr createFace (const String& fontName, const String& fontStyle)
|
FTFaceWrapper::Ptr createFace (const String& fontName, const String& fontStyle)
|
||||||
{
|
{
|
||||||
const KnownTypeface* ftFace = matchTypeface (fontName, fontStyle);
|
auto ftFace = matchTypeface (fontName, fontStyle);
|
||||||
|
|
||||||
if (ftFace == nullptr) ftFace = matchTypeface (fontName, "Regular");
|
if (ftFace == nullptr) ftFace = matchTypeface (fontName, "Regular");
|
||||||
if (ftFace == nullptr) ftFace = matchTypeface (fontName, String());
|
if (ftFace == nullptr) ftFace = matchTypeface (fontName, {});
|
||||||
|
|
||||||
if (ftFace != nullptr)
|
if (ftFace != nullptr)
|
||||||
return createFace (ftFace->file, ftFace->faceIndex);
|
return createFace (ftFace->file, ftFace->faceIndex);
|
||||||
|
|
@ -157,8 +157,8 @@ public:
|
||||||
{
|
{
|
||||||
StringArray s;
|
StringArray s;
|
||||||
|
|
||||||
for (int i = 0; i < faces.size(); ++i)
|
for (auto* face : faces)
|
||||||
s.addIfNotAlreadyThere (faces.getUnchecked(i)->family);
|
s.addIfNotAlreadyThere (face->family);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
@ -167,28 +167,27 @@ public:
|
||||||
{
|
{
|
||||||
int i = styles.indexOf ("Regular", true);
|
int i = styles.indexOf ("Regular", true);
|
||||||
|
|
||||||
if (i < 0)
|
if (i >= 0)
|
||||||
for (i = 0; i < styles.size(); ++i)
|
return i;
|
||||||
if (! (styles[i].containsIgnoreCase ("Bold") || styles[i].containsIgnoreCase ("Italic")))
|
|
||||||
break;
|
|
||||||
|
|
||||||
return i;
|
for (i = 0; i < styles.size(); ++i)
|
||||||
|
if (! (styles[i].containsIgnoreCase ("Bold") || styles[i].containsIgnoreCase ("Italic")))
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringArray findAllTypefaceStyles (const String& family) const
|
StringArray findAllTypefaceStyles (const String& family) const
|
||||||
{
|
{
|
||||||
StringArray s;
|
StringArray s;
|
||||||
|
|
||||||
for (int i = 0; i < faces.size(); ++i)
|
for (auto* face : faces)
|
||||||
{
|
|
||||||
const KnownTypeface* const face = faces.getUnchecked(i);
|
|
||||||
|
|
||||||
if (face->family == family)
|
if (face->family == family)
|
||||||
s.addIfNotAlreadyThere (face->style);
|
s.addIfNotAlreadyThere (face->style);
|
||||||
}
|
|
||||||
|
|
||||||
// try to get a regular style to be first in the list
|
// try to get a regular style to be first in the list
|
||||||
const int regular = indexOfRegularStyle (s);
|
auto regular = indexOfRegularStyle (s);
|
||||||
|
|
||||||
if (regular > 0)
|
if (regular > 0)
|
||||||
s.strings.swap (0, regular);
|
s.strings.swap (0, regular);
|
||||||
|
|
||||||
|
|
@ -197,10 +196,9 @@ public:
|
||||||
|
|
||||||
void scanFontPaths (const StringArray& paths)
|
void scanFontPaths (const StringArray& paths)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < paths.size(); ++i)
|
for (auto& path : paths)
|
||||||
{
|
{
|
||||||
DirectoryIterator iter (File::getCurrentWorkingDirectory()
|
DirectoryIterator iter (File::getCurrentWorkingDirectory().getChildFile (path), true);
|
||||||
.getChildFile (paths[i]), true);
|
|
||||||
|
|
||||||
while (iter.next())
|
while (iter.next())
|
||||||
if (iter.getFile().hasFileExtension ("ttf;pfb;pcf;otf"))
|
if (iter.getFile().hasFileExtension ("ttf;pfb;pcf;otf"))
|
||||||
|
|
@ -210,23 +208,23 @@ public:
|
||||||
|
|
||||||
void getMonospacedNames (StringArray& monoSpaced) const
|
void getMonospacedNames (StringArray& monoSpaced) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < faces.size(); ++i)
|
for (auto* face : faces)
|
||||||
if (faces.getUnchecked(i)->isMonospaced)
|
if (face->isMonospaced)
|
||||||
monoSpaced.addIfNotAlreadyThere (faces.getUnchecked(i)->family);
|
monoSpaced.addIfNotAlreadyThere (face->family);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getSerifNames (StringArray& serif) const
|
void getSerifNames (StringArray& serif) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < faces.size(); ++i)
|
for (auto* face : faces)
|
||||||
if (! faces.getUnchecked(i)->isSansSerif)
|
if (! (face->isSansSerif || face->isMonospaced))
|
||||||
serif.addIfNotAlreadyThere (faces.getUnchecked(i)->family);
|
serif.addIfNotAlreadyThere (face->family);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getSansSerifNames (StringArray& sansSerif) const
|
void getSansSerifNames (StringArray& sansSerif) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < faces.size(); ++i)
|
for (auto* face : faces)
|
||||||
if (faces.getUnchecked(i)->isSansSerif)
|
if (face->isSansSerif)
|
||||||
sansSerif.addIfNotAlreadyThere (faces.getUnchecked(i)->family);
|
sansSerif.addIfNotAlreadyThere (face->family);
|
||||||
}
|
}
|
||||||
|
|
||||||
JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (FTTypefaceList)
|
JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (FTTypefaceList)
|
||||||
|
|
@ -262,14 +260,10 @@ private:
|
||||||
|
|
||||||
const KnownTypeface* matchTypeface (const String& familyName, const String& style) const noexcept
|
const KnownTypeface* matchTypeface (const String& familyName, const String& style) const noexcept
|
||||||
{
|
{
|
||||||
for (int i = 0; i < faces.size(); ++i)
|
for (auto* face : faces)
|
||||||
{
|
|
||||||
const KnownTypeface* const face = faces.getUnchecked(i);
|
|
||||||
|
|
||||||
if (face->family == familyName
|
if (face->family == familyName
|
||||||
&& (face->style.equalsIgnoreCase (style) || style.isEmpty()))
|
&& (face->style.equalsIgnoreCase (style) || style.isEmpty()))
|
||||||
return face;
|
return face;
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -278,8 +272,8 @@ private:
|
||||||
{
|
{
|
||||||
static const char* sansNames[] = { "Sans", "Verdana", "Arial", "Ubuntu" };
|
static const char* sansNames[] = { "Sans", "Verdana", "Arial", "Ubuntu" };
|
||||||
|
|
||||||
for (int i = 0; i < numElementsInArray (sansNames); ++i)
|
for (auto* name : sansNames)
|
||||||
if (family.containsIgnoreCase (sansNames[i]))
|
if (family.containsIgnoreCase (name))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -323,13 +317,13 @@ public:
|
||||||
{
|
{
|
||||||
if (faceWrapper != nullptr)
|
if (faceWrapper != nullptr)
|
||||||
{
|
{
|
||||||
FT_Face face = faceWrapper->face;
|
auto face = faceWrapper->face;
|
||||||
const unsigned int glyphIndex = FT_Get_Char_Index (face, (FT_ULong) character);
|
auto glyphIndex = FT_Get_Char_Index (face, (FT_ULong) character);
|
||||||
|
|
||||||
if (FT_Load_Glyph (face, glyphIndex, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM | FT_LOAD_NO_HINTING) == 0
|
if (FT_Load_Glyph (face, glyphIndex, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM | FT_LOAD_NO_HINTING) == 0
|
||||||
&& face->glyph->format == ft_glyph_format_outline)
|
&& face->glyph->format == ft_glyph_format_outline)
|
||||||
{
|
{
|
||||||
const float scale = 1.0f / (float) (face->ascender - face->descender);
|
auto scale = 1.0f / (float) (face->ascender - face->descender);
|
||||||
Path destShape;
|
Path destShape;
|
||||||
|
|
||||||
if (getGlyphShape (destShape, face->glyph->outline, scale))
|
if (getGlyphShape (destShape, face->glyph->outline, scale))
|
||||||
|
|
@ -350,12 +344,12 @@ public:
|
||||||
private:
|
private:
|
||||||
FTFaceWrapper::Ptr faceWrapper;
|
FTFaceWrapper::Ptr faceWrapper;
|
||||||
|
|
||||||
bool getGlyphShape (Path& destShape, const FT_Outline& outline, const float scaleX)
|
bool getGlyphShape (Path& destShape, const FT_Outline& outline, float scaleX)
|
||||||
{
|
{
|
||||||
const float scaleY = -scaleX;
|
auto scaleY = -scaleX;
|
||||||
const short* const contours = outline.contours;
|
auto* contours = outline.contours;
|
||||||
const char* const tags = outline.tags;
|
auto* tags = outline.tags;
|
||||||
const FT_Vector* const points = outline.points;
|
auto* points = outline.points;
|
||||||
|
|
||||||
for (int c = 0; c < outline.n_contours; ++c)
|
for (int c = 0; c < outline.n_contours; ++c)
|
||||||
{
|
{
|
||||||
|
|
@ -364,15 +358,15 @@ private:
|
||||||
|
|
||||||
for (int p = startPoint; p <= endPoint; ++p)
|
for (int p = startPoint; p <= endPoint; ++p)
|
||||||
{
|
{
|
||||||
const float x = scaleX * points[p].x;
|
auto x = scaleX * points[p].x;
|
||||||
const float y = scaleY * points[p].y;
|
auto y = scaleY * points[p].y;
|
||||||
|
|
||||||
if (p == startPoint)
|
if (p == startPoint)
|
||||||
{
|
{
|
||||||
if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic)
|
if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic)
|
||||||
{
|
{
|
||||||
float x2 = scaleX * points [endPoint].x;
|
auto x2 = scaleX * points [endPoint].x;
|
||||||
float y2 = scaleY * points [endPoint].y;
|
auto y2 = scaleY * points [endPoint].y;
|
||||||
|
|
||||||
if (FT_CURVE_TAG (tags[endPoint]) != FT_Curve_Tag_On)
|
if (FT_CURVE_TAG (tags[endPoint]) != FT_Curve_Tag_On)
|
||||||
{
|
{
|
||||||
|
|
@ -396,8 +390,8 @@ private:
|
||||||
else if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic)
|
else if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic)
|
||||||
{
|
{
|
||||||
const int nextIndex = (p == endPoint) ? startPoint : p + 1;
|
const int nextIndex = (p == endPoint) ? startPoint : p + 1;
|
||||||
float x2 = scaleX * points [nextIndex].x;
|
auto x2 = scaleX * points [nextIndex].x;
|
||||||
float y2 = scaleY * points [nextIndex].y;
|
auto y2 = scaleY * points [nextIndex].y;
|
||||||
|
|
||||||
if (FT_CURVE_TAG (tags [nextIndex]) == FT_Curve_Tag_Conic)
|
if (FT_CURVE_TAG (tags [nextIndex]) == FT_Curve_Tag_Conic)
|
||||||
{
|
{
|
||||||
|
|
@ -421,10 +415,10 @@ private:
|
||||||
|| FT_CURVE_TAG (tags[next2]) != FT_Curve_Tag_On)
|
|| FT_CURVE_TAG (tags[next2]) != FT_Curve_Tag_On)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const float x2 = scaleX * points [next1].x;
|
auto x2 = scaleX * points [next1].x;
|
||||||
const float y2 = scaleY * points [next1].y;
|
auto y2 = scaleY * points [next1].y;
|
||||||
const float x3 = scaleX * points [next2].x;
|
auto x3 = scaleX * points [next2].x;
|
||||||
const float y3 = scaleY * points [next2].y;
|
auto y3 = scaleY * points [next2].y;
|
||||||
|
|
||||||
destShape.cubicTo (x, y, x2, y2, x3, y3);
|
destShape.cubicTo (x, y, x2, y2, x3, y3);
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
@ -439,10 +433,10 @@ private:
|
||||||
|
|
||||||
void addKerning (FT_Face face, const uint32 character, const uint32 glyphIndex)
|
void addKerning (FT_Face face, const uint32 character, const uint32 glyphIndex)
|
||||||
{
|
{
|
||||||
const float height = (float) (face->ascender - face->descender);
|
auto height = (float) (face->ascender - face->descender);
|
||||||
|
|
||||||
uint32 rightGlyphIndex;
|
uint32 rightGlyphIndex;
|
||||||
FT_ULong rightCharCode = FT_Get_First_Char (face, &rightGlyphIndex);
|
auto rightCharCode = FT_Get_First_Char (face, &rightGlyphIndex);
|
||||||
|
|
||||||
while (rightGlyphIndex != 0)
|
while (rightGlyphIndex != 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -761,7 +761,7 @@ void Direct2DLowLevelGraphicsContext::drawImage (const Image& image, const Affin
|
||||||
pimpl->renderingTarget->SetTransform (D2D1::IdentityMatrix());
|
pimpl->renderingTarget->SetTransform (D2D1::IdentityMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Direct2DLowLevelGraphicsContext::drawLine (const Line <float>& line)
|
void Direct2DLowLevelGraphicsContext::drawLine (const Line<float>& line)
|
||||||
{
|
{
|
||||||
// xxx doesn't seem to be correctly aligned, may need nudging by 0.5 to match the software renderer's behaviour
|
// xxx doesn't seem to be correctly aligned, may need nudging by 0.5 to match the software renderer's behaviour
|
||||||
pimpl->renderingTarget->SetTransform (transformToMatrix (currentState->transform));
|
pimpl->renderingTarget->SetTransform (transformToMatrix (currentState->transform));
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,7 @@ namespace DirectWriteTypeLayout
|
||||||
CustomDirectWriteTextRenderer (IDWriteFontCollection& fonts, const AttributedString& as)
|
CustomDirectWriteTextRenderer (IDWriteFontCollection& fonts, const AttributedString& as)
|
||||||
: ComBaseClassHelper<IDWriteTextRenderer> (0),
|
: ComBaseClassHelper<IDWriteTextRenderer> (0),
|
||||||
attributedString (as),
|
attributedString (as),
|
||||||
fontCollection (fonts),
|
fontCollection (fonts)
|
||||||
currentLine (-1),
|
|
||||||
lastOriginY (-10000.0f)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +87,7 @@ namespace DirectWriteTypeLayout
|
||||||
DWRITE_GLYPH_RUN const* glyphRun, DWRITE_GLYPH_RUN_DESCRIPTION const* runDescription,
|
DWRITE_GLYPH_RUN const* glyphRun, DWRITE_GLYPH_RUN_DESCRIPTION const* runDescription,
|
||||||
IUnknown* clientDrawingEffect) override
|
IUnknown* clientDrawingEffect) override
|
||||||
{
|
{
|
||||||
TextLayout* const layout = static_cast<TextLayout*> (clientDrawingContext);
|
auto layout = static_cast<TextLayout*> (clientDrawingContext);
|
||||||
|
|
||||||
if (! (baselineOriginY >= -1.0e10f && baselineOriginY <= 1.0e10f))
|
if (! (baselineOriginY >= -1.0e10f && baselineOriginY <= 1.0e10f))
|
||||||
baselineOriginY = 0; // DirectWrite sometimes sends NaNs in this parameter
|
baselineOriginY = 0; // DirectWrite sometimes sends NaNs in this parameter
|
||||||
|
|
@ -102,14 +100,14 @@ namespace DirectWriteTypeLayout
|
||||||
if (currentLine >= layout->getNumLines())
|
if (currentLine >= layout->getNumLines())
|
||||||
{
|
{
|
||||||
jassert (currentLine == layout->getNumLines());
|
jassert (currentLine == layout->getNumLines());
|
||||||
TextLayout::Line* const line = new TextLayout::Line();
|
auto line = new TextLayout::Line();
|
||||||
layout->addLine (line);
|
layout->addLine (line);
|
||||||
|
|
||||||
line->lineOrigin = Point<float> (baselineOriginX, baselineOriginY);
|
line->lineOrigin = Point<float> (baselineOriginX, baselineOriginY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextLayout::Line& glyphLine = layout->getLine (currentLine);
|
auto& glyphLine = layout->getLine (currentLine);
|
||||||
|
|
||||||
DWRITE_FONT_METRICS dwFontMetrics;
|
DWRITE_FONT_METRICS dwFontMetrics;
|
||||||
glyphRun->fontFace->GetMetrics (&dwFontMetrics);
|
glyphRun->fontFace->GetMetrics (&dwFontMetrics);
|
||||||
|
|
@ -117,27 +115,27 @@ namespace DirectWriteTypeLayout
|
||||||
glyphLine.ascent = jmax (glyphLine.ascent, scaledFontSize (dwFontMetrics.ascent, dwFontMetrics, *glyphRun));
|
glyphLine.ascent = jmax (glyphLine.ascent, scaledFontSize (dwFontMetrics.ascent, dwFontMetrics, *glyphRun));
|
||||||
glyphLine.descent = jmax (glyphLine.descent, scaledFontSize (dwFontMetrics.descent, dwFontMetrics, *glyphRun));
|
glyphLine.descent = jmax (glyphLine.descent, scaledFontSize (dwFontMetrics.descent, dwFontMetrics, *glyphRun));
|
||||||
|
|
||||||
TextLayout::Run* const glyphRunLayout = new TextLayout::Run (Range<int> (runDescription->textPosition,
|
auto glyphRunLayout = new TextLayout::Run (Range<int> (runDescription->textPosition,
|
||||||
runDescription->textPosition + runDescription->stringLength),
|
runDescription->textPosition + runDescription->stringLength),
|
||||||
glyphRun->glyphCount);
|
glyphRun->glyphCount);
|
||||||
glyphLine.runs.add (glyphRunLayout);
|
glyphLine.runs.add (glyphRunLayout);
|
||||||
|
|
||||||
glyphRun->fontFace->GetMetrics (&dwFontMetrics);
|
glyphRun->fontFace->GetMetrics (&dwFontMetrics);
|
||||||
const float totalHeight = std::abs ((float) dwFontMetrics.ascent) + std::abs ((float) dwFontMetrics.descent);
|
auto totalHeight = std::abs ((float) dwFontMetrics.ascent) + std::abs ((float) dwFontMetrics.descent);
|
||||||
const float fontHeightToEmSizeFactor = (float) dwFontMetrics.designUnitsPerEm / totalHeight;
|
auto fontHeightToEmSizeFactor = (float) dwFontMetrics.designUnitsPerEm / totalHeight;
|
||||||
|
|
||||||
glyphRunLayout->font = getFontForRun (*glyphRun, glyphRun->fontEmSize / fontHeightToEmSizeFactor);
|
glyphRunLayout->font = getFontForRun (*glyphRun, glyphRun->fontEmSize / fontHeightToEmSizeFactor);
|
||||||
glyphRunLayout->colour = getColourOf (static_cast<ID2D1SolidColorBrush*> (clientDrawingEffect));
|
glyphRunLayout->colour = getColourOf (static_cast<ID2D1SolidColorBrush*> (clientDrawingEffect));
|
||||||
|
|
||||||
const Point<float> lineOrigin (layout->getLine (currentLine).lineOrigin);
|
auto lineOrigin = layout->getLine (currentLine).lineOrigin;
|
||||||
float x = baselineOriginX - lineOrigin.x;
|
auto x = baselineOriginX - lineOrigin.x;
|
||||||
|
|
||||||
const float extraKerning = glyphRunLayout->font.getExtraKerningFactor()
|
auto extraKerning = glyphRunLayout->font.getExtraKerningFactor()
|
||||||
* glyphRunLayout->font.getHeight();
|
* glyphRunLayout->font.getHeight();
|
||||||
|
|
||||||
for (UINT32 i = 0; i < glyphRun->glyphCount; ++i)
|
for (UINT32 i = 0; i < glyphRun->glyphCount; ++i)
|
||||||
{
|
{
|
||||||
const float advance = glyphRun->glyphAdvances[i];
|
auto advance = glyphRun->glyphAdvances[i];
|
||||||
|
|
||||||
if ((glyphRun->bidiLevel & 1) != 0)
|
if ((glyphRun->bidiLevel & 1) != 0)
|
||||||
x -= advance + extraKerning; // RTL text
|
x -= advance + extraKerning; // RTL text
|
||||||
|
|
@ -156,8 +154,8 @@ namespace DirectWriteTypeLayout
|
||||||
private:
|
private:
|
||||||
const AttributedString& attributedString;
|
const AttributedString& attributedString;
|
||||||
IDWriteFontCollection& fontCollection;
|
IDWriteFontCollection& fontCollection;
|
||||||
int currentLine;
|
int currentLine = -1;
|
||||||
float lastOriginY;
|
float lastOriginY = -10000.0f;
|
||||||
|
|
||||||
static float scaledFontSize (int n, const DWRITE_FONT_METRICS& metrics, const DWRITE_GLYPH_RUN& glyphRun) noexcept
|
static float scaledFontSize (int n, const DWRITE_FONT_METRICS& metrics, const DWRITE_GLYPH_RUN& glyphRun) noexcept
|
||||||
{
|
{
|
||||||
|
|
@ -177,15 +175,15 @@ namespace DirectWriteTypeLayout
|
||||||
{
|
{
|
||||||
for (int i = 0; i < attributedString.getNumAttributes(); ++i)
|
for (int i = 0; i < attributedString.getNumAttributes(); ++i)
|
||||||
{
|
{
|
||||||
const Font& font = attributedString.getAttribute(i).font;
|
auto& font = attributedString.getAttribute(i).font;
|
||||||
|
|
||||||
if (WindowsDirectWriteTypeface* wt = dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface()))
|
if (auto* wt = dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface()))
|
||||||
if (wt->getIDWriteFontFace() == glyphRun.fontFace)
|
if (wt->getIDWriteFontFace() == glyphRun.fontFace)
|
||||||
return font.withHeight (fontHeight);
|
return font.withHeight (fontHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
ComSmartPtr<IDWriteFont> dwFont;
|
ComSmartPtr<IDWriteFont> dwFont;
|
||||||
HRESULT hr = fontCollection.GetFontFromFontFace (glyphRun.fontFace, dwFont.resetAndGetPointerAddress());
|
auto hr = fontCollection.GetFontFromFontFace (glyphRun.fontFace, dwFont.resetAndGetPointerAddress());
|
||||||
jassert (dwFont != nullptr);
|
jassert (dwFont != nullptr);
|
||||||
|
|
||||||
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
|
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
|
||||||
|
|
@ -261,7 +259,7 @@ namespace DirectWriteTypeLayout
|
||||||
range.length = jmin (attr.range.getLength(), textLen - attr.range.getStart());
|
range.length = jmin (attr.range.getLength(), textLen - attr.range.getStart());
|
||||||
|
|
||||||
{
|
{
|
||||||
const String familyName (FontStyleHelpers::getConcreteFamilyName (attr.font));
|
auto familyName = FontStyleHelpers::getConcreteFamilyName (attr.font);
|
||||||
|
|
||||||
BOOL fontFound = false;
|
BOOL fontFound = false;
|
||||||
uint32 fontIndex;
|
uint32 fontIndex;
|
||||||
|
|
@ -271,7 +269,7 @@ namespace DirectWriteTypeLayout
|
||||||
fontIndex = 0;
|
fontIndex = 0;
|
||||||
|
|
||||||
ComSmartPtr<IDWriteFontFamily> fontFamily;
|
ComSmartPtr<IDWriteFontFamily> fontFamily;
|
||||||
HRESULT hr = fontCollection.GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress());
|
auto hr = fontCollection.GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress());
|
||||||
|
|
||||||
ComSmartPtr<IDWriteFont> dwFont;
|
ComSmartPtr<IDWriteFont> dwFont;
|
||||||
uint32 fontFacesCount = 0;
|
uint32 fontFacesCount = 0;
|
||||||
|
|
@ -290,12 +288,12 @@ namespace DirectWriteTypeLayout
|
||||||
textLayout.SetFontStretch (dwFont->GetStretch(), range);
|
textLayout.SetFontStretch (dwFont->GetStretch(), range);
|
||||||
textLayout.SetFontStyle (dwFont->GetStyle(), range);
|
textLayout.SetFontStyle (dwFont->GetStyle(), range);
|
||||||
|
|
||||||
const float fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*dwFont);
|
auto fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*dwFont);
|
||||||
textLayout.SetFontSize (attr.font.getHeight() * fontHeightToEmSizeFactor, range);
|
textLayout.SetFontSize (attr.font.getHeight() * fontHeightToEmSizeFactor, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const Colour col (attr.colour);
|
auto col = attr.colour;
|
||||||
ComSmartPtr<ID2D1SolidColorBrush> d2dBrush;
|
ComSmartPtr<ID2D1SolidColorBrush> d2dBrush;
|
||||||
renderTarget.CreateSolidColorBrush (D2D1::ColorF (col.getFloatRed(),
|
renderTarget.CreateSolidColorBrush (D2D1::ColorF (col.getFloatRed(),
|
||||||
col.getFloatGreen(),
|
col.getFloatGreen(),
|
||||||
|
|
@ -308,7 +306,7 @@ namespace DirectWriteTypeLayout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setupLayout (const AttributedString& text, const float maxWidth, const float maxHeight,
|
bool setupLayout (const AttributedString& text, float maxWidth, float maxHeight,
|
||||||
ID2D1RenderTarget& renderTarget, IDWriteFactory& directWriteFactory,
|
ID2D1RenderTarget& renderTarget, IDWriteFactory& directWriteFactory,
|
||||||
IDWriteFontCollection& fontCollection, ComSmartPtr<IDWriteTextLayout>& textLayout)
|
IDWriteFontCollection& fontCollection, ComSmartPtr<IDWriteTextLayout>& textLayout)
|
||||||
{
|
{
|
||||||
|
|
@ -324,14 +322,14 @@ namespace DirectWriteTypeLayout
|
||||||
fontIndex = 0;
|
fontIndex = 0;
|
||||||
|
|
||||||
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
|
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
|
||||||
HRESULT hr = fontCollection.GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress());
|
auto hr = fontCollection.GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress());
|
||||||
|
|
||||||
ComSmartPtr<IDWriteFont> dwFont;
|
ComSmartPtr<IDWriteFont> dwFont;
|
||||||
hr = dwFontFamily->GetFirstMatchingFont (DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL,
|
hr = dwFontFamily->GetFirstMatchingFont (DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL,
|
||||||
dwFont.resetAndGetPointerAddress());
|
dwFont.resetAndGetPointerAddress());
|
||||||
jassert (dwFont != nullptr);
|
jassert (dwFont != nullptr);
|
||||||
|
|
||||||
const float defaultFontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*dwFont);
|
auto defaultFontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*dwFont);
|
||||||
|
|
||||||
ComSmartPtr<IDWriteTextFormat> dwTextFormat;
|
ComSmartPtr<IDWriteTextFormat> dwTextFormat;
|
||||||
hr = directWriteFactory.CreateTextFormat (defaultFont.getTypefaceName().toWideCharPointer(), &fontCollection,
|
hr = directWriteFactory.CreateTextFormat (defaultFont.getTypefaceName().toWideCharPointer(), &fontCollection,
|
||||||
|
|
@ -348,7 +346,7 @@ namespace DirectWriteTypeLayout
|
||||||
hr = dwTextFormat->SetTrimming (&trimming, trimmingSign);
|
hr = dwTextFormat->SetTrimming (&trimming, trimmingSign);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int textLen = text.getText().length();
|
auto textLen = text.getText().length();
|
||||||
|
|
||||||
hr = directWriteFactory.CreateTextLayout (text.getText().toWideCharPointer(), textLen, dwTextFormat,
|
hr = directWriteFactory.CreateTextLayout (text.getText().toWideCharPointer(), textLen, dwTextFormat,
|
||||||
maxWidth, maxHeight, textLayout.resetAndGetPointerAddress());
|
maxWidth, maxHeight, textLayout.resetAndGetPointerAddress());
|
||||||
|
|
@ -356,7 +354,7 @@ namespace DirectWriteTypeLayout
|
||||||
if (FAILED (hr) || textLayout == nullptr)
|
if (FAILED (hr) || textLayout == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const int numAttributes = text.getNumAttributes();
|
auto numAttributes = text.getNumAttributes();
|
||||||
|
|
||||||
for (int i = 0; i < numAttributes; ++i)
|
for (int i = 0; i < numAttributes; ++i)
|
||||||
addAttributedRange (text.getAttribute (i), *textLayout, textLen, renderTarget, fontCollection);
|
addAttributedRange (text.getAttribute (i), *textLayout, textLen, renderTarget, fontCollection);
|
||||||
|
|
@ -376,7 +374,7 @@ namespace DirectWriteTypeLayout
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UINT32 actualLineCount = 0;
|
UINT32 actualLineCount = 0;
|
||||||
HRESULT hr = dwTextLayout->GetLineMetrics (nullptr, 0, &actualLineCount);
|
auto hr = dwTextLayout->GetLineMetrics (nullptr, 0, &actualLineCount);
|
||||||
|
|
||||||
layout.ensureStorageAllocated (actualLineCount);
|
layout.ensureStorageAllocated (actualLineCount);
|
||||||
|
|
||||||
|
|
@ -388,13 +386,13 @@ namespace DirectWriteTypeLayout
|
||||||
HeapBlock<DWRITE_LINE_METRICS> dwLineMetrics (actualLineCount);
|
HeapBlock<DWRITE_LINE_METRICS> dwLineMetrics (actualLineCount);
|
||||||
hr = dwTextLayout->GetLineMetrics (dwLineMetrics, actualLineCount, &actualLineCount);
|
hr = dwTextLayout->GetLineMetrics (dwLineMetrics, actualLineCount, &actualLineCount);
|
||||||
int lastLocation = 0;
|
int lastLocation = 0;
|
||||||
const int numLines = jmin ((int) actualLineCount, layout.getNumLines());
|
auto numLines = jmin ((int) actualLineCount, layout.getNumLines());
|
||||||
float yAdjustment = 0;
|
float yAdjustment = 0;
|
||||||
const float extraLineSpacing = text.getLineSpacing();
|
auto extraLineSpacing = text.getLineSpacing();
|
||||||
|
|
||||||
for (int i = 0; i < numLines; ++i)
|
for (int i = 0; i < numLines; ++i)
|
||||||
{
|
{
|
||||||
TextLayout::Line& line = layout.getLine (i);
|
auto& line = layout.getLine (i);
|
||||||
line.stringRange = Range<int> (lastLocation, (int) lastLocation + dwLineMetrics[i].length);
|
line.stringRange = Range<int> (lastLocation, (int) lastLocation + dwLineMetrics[i].length);
|
||||||
line.lineOrigin.y += yAdjustment;
|
line.lineOrigin.y += yAdjustment;
|
||||||
yAdjustment += extraLineSpacing;
|
yAdjustment += extraLineSpacing;
|
||||||
|
|
@ -422,7 +420,7 @@ namespace DirectWriteTypeLayout
|
||||||
|
|
||||||
static bool canAllTypefacesBeUsedInLayout (const AttributedString& text)
|
static bool canAllTypefacesBeUsedInLayout (const AttributedString& text)
|
||||||
{
|
{
|
||||||
const int numCharacterAttributes = text.getNumAttributes();
|
auto numCharacterAttributes = text.getNumAttributes();
|
||||||
|
|
||||||
for (int i = 0; i < numCharacterAttributes; ++i)
|
for (int i = 0; i < numCharacterAttributes; ++i)
|
||||||
if (dynamic_cast<WindowsDirectWriteTypeface*> (text.getAttribute(i).font.getTypeface()) == nullptr)
|
if (dynamic_cast<WindowsDirectWriteTypeface*> (text.getAttribute(i).font.getTypeface()) == nullptr)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@ namespace
|
||||||
|
|
||||||
uint32 index = 0;
|
uint32 index = 0;
|
||||||
BOOL exists = false;
|
BOOL exists = false;
|
||||||
HRESULT hr = names->FindLocaleName (L"en-us", &index, &exists);
|
auto hr = names->FindLocaleName (L"en-us", &index, &exists);
|
||||||
|
|
||||||
if (! exists)
|
if (! exists)
|
||||||
index = 0;
|
index = 0;
|
||||||
|
|
||||||
|
|
@ -53,7 +54,7 @@ namespace
|
||||||
{
|
{
|
||||||
jassert (family != nullptr);
|
jassert (family != nullptr);
|
||||||
ComSmartPtr<IDWriteLocalizedStrings> familyNames;
|
ComSmartPtr<IDWriteLocalizedStrings> familyNames;
|
||||||
HRESULT hr = family->GetFamilyNames (familyNames.resetAndGetPointerAddress());
|
auto hr = family->GetFamilyNames (familyNames.resetAndGetPointerAddress());
|
||||||
jassert (SUCCEEDED (hr)); ignoreUnused (hr);
|
jassert (SUCCEEDED (hr)); ignoreUnused (hr);
|
||||||
return getLocalisedName (familyNames);
|
return getLocalisedName (familyNames);
|
||||||
}
|
}
|
||||||
|
|
@ -62,7 +63,7 @@ namespace
|
||||||
{
|
{
|
||||||
jassert (font != nullptr);
|
jassert (font != nullptr);
|
||||||
ComSmartPtr<IDWriteLocalizedStrings> faceNames;
|
ComSmartPtr<IDWriteLocalizedStrings> faceNames;
|
||||||
HRESULT hr = font->GetFaceNames (faceNames.resetAndGetPointerAddress());
|
auto hr = font->GetFaceNames (faceNames.resetAndGetPointerAddress());
|
||||||
jassert (SUCCEEDED (hr)); ignoreUnused (hr);
|
jassert (SUCCEEDED (hr)); ignoreUnused (hr);
|
||||||
return getLocalisedName (faceNames);
|
return getLocalisedName (faceNames);
|
||||||
}
|
}
|
||||||
|
|
@ -106,12 +107,12 @@ public:
|
||||||
|
|
||||||
if (d2dFactory != nullptr)
|
if (d2dFactory != nullptr)
|
||||||
{
|
{
|
||||||
D2D1_RENDER_TARGET_PROPERTIES d2dRTProp = D2D1::RenderTargetProperties (D2D1_RENDER_TARGET_TYPE_SOFTWARE,
|
auto d2dRTProp = D2D1::RenderTargetProperties (D2D1_RENDER_TARGET_TYPE_SOFTWARE,
|
||||||
D2D1::PixelFormat (DXGI_FORMAT_B8G8R8A8_UNORM,
|
D2D1::PixelFormat (DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
D2D1_ALPHA_MODE_IGNORE),
|
D2D1_ALPHA_MODE_IGNORE),
|
||||||
0, 0,
|
0, 0,
|
||||||
D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE,
|
D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE,
|
||||||
D2D1_FEATURE_LEVEL_DEFAULT);
|
D2D1_FEATURE_LEVEL_DEFAULT);
|
||||||
|
|
||||||
d2dFactory->CreateDCRenderTarget (&d2dRTProp, directWriteRenderTarget.resetAndGetPointerAddress());
|
d2dFactory->CreateDCRenderTarget (&d2dRTProp, directWriteRenderTarget.resetAndGetPointerAddress());
|
||||||
}
|
}
|
||||||
|
|
@ -142,14 +143,14 @@ class WindowsDirectWriteTypeface : public Typeface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WindowsDirectWriteTypeface (const Font& font, IDWriteFontCollection* fontCollection)
|
WindowsDirectWriteTypeface (const Font& font, IDWriteFontCollection* fontCollection)
|
||||||
: Typeface (font.getTypefaceName(), font.getTypefaceStyle()),
|
: Typeface (font.getTypefaceName(), font.getTypefaceStyle())
|
||||||
unitsToHeightScaleFactor (1.0f), heightToPointsFactor (1.0f), ascent (0.0f)
|
|
||||||
{
|
{
|
||||||
jassert (fontCollection != nullptr);
|
jassert (fontCollection != nullptr);
|
||||||
|
|
||||||
BOOL fontFound = false;
|
BOOL fontFound = false;
|
||||||
uint32 fontIndex = 0;
|
uint32 fontIndex = 0;
|
||||||
HRESULT hr = fontCollection->FindFamilyName (font.getTypefaceName().toWideCharPointer(), &fontIndex, &fontFound);
|
auto hr = fontCollection->FindFamilyName (font.getTypefaceName().toWideCharPointer(), &fontIndex, &fontFound);
|
||||||
|
|
||||||
if (! fontFound)
|
if (! fontFound)
|
||||||
fontIndex = 0;
|
fontIndex = 0;
|
||||||
|
|
||||||
|
|
@ -190,18 +191,18 @@ public:
|
||||||
designUnitsPerEm = dwFontMetrics.designUnitsPerEm;
|
designUnitsPerEm = dwFontMetrics.designUnitsPerEm;
|
||||||
|
|
||||||
ascent = std::abs ((float) dwFontMetrics.ascent);
|
ascent = std::abs ((float) dwFontMetrics.ascent);
|
||||||
const float totalSize = ascent + std::abs ((float) dwFontMetrics.descent);
|
auto totalSize = ascent + std::abs ((float) dwFontMetrics.descent);
|
||||||
ascent /= totalSize;
|
ascent /= totalSize;
|
||||||
unitsToHeightScaleFactor = designUnitsPerEm / totalSize;
|
unitsToHeightScaleFactor = designUnitsPerEm / totalSize;
|
||||||
|
|
||||||
HDC tempDC = GetDC (0);
|
auto tempDC = GetDC (0);
|
||||||
float dpi = (GetDeviceCaps (tempDC, LOGPIXELSX) + GetDeviceCaps (tempDC, LOGPIXELSY)) / 2.0f;
|
auto dpi = (GetDeviceCaps (tempDC, LOGPIXELSX) + GetDeviceCaps (tempDC, LOGPIXELSY)) / 2.0f;
|
||||||
heightToPointsFactor = (dpi / GetDeviceCaps (tempDC, LOGPIXELSY)) * unitsToHeightScaleFactor;
|
heightToPointsFactor = (dpi / GetDeviceCaps (tempDC, LOGPIXELSY)) * unitsToHeightScaleFactor;
|
||||||
ReleaseDC (0, tempDC);
|
ReleaseDC (0, tempDC);
|
||||||
|
|
||||||
const float pathAscent = (1024.0f * dwFontMetrics.ascent) / designUnitsPerEm;
|
auto pathAscent = (1024.0f * dwFontMetrics.ascent) / designUnitsPerEm;
|
||||||
const float pathDescent = (1024.0f * dwFontMetrics.descent) / designUnitsPerEm;
|
auto pathDescent = (1024.0f * dwFontMetrics.descent) / designUnitsPerEm;
|
||||||
const float pathScale = 1.0f / (std::abs (pathAscent) + std::abs (pathDescent));
|
auto pathScale = 1.0f / (std::abs (pathAscent) + std::abs (pathDescent));
|
||||||
pathTransform = AffineTransform::scale (pathScale);
|
pathTransform = AffineTransform::scale (pathScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -214,8 +215,8 @@ public:
|
||||||
|
|
||||||
float getStringWidth (const String& text)
|
float getStringWidth (const String& text)
|
||||||
{
|
{
|
||||||
const CharPointer_UTF32 textUTF32 (text.toUTF32());
|
auto textUTF32 = text.toUTF32();
|
||||||
const size_t len = textUTF32.length();
|
auto len = textUTF32.length();
|
||||||
|
|
||||||
HeapBlock<UINT16> glyphIndices (len);
|
HeapBlock<UINT16> glyphIndices (len);
|
||||||
dwFontFace->GetGlyphIndices (textUTF32, (UINT32) len, glyphIndices);
|
dwFontFace->GetGlyphIndices (textUTF32, (UINT32) len, glyphIndices);
|
||||||
|
|
@ -224,6 +225,7 @@ public:
|
||||||
dwFontFace->GetDesignGlyphMetrics (glyphIndices, (UINT32) len, dwGlyphMetrics, false);
|
dwFontFace->GetDesignGlyphMetrics (glyphIndices, (UINT32) len, dwGlyphMetrics, false);
|
||||||
|
|
||||||
float x = 0;
|
float x = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
x += (float) dwGlyphMetrics[i].advanceWidth / designUnitsPerEm;
|
x += (float) dwGlyphMetrics[i].advanceWidth / designUnitsPerEm;
|
||||||
|
|
||||||
|
|
@ -234,8 +236,8 @@ public:
|
||||||
{
|
{
|
||||||
xOffsets.add (0);
|
xOffsets.add (0);
|
||||||
|
|
||||||
const CharPointer_UTF32 textUTF32 (text.toUTF32());
|
auto textUTF32 = text.toUTF32();
|
||||||
const size_t len = textUTF32.length();
|
auto len = textUTF32.length();
|
||||||
|
|
||||||
HeapBlock<UINT16> glyphIndices (len);
|
HeapBlock<UINT16> glyphIndices (len);
|
||||||
dwFontFace->GetGlyphIndices (textUTF32, (UINT32) len, glyphIndices);
|
dwFontFace->GetGlyphIndices (textUTF32, (UINT32) len, glyphIndices);
|
||||||
|
|
@ -243,6 +245,7 @@ public:
|
||||||
dwFontFace->GetDesignGlyphMetrics (glyphIndices, (UINT32) len, dwGlyphMetrics, false);
|
dwFontFace->GetDesignGlyphMetrics (glyphIndices, (UINT32) len, dwGlyphMetrics, false);
|
||||||
|
|
||||||
float x = 0;
|
float x = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
x += (float) dwGlyphMetrics[i].advanceWidth / designUnitsPerEm;
|
x += (float) dwGlyphMetrics[i].advanceWidth / designUnitsPerEm;
|
||||||
|
|
@ -254,10 +257,11 @@ public:
|
||||||
bool getOutlineForGlyph (int glyphNumber, Path& path)
|
bool getOutlineForGlyph (int glyphNumber, Path& path)
|
||||||
{
|
{
|
||||||
jassert (path.isEmpty()); // we might need to apply a transform to the path, so this must be empty
|
jassert (path.isEmpty()); // we might need to apply a transform to the path, so this must be empty
|
||||||
UINT16 glyphIndex = (UINT16) glyphNumber;
|
auto glyphIndex = (UINT16) glyphNumber;
|
||||||
ComSmartPtr<PathGeometrySink> pathGeometrySink (new PathGeometrySink());
|
ComSmartPtr<PathGeometrySink> pathGeometrySink (new PathGeometrySink());
|
||||||
|
|
||||||
dwFontFace->GetGlyphRunOutline (1024.0f, &glyphIndex, nullptr, nullptr, 1, false, false, pathGeometrySink);
|
dwFontFace->GetGlyphRunOutline (1024.0f, &glyphIndex, nullptr, nullptr,
|
||||||
|
1, false, false, pathGeometrySink);
|
||||||
path = pathGeometrySink->path;
|
path = pathGeometrySink->path;
|
||||||
|
|
||||||
if (! pathTransform.isIdentity())
|
if (! pathTransform.isIdentity())
|
||||||
|
|
@ -273,8 +277,8 @@ public:
|
||||||
private:
|
private:
|
||||||
SharedResourcePointer<Direct2DFactories> factories;
|
SharedResourcePointer<Direct2DFactories> factories;
|
||||||
ComSmartPtr<IDWriteFontFace> dwFontFace;
|
ComSmartPtr<IDWriteFontFace> dwFontFace;
|
||||||
float unitsToHeightScaleFactor, heightToPointsFactor, ascent;
|
float unitsToHeightScaleFactor = 1.0f, heightToPointsFactor = 1.0f, ascent = 0;
|
||||||
int designUnitsPerEm;
|
int designUnitsPerEm = 0;
|
||||||
AffineTransform pathTransform;
|
AffineTransform pathTransform;
|
||||||
|
|
||||||
struct PathGeometrySink : public ComBaseClassHelper<IDWriteGeometrySink>
|
struct PathGeometrySink : public ComBaseClassHelper<IDWriteGeometrySink>
|
||||||
|
|
|
||||||
|
|
@ -63,14 +63,14 @@ namespace TTFNameExtractor
|
||||||
const int64 directoryOffset, const int64 offsetOfStringStorage)
|
const int64 directoryOffset, const int64 offsetOfStringStorage)
|
||||||
{
|
{
|
||||||
String result;
|
String result;
|
||||||
const int64 oldPos = input.getPosition();
|
auto oldPos = input.getPosition();
|
||||||
input.setPosition (directoryOffset + offsetOfStringStorage + ByteOrder::swapIfLittleEndian (nameRecord.offsetFromStorageArea));
|
input.setPosition (directoryOffset + offsetOfStringStorage + ByteOrder::swapIfLittleEndian (nameRecord.offsetFromStorageArea));
|
||||||
const int stringLength = (int) ByteOrder::swapIfLittleEndian (nameRecord.stringLength);
|
auto stringLength = (int) ByteOrder::swapIfLittleEndian (nameRecord.stringLength);
|
||||||
const int platformID = ByteOrder::swapIfLittleEndian (nameRecord.platformID);
|
auto platformID = ByteOrder::swapIfLittleEndian (nameRecord.platformID);
|
||||||
|
|
||||||
if (platformID == 0 || platformID == 3)
|
if (platformID == 0 || platformID == 3)
|
||||||
{
|
{
|
||||||
const int numChars = stringLength / 2 + 1;
|
auto numChars = stringLength / 2 + 1;
|
||||||
HeapBlock<uint16> buffer;
|
HeapBlock<uint16> buffer;
|
||||||
buffer.calloc (numChars + 1);
|
buffer.calloc (numChars + 1);
|
||||||
input.read (buffer, stringLength);
|
input.read (buffer, stringLength);
|
||||||
|
|
@ -165,10 +165,8 @@ namespace FontEnumerators
|
||||||
const String fontName (lpelfe->elfLogFont.lfFaceName);
|
const String fontName (lpelfe->elfLogFont.lfFaceName);
|
||||||
fontName.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));
|
fontName.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));
|
||||||
|
|
||||||
HDC dc = CreateCompatibleDC (0);
|
auto dc = CreateCompatibleDC (0);
|
||||||
EnumFontFamiliesEx (dc, &lf,
|
EnumFontFamiliesEx (dc, &lf, (FONTENUMPROCW) &fontEnum2, lParam, 0);
|
||||||
(FONTENUMPROCW) &fontEnum2,
|
|
||||||
lParam, 0);
|
|
||||||
DeleteDC (dc);
|
DeleteDC (dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,7 +189,7 @@ StringArray Font::findAllTypefaceNames()
|
||||||
|
|
||||||
for (uint32 i = 0; i < fontFamilyCount; ++i)
|
for (uint32 i = 0; i < fontFamilyCount; ++i)
|
||||||
{
|
{
|
||||||
HRESULT hr = factories->systemFonts->GetFontFamily (i, fontFamily.resetAndGetPointerAddress());
|
auto hr = factories->systemFonts->GetFontFamily (i, fontFamily.resetAndGetPointerAddress());
|
||||||
|
|
||||||
if (SUCCEEDED (hr))
|
if (SUCCEEDED (hr))
|
||||||
results.addIfNotAlreadyThere (getFontFamilyName (fontFamily));
|
results.addIfNotAlreadyThere (getFontFamilyName (fontFamily));
|
||||||
|
|
@ -200,7 +198,7 @@ StringArray Font::findAllTypefaceNames()
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
HDC dc = CreateCompatibleDC (0);
|
auto dc = CreateCompatibleDC (0);
|
||||||
|
|
||||||
{
|
{
|
||||||
LOGFONTW lf = { 0 };
|
LOGFONTW lf = { 0 };
|
||||||
|
|
@ -237,7 +235,8 @@ StringArray Font::findAllTypefaceStyles (const String& family)
|
||||||
{
|
{
|
||||||
BOOL fontFound = false;
|
BOOL fontFound = false;
|
||||||
uint32 fontIndex = 0;
|
uint32 fontIndex = 0;
|
||||||
HRESULT hr = factories->systemFonts->FindFamilyName (family.toWideCharPointer(), &fontIndex, &fontFound);
|
auto hr = factories->systemFonts->FindFamilyName (family.toWideCharPointer(), &fontIndex, &fontFound);
|
||||||
|
|
||||||
if (! fontFound)
|
if (! fontFound)
|
||||||
fontIndex = 0;
|
fontIndex = 0;
|
||||||
|
|
||||||
|
|
@ -302,7 +301,7 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
|
||||||
static DefaultFontNames defaultNames;
|
static DefaultFontNames defaultNames;
|
||||||
|
|
||||||
Font newFont (font);
|
Font newFont (font);
|
||||||
const String& faceName = font.getTypefaceName();
|
auto& faceName = font.getTypefaceName();
|
||||||
|
|
||||||
if (faceName == getDefaultSansSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSans);
|
if (faceName == getDefaultSansSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSans);
|
||||||
else if (faceName == getDefaultSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSerif);
|
else if (faceName == getDefaultSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSerif);
|
||||||
|
|
@ -318,22 +317,14 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
|
||||||
class WindowsTypeface : public Typeface
|
class WindowsTypeface : public Typeface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WindowsTypeface (const Font& font)
|
WindowsTypeface (const Font& font) : Typeface (font.getTypefaceName(),
|
||||||
: Typeface (font.getTypefaceName(), font.getTypefaceStyle()),
|
font.getTypefaceStyle())
|
||||||
fontH (0), previousFontH (0),
|
|
||||||
dc (CreateCompatibleDC (0)), memoryFont (0),
|
|
||||||
ascent (1.0f), heightToPointsFactor (1.0f),
|
|
||||||
defaultGlyph (-1)
|
|
||||||
{
|
{
|
||||||
loadFont();
|
loadFont();
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowsTypeface (const void* data, size_t dataSize)
|
WindowsTypeface (const void* data, size_t dataSize)
|
||||||
: Typeface (String(), String()),
|
: Typeface (String(), String())
|
||||||
fontH (0), previousFontH (0),
|
|
||||||
dc (CreateCompatibleDC (0)), memoryFont (0),
|
|
||||||
ascent (1.0f), heightToPointsFactor (1.0f),
|
|
||||||
defaultGlyph (-1)
|
|
||||||
{
|
{
|
||||||
DWORD numInstalled = 0;
|
DWORD numInstalled = 0;
|
||||||
memoryFont = AddFontMemResourceEx (const_cast<void*> (data), (DWORD) dataSize,
|
memoryFont = AddFontMemResourceEx (const_cast<void*> (data), (DWORD) dataSize,
|
||||||
|
|
@ -362,8 +353,8 @@ public:
|
||||||
|
|
||||||
float getStringWidth (const String& text)
|
float getStringWidth (const String& text)
|
||||||
{
|
{
|
||||||
const CharPointer_UTF16 utf16 (text.toUTF16());
|
auto utf16 = text.toUTF16();
|
||||||
const size_t numChars = utf16.length();
|
auto numChars = utf16.length();
|
||||||
HeapBlock<uint16> results (numChars);
|
HeapBlock<uint16> results (numChars);
|
||||||
float x = 0;
|
float x = 0;
|
||||||
|
|
||||||
|
|
@ -377,10 +368,10 @@ public:
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getGlyphPositions (const String& text, Array <int>& resultGlyphs, Array <float>& xOffsets)
|
void getGlyphPositions (const String& text, Array<int>& resultGlyphs, Array<float>& xOffsets)
|
||||||
{
|
{
|
||||||
const CharPointer_UTF16 utf16 (text.toUTF16());
|
auto utf16 = text.toUTF16();
|
||||||
const size_t numChars = utf16.length();
|
auto numChars = utf16.length();
|
||||||
HeapBlock<uint16> results (numChars);
|
HeapBlock<uint16> results (numChars);
|
||||||
float x = 0;
|
float x = 0;
|
||||||
|
|
||||||
|
|
@ -408,8 +399,8 @@ public:
|
||||||
|
|
||||||
GLYPHMETRICS gm;
|
GLYPHMETRICS gm;
|
||||||
// (although GetGlyphOutline returns a DWORD, it may be -1 on failure, so treat it as signed int..)
|
// (although GetGlyphOutline returns a DWORD, it may be -1 on failure, so treat it as signed int..)
|
||||||
const int bufSize = (int) GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX,
|
auto bufSize = (int) GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX,
|
||||||
&gm, 0, 0, &identityMatrix);
|
&gm, 0, 0, &identityMatrix);
|
||||||
|
|
||||||
if (bufSize > 0)
|
if (bufSize > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -417,18 +408,18 @@ public:
|
||||||
GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX, &gm,
|
GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX, &gm,
|
||||||
bufSize, data, &identityMatrix);
|
bufSize, data, &identityMatrix);
|
||||||
|
|
||||||
const TTPOLYGONHEADER* pheader = reinterpret_cast<TTPOLYGONHEADER*> (data.getData());
|
auto pheader = reinterpret_cast<const TTPOLYGONHEADER*> (data.getData());
|
||||||
|
|
||||||
const float scaleX = 1.0f / tm.tmHeight;
|
auto scaleX = 1.0f / tm.tmHeight;
|
||||||
const float scaleY = -scaleX;
|
auto scaleY = -scaleX;
|
||||||
|
|
||||||
while ((char*) pheader < data + bufSize)
|
while ((char*) pheader < data + bufSize)
|
||||||
{
|
{
|
||||||
glyphPath.startNewSubPath (scaleX * pheader->pfxStart.x.value,
|
glyphPath.startNewSubPath (scaleX * pheader->pfxStart.x.value,
|
||||||
scaleY * pheader->pfxStart.y.value);
|
scaleY * pheader->pfxStart.y.value);
|
||||||
|
|
||||||
const TTPOLYCURVE* curve = (const TTPOLYCURVE*) ((const char*) pheader + sizeof (TTPOLYGONHEADER));
|
auto curve = (const TTPOLYCURVE*) ((const char*) pheader + sizeof (TTPOLYGONHEADER));
|
||||||
const char* const curveEnd = ((const char*) pheader) + pheader->cb;
|
auto curveEnd = ((const char*) pheader) + pheader->cb;
|
||||||
|
|
||||||
while ((const char*) curve < curveEnd)
|
while ((const char*) curve < curveEnd)
|
||||||
{
|
{
|
||||||
|
|
@ -442,10 +433,10 @@ public:
|
||||||
{
|
{
|
||||||
for (int i = 0; i < curve->cpfx - 1; ++i)
|
for (int i = 0; i < curve->cpfx - 1; ++i)
|
||||||
{
|
{
|
||||||
const float x2 = scaleX * curve->apfx[i].x.value;
|
auto x2 = scaleX * curve->apfx[i].x.value;
|
||||||
const float y2 = scaleY * curve->apfx[i].y.value;
|
auto y2 = scaleY * curve->apfx[i].y.value;
|
||||||
float x3 = scaleX * curve->apfx[i + 1].x.value;
|
auto x3 = scaleX * curve->apfx[i + 1].x.value;
|
||||||
float y3 = scaleY * curve->apfx[i + 1].y.value;
|
auto y3 = scaleY * curve->apfx[i + 1].y.value;
|
||||||
|
|
||||||
if (i < curve->cpfx - 2)
|
if (i < curve->cpfx - 2)
|
||||||
{
|
{
|
||||||
|
|
@ -471,13 +462,13 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const MAT2 identityMatrix;
|
static const MAT2 identityMatrix;
|
||||||
HFONT fontH;
|
HFONT fontH = {};
|
||||||
HGDIOBJ previousFontH;
|
HGDIOBJ previousFontH = {};
|
||||||
HDC dc;
|
HDC dc { CreateCompatibleDC (0) };
|
||||||
TEXTMETRIC tm;
|
TEXTMETRIC tm;
|
||||||
HANDLE memoryFont;
|
HANDLE memoryFont = {};
|
||||||
float ascent, heightToPointsFactor;
|
float ascent = 1.0f, heightToPointsFactor = 1.0f;
|
||||||
int defaultGlyph, heightInPoints;
|
int defaultGlyph = -1, heightInPoints = 0;
|
||||||
|
|
||||||
struct KerningPair
|
struct KerningPair
|
||||||
{
|
{
|
||||||
|
|
@ -514,15 +505,15 @@ private:
|
||||||
lf.lfHeight = -256;
|
lf.lfHeight = -256;
|
||||||
name.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));
|
name.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));
|
||||||
|
|
||||||
HFONT standardSizedFont = CreateFontIndirect (&lf);
|
auto standardSizedFont = CreateFontIndirect (&lf);
|
||||||
|
|
||||||
if (standardSizedFont != 0)
|
if (standardSizedFont != 0)
|
||||||
{
|
{
|
||||||
if ((previousFontH = SelectObject (dc, standardSizedFont)) != 0)
|
if ((previousFontH = SelectObject (dc, standardSizedFont)) != 0)
|
||||||
{
|
{
|
||||||
fontH = standardSizedFont;
|
fontH = standardSizedFont;
|
||||||
|
|
||||||
OUTLINETEXTMETRIC otm;
|
OUTLINETEXTMETRIC otm;
|
||||||
|
|
||||||
if (GetOutlineTextMetrics (dc, sizeof (otm), &otm) != 0)
|
if (GetOutlineTextMetrics (dc, sizeof (otm), &otm) != 0)
|
||||||
{
|
{
|
||||||
heightInPoints = otm.otmEMSquare;
|
heightInPoints = otm.otmEMSquare;
|
||||||
|
|
@ -537,7 +528,7 @@ private:
|
||||||
|
|
||||||
if (GetTextMetrics (dc, &tm))
|
if (GetTextMetrics (dc, &tm))
|
||||||
{
|
{
|
||||||
float dpi = (GetDeviceCaps (dc, LOGPIXELSX) + GetDeviceCaps (dc, LOGPIXELSY)) / 2.0f;
|
auto dpi = (GetDeviceCaps (dc, LOGPIXELSX) + GetDeviceCaps (dc, LOGPIXELSY)) / 2.0f;
|
||||||
heightToPointsFactor = (dpi / GetDeviceCaps (dc, LOGPIXELSY)) * heightInPoints / (float) tm.tmHeight;
|
heightToPointsFactor = (dpi / GetDeviceCaps (dc, LOGPIXELSY)) * heightInPoints / (float) tm.tmHeight;
|
||||||
ascent = tm.tmAscent / (float) tm.tmHeight;
|
ascent = tm.tmAscent / (float) tm.tmHeight;
|
||||||
defaultGlyph = getGlyphForChar (dc, tm.tmDefaultChar);
|
defaultGlyph = getGlyphForChar (dc, tm.tmDefaultChar);
|
||||||
|
|
@ -545,10 +536,10 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void createKerningPairs (HDC hdc, const float height)
|
void createKerningPairs (HDC hdc, float height)
|
||||||
{
|
{
|
||||||
HeapBlock<KERNINGPAIR> rawKerning;
|
HeapBlock<KERNINGPAIR> rawKerning;
|
||||||
const DWORD numKPs = GetKerningPairs (hdc, 0, 0);
|
auto numKPs = GetKerningPairs (hdc, 0, 0);
|
||||||
rawKerning.calloc (numKPs);
|
rawKerning.calloc (numKPs);
|
||||||
GetKerningPairs (hdc, numKPs, rawKerning);
|
GetKerningPairs (hdc, numKPs, rawKerning);
|
||||||
|
|
||||||
|
|
@ -560,7 +551,7 @@ private:
|
||||||
kp.glyph1 = getGlyphForChar (hdc, rawKerning[i].wFirst);
|
kp.glyph1 = getGlyphForChar (hdc, rawKerning[i].wFirst);
|
||||||
kp.glyph2 = getGlyphForChar (hdc, rawKerning[i].wSecond);
|
kp.glyph2 = getGlyphForChar (hdc, rawKerning[i].wSecond);
|
||||||
|
|
||||||
const int standardWidth = getGlyphWidth (hdc, kp.glyph1);
|
auto standardWidth = getGlyphWidth (hdc, kp.glyph1);
|
||||||
kp.kerning = (standardWidth + rawKerning[i].iKernAmount) / height;
|
kp.kerning = (standardWidth + rawKerning[i].iKernAmount) / height;
|
||||||
kerningPairs.add (kp);
|
kerningPairs.add (kp);
|
||||||
|
|
||||||
|
|
@ -590,12 +581,12 @@ private:
|
||||||
return gm.gmCellIncX;
|
return gm.gmCellIncX;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getKerning (HDC hdc, const int glyph1, const int glyph2)
|
float getKerning (HDC hdc, int glyph1, int glyph2)
|
||||||
{
|
{
|
||||||
KerningPair kp;
|
KerningPair kp;
|
||||||
kp.glyph1 = glyph1;
|
kp.glyph1 = glyph1;
|
||||||
kp.glyph2 = glyph2;
|
kp.glyph2 = glyph2;
|
||||||
int index = kerningPairs.indexOf (kp);
|
auto index = kerningPairs.indexOf (kp);
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2123,7 +2123,7 @@ public:
|
||||||
and you can test whether it's null before using it to see if something has deleted
|
and you can test whether it's null before using it to see if something has deleted
|
||||||
it.
|
it.
|
||||||
|
|
||||||
The ComponentType typedef must be Component, or some subclass of Component.
|
The ComponentType template parameter must be Component, or some subclass of Component.
|
||||||
|
|
||||||
You may also want to use a WeakReference<Component> object for the same purpose.
|
You may also want to use a WeakReference<Component> object for the same purpose.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,9 @@ class SelectedItemSet : public ChangeBroadcaster
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
typedef SelectableItemType ItemType;
|
using ItemType = SelectableItemType;
|
||||||
typedef Array<SelectableItemType> ItemArray;
|
using ItemArray = Array<SelectableItemType>;
|
||||||
typedef typename TypeHelpers::ParameterType<SelectableItemType>::type ParameterType;
|
using ParameterType = typename TypeHelpers::ParameterType<SelectableItemType>::type;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** Creates an empty set. */
|
/** Creates an empty set. */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue