Added SDK
This commit is contained in:
@@ -0,0 +1,436 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/RefPtr.h>
|
||||
#include <Ultralight/Geometry.h>
|
||||
#include <Ultralight/Buffer.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// The various Bitmap formats.
|
||||
///
|
||||
enum class BitmapFormat : uint8_t {
|
||||
///
|
||||
/// Alpha channel only, 8-bits per pixel.
|
||||
///
|
||||
/// Encoding: 8-bits per channel, unsigned normalized.
|
||||
///
|
||||
/// Color-space: Linear (no gamma), alpha-coverage only.
|
||||
///
|
||||
A8_UNORM,
|
||||
|
||||
///
|
||||
/// Blue Green Red Alpha channels, 32-bits per pixel.
|
||||
///
|
||||
/// Encoding: 8-bits per channel, unsigned normalized.
|
||||
///
|
||||
/// Color-space: sRGB gamma with premultiplied linear alpha channel.
|
||||
///
|
||||
BGRA8_UNORM_SRGB,
|
||||
};
|
||||
|
||||
///
|
||||
/// Macro to get the bytes per pixel from a BitmapFormat
|
||||
///
|
||||
#define GetBytesPerPixel(x) (x == BitmapFormat::A8_UNORM ? 1 : 4)
|
||||
|
||||
///
|
||||
/// Forward declaration for the LockedPixels class.
|
||||
///
|
||||
template<typename T>
|
||||
class LockedPixels;
|
||||
|
||||
///
|
||||
/// Function signature for a user-defined destruction callback to be optionally called when the
|
||||
/// Bitmap is destroyed.
|
||||
///
|
||||
/// @param user_data Pointer to user-defined user-data (this will be the same value as what was
|
||||
/// passed to Bitmap::Create, if any)
|
||||
///
|
||||
/// @param data Pointer to raw Bitmap pixel data.
|
||||
///
|
||||
typedef void (*DestroyBitmapCallback)(void* user_data, void* data);
|
||||
|
||||
///
|
||||
/// A thread-safe container for pixel data.
|
||||
///
|
||||
/// The bitmap class is used to store pixel data in a variety of formats. It intelligently manages
|
||||
/// the lifetime of the pixel buffer and provides thread-safe access to the pixel data.
|
||||
///
|
||||
/// ## Accessing Pixel Data
|
||||
///
|
||||
/// You can access the underlying pixel data by using the LockPixelsSafe() method. An example
|
||||
/// follows:
|
||||
///
|
||||
/// ```
|
||||
/// auto bitmap = Bitmap::Create(100, 100, BitmapFormat::BGRA8_UNORM_SRGB);
|
||||
/// auto pixels = bitmap->LockPixelsSafe();
|
||||
/// if (pixels && pixels.data()) {
|
||||
/// // Zero out the pixel buffer by setting every byte to 0.
|
||||
/// memset(pixels.data(), 0, pixels.size());
|
||||
/// }
|
||||
///
|
||||
/// // 'pixels' is automatically unlocked when it goes out of scope.
|
||||
/// ```
|
||||
class UExport Bitmap : public RefCounted {
|
||||
public:
|
||||
///
|
||||
/// Create an empty Bitmap. No pixels will be allocated.
|
||||
///
|
||||
static RefPtr<Bitmap> Create();
|
||||
|
||||
///
|
||||
/// Create a Bitmap with a certain configuration. Pixels will be allocated but not initialized.
|
||||
///
|
||||
/// @param width The width in pixels.
|
||||
///
|
||||
/// @param height The height in pixels.
|
||||
///
|
||||
/// @param format The pixel format to use.
|
||||
///
|
||||
/// @return A ref-pointer to a new Bitmap instance.
|
||||
///
|
||||
static RefPtr<Bitmap> Create(uint32_t width, uint32_t height, BitmapFormat format);
|
||||
|
||||
///
|
||||
/// Create an aligned Bitmap with a certain configuration. Pixels will be allocated but not
|
||||
/// initialized. Row bytes will be padded to reach the specified alignment.
|
||||
///
|
||||
/// @param width The width in pixels.
|
||||
///
|
||||
/// @param height The height in pixels.
|
||||
///
|
||||
/// @param format The pixel format to use.
|
||||
///
|
||||
/// @param alignment The alignment (in bytes) to use. Row bytes will be padded to reach a
|
||||
/// multiple of this value and the underlying storage will be allocated with
|
||||
/// this alignment.
|
||||
///
|
||||
/// @return A ref-pointer to a new Bitmap instance.
|
||||
///
|
||||
static RefPtr<Bitmap> Create(uint32_t width, uint32_t height, BitmapFormat format,
|
||||
uint32_t alignment);
|
||||
|
||||
///
|
||||
/// Create a Bitmap with existing pixel data, a copy will be made unless should_copy is false.
|
||||
///
|
||||
/// @param width The width in pixels.
|
||||
///
|
||||
/// @param height The height in pixels.
|
||||
///
|
||||
/// @param format The pixel format to use.
|
||||
///
|
||||
/// @param row_bytes The number of bytes between each row (note that this value should be >=
|
||||
/// width * bytes_per_pixel).
|
||||
///
|
||||
/// @param pixels Pointer to raw pixel buffer.
|
||||
///
|
||||
/// @param size Size of the raw pixel buffer.
|
||||
///
|
||||
/// @param should_copy Whether or not a copy should be made of the pixels. If this is false
|
||||
/// the returned Bitmap will use the raw pixels passed in as its own, but
|
||||
/// you are still responsible for destroying your buffer afterwards.
|
||||
///
|
||||
/// @return A ref-pointer to a new Bitmap instance.
|
||||
///
|
||||
static RefPtr<Bitmap> Create(uint32_t width, uint32_t height, BitmapFormat format,
|
||||
uint32_t row_bytes, const void* pixels, size_t size,
|
||||
bool should_copy = true);
|
||||
|
||||
///
|
||||
/// Create a Bitmap that wraps existing pixel data, a user-defined destruction callback will be
|
||||
/// called when the Bitmap wants to destroy the data.
|
||||
///
|
||||
/// @param width The width in pixels.
|
||||
///
|
||||
/// @param height The height in pixels.
|
||||
///
|
||||
/// @param format The pixel format to use.
|
||||
///
|
||||
/// @param row_bytes The number of bytes between each row (note that this value should be >=
|
||||
/// width * bytes_per_pixel).
|
||||
///
|
||||
/// @param pixels Pointer to raw pixel buffer.
|
||||
///
|
||||
/// @param size Size of the raw pixel buffer.
|
||||
///
|
||||
/// @param user_data Optional user data that will be passed to destruction_callback when the
|
||||
/// Bitmap wants to destroy the pixel data. (Pass nullptr to ignore)
|
||||
///
|
||||
/// @param destruction_callback Callback that will be called upon destruction.
|
||||
///
|
||||
/// @return A ref-pointer to a new Bitmap instance.
|
||||
///
|
||||
static RefPtr<Bitmap> Create(uint32_t width, uint32_t height, BitmapFormat format,
|
||||
uint32_t row_bytes, const void* pixels, size_t size,
|
||||
void* user_data, DestroyBitmapCallback destruction_callback);
|
||||
|
||||
///
|
||||
/// Create a bitmap from a deep copy of another Bitmap.
|
||||
///
|
||||
static RefPtr<Bitmap> Create(const Bitmap& bitmap);
|
||||
|
||||
///
|
||||
/// Get the width in pixels.
|
||||
///
|
||||
virtual uint32_t width() const = 0;
|
||||
|
||||
///
|
||||
/// Get the height in pixels.
|
||||
///
|
||||
virtual uint32_t height() const = 0;
|
||||
|
||||
///
|
||||
/// Get the bounds as an IntRect
|
||||
///
|
||||
virtual IntRect bounds() const = 0;
|
||||
|
||||
///
|
||||
/// Get the pixel format.
|
||||
///
|
||||
virtual BitmapFormat format() const = 0;
|
||||
|
||||
///
|
||||
/// Get the number of bytes per pixel.
|
||||
///
|
||||
virtual uint32_t bpp() const = 0;
|
||||
|
||||
///
|
||||
/// Get the number of bytes between each row of pixels.
|
||||
///
|
||||
/// @note This value is usually calculated as width * bytes_per_pixel (bpp) but it may be larger
|
||||
/// due to alignment rules in the allocator.
|
||||
///
|
||||
virtual uint32_t row_bytes() const = 0;
|
||||
|
||||
///
|
||||
/// Get the size in bytes of the pixel buffer.
|
||||
///
|
||||
/// @note Size is calculated as row_bytes() * height().
|
||||
///
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
///
|
||||
/// Whether or not this Bitmap owns the pixel buffer and will destroy it at the end of its
|
||||
/// lifetime.
|
||||
///
|
||||
virtual bool owns_pixels() const = 0;
|
||||
|
||||
///
|
||||
/// Lock the pixel buffer for reading/writing (safe version, automatically unlocks).
|
||||
///
|
||||
/// @return A managed container that can be used to access the pixels (LockedPixels::data()).
|
||||
/// This container will automatically unlock the pixels when it goes out of scope.
|
||||
///
|
||||
virtual LockedPixels<RefPtr<Bitmap>> LockPixelsSafe() const = 0;
|
||||
|
||||
///
|
||||
/// Lock the pixel buffer for reading/writing.
|
||||
///
|
||||
/// @return A pointer to the pixel buffer.
|
||||
///
|
||||
virtual void* LockPixels() = 0;
|
||||
|
||||
///
|
||||
/// Unlock the pixel buffer.
|
||||
///
|
||||
virtual void UnlockPixels() = 0;
|
||||
|
||||
///
|
||||
/// Lock the pixel buffer for reading/writing. (const)
|
||||
///
|
||||
/// @return A const pointer to the pixel buffer.
|
||||
///
|
||||
virtual const void* LockPixels() const = 0;
|
||||
|
||||
///
|
||||
/// Unlock the pixel buffer. (const)
|
||||
///
|
||||
virtual void UnlockPixels() const = 0;
|
||||
|
||||
///
|
||||
/// Get the raw pixel buffer.
|
||||
///
|
||||
/// @note You should only call this if pixels are already locked.
|
||||
///
|
||||
virtual void* raw_pixels() = 0;
|
||||
|
||||
///
|
||||
/// Whether or not this Bitmap is empty (no pixels allocated).
|
||||
///
|
||||
virtual bool IsEmpty() const = 0;
|
||||
|
||||
///
|
||||
/// Erase the Bitmap (set all pixels to 0).
|
||||
///
|
||||
virtual void Erase() = 0;
|
||||
|
||||
///
|
||||
/// Assign another bitmap to this one.
|
||||
///
|
||||
/// @param bitmap The bitmap to copy from.
|
||||
///
|
||||
virtual void Set(RefPtr<Bitmap> bitmap) = 0;
|
||||
|
||||
///
|
||||
/// Draw another bitmap to this bitmap.
|
||||
///
|
||||
/// @note Formats do not need to match. Bitmap formats will be converted to one another
|
||||
/// automatically. Note that when converting from BGRA8 to A8, only the Blue channel will
|
||||
/// be used.
|
||||
///
|
||||
/// @param src_rect The source rectangle, relative to src bitmap.
|
||||
///
|
||||
/// @param dest_rect The destination rectangle, relative to this bitmap.
|
||||
///
|
||||
/// @param src The source bitmap.
|
||||
///
|
||||
/// @param pad_repeat Whether or not we should pad the drawn bitmap by one pixel of repeated
|
||||
/// edge pixels from the source bitmap.
|
||||
///
|
||||
/// @return Whether or not the operation succeeded (this can fail if the src_rect and/or
|
||||
/// dest_rect are invalid).
|
||||
///
|
||||
virtual bool DrawBitmap(IntRect src_rect, IntRect dest_rect, RefPtr<Bitmap> src, bool pad_repeat)
|
||||
= 0;
|
||||
|
||||
///
|
||||
/// Encode this Bitmap as a PNG image and store the encoded bytes in a Buffer.
|
||||
///
|
||||
/// @param convert_to_rgba The PNG format expects RGBA format but our bitmap is stored as BGRA,
|
||||
/// set this to true to perform the conversion automatically.
|
||||
///
|
||||
/// @param convert_to_straight_alpha The PNG format expects semi-transparent values to be
|
||||
/// stored as straight alpha instead of premultiplied alpha,
|
||||
/// set this to true to perform the conversion automatically.
|
||||
///
|
||||
/// @return On success, a buffer containing the encoded bytes, otherwise a null RefPtr.
|
||||
///
|
||||
virtual RefPtr<Buffer> EncodePNG(bool convert_to_rgba = true,
|
||||
bool convert_to_straight_alpha = true) const = 0;
|
||||
|
||||
///
|
||||
/// Write this Bitmap out to a PNG image.
|
||||
///
|
||||
/// @param path The filepath to write to (opened with fopen())
|
||||
///
|
||||
/// @param convert_to_rgba The PNG format expects RGBA format but our bitmap is stored as BGRA,
|
||||
/// set this to true to perform the conversion automatically.
|
||||
///
|
||||
/// @param convert_to_straight_alpha The PNG format expects semi-transparent values to be
|
||||
/// stored as straight alpha instead of premultiplied alpha,
|
||||
/// set this to true to perform the conversion automatically.
|
||||
///
|
||||
/// @return Whether or not the operation succeeded.
|
||||
///
|
||||
virtual bool WritePNG(const char* path, bool convert_to_rgba = true,
|
||||
bool convert_to_straight_alpha = true) const = 0;
|
||||
|
||||
///
|
||||
/// Make a resized copy of this bitmap by writing to a pre-allocated destination bitmap.
|
||||
///
|
||||
/// @param destination The bitmap to store the result in, the width and height of the
|
||||
/// destination will be used.
|
||||
///
|
||||
/// @param high_quality Whether or not a high quality resampling will be used during the
|
||||
/// resize. (Otherwise, just uses fast nearest-neighbor sampling)
|
||||
///
|
||||
/// @return Whether or not the operation succeeded. This operation is only valid if both formats
|
||||
/// are BitmapFormat::BGRA8_UNORM_SRGB and the source and destination are non-empty.
|
||||
///
|
||||
virtual bool Resample(RefPtr<Bitmap> destination, bool high_quality) = 0;
|
||||
|
||||
///
|
||||
/// Convert a BGRA bitmap to RGBA bitmap and vice-versa by swapping the red and blue channels.
|
||||
///
|
||||
/// @note Only valid if the format is BitmapFormat::BGRA8_UNORM_SRGB
|
||||
///
|
||||
virtual void SwapRedBlueChannels() = 0;
|
||||
|
||||
///
|
||||
/// Convert a BGRA bitmap from premultiplied alpha (the default) to straight alpha.
|
||||
///
|
||||
/// @note Only valid if the format is BitmapFormat::BGRA8_UNORM_SRGB
|
||||
///
|
||||
virtual void ConvertToStraightAlpha() = 0;
|
||||
|
||||
///
|
||||
/// Convert a BGRA bitmap from straight alpha to premultiplied alpha.
|
||||
///
|
||||
/// @note Only valid if the format is BitmapFormat::BGRA8_UNORM_SRGB
|
||||
///
|
||||
virtual void ConvertToPremultipliedAlpha() = 0;
|
||||
|
||||
protected:
|
||||
Bitmap();
|
||||
virtual ~Bitmap();
|
||||
Bitmap(const Bitmap&);
|
||||
void operator=(const Bitmap&);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class LockedPixels {
|
||||
public:
|
||||
LockedPixels(const LockedPixels&) = delete;
|
||||
LockedPixels& operator=(const LockedPixels&) = delete;
|
||||
LockedPixels(int) = delete;
|
||||
explicit LockedPixels(T& lockable) : lockable_(lockable), data_(nullptr), size_(0) { lock(); }
|
||||
|
||||
~LockedPixels() {
|
||||
if (lockable_)
|
||||
lockable_->UnlockPixels();
|
||||
}
|
||||
|
||||
///
|
||||
/// Access the locked pixel data.
|
||||
///
|
||||
void* data() { return data_; }
|
||||
|
||||
///
|
||||
/// Access the size of the locked pixel data.
|
||||
///
|
||||
size_t size() { return size_; }
|
||||
|
||||
explicit operator bool() const { return !!lockable_; }
|
||||
|
||||
LockedPixels(LockedPixels&& other) : lockable_(other.lockable_), data_(other.data_),
|
||||
size_(other.size_) {
|
||||
other.lockable_ = nullptr;
|
||||
other.data_ = nullptr;
|
||||
other.size_ = 0;
|
||||
}
|
||||
|
||||
LockedPixels& operator=(LockedPixels&& other) {
|
||||
if (lockable_)
|
||||
lockable_->UnlockPixels();
|
||||
lockable_ = other.lockable_;
|
||||
data_ = other.data_;
|
||||
size_ = other.size_;
|
||||
other.lockable_ = nullptr;
|
||||
other.data_ = nullptr;
|
||||
other.size_ = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void lock() {
|
||||
if (lockable_) {
|
||||
data_ = lockable_->LockPixels();
|
||||
size_ = lockable_->size();
|
||||
}
|
||||
}
|
||||
|
||||
T lockable_;
|
||||
void* data_;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,88 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/RefPtr.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Function signature for a user-defined destruction callback to optionally be called when Buffer
|
||||
/// is destroyed. Users can use this to deallocate any data associated with the Buffer.
|
||||
///
|
||||
/// @param user_data Pointer to user-defined user-data (this will be the same value as what was
|
||||
/// passed to Buffer::Create, if any)
|
||||
///
|
||||
/// @param data Pointer to raw Buffer data.
|
||||
///
|
||||
typedef void (*DestroyBufferCallback)(void* user_data, void* data);
|
||||
|
||||
///
|
||||
/// A fixed-size container for raw byte data.
|
||||
///
|
||||
/// This class is used to represent raw data buffers in Ultralight. It intelligently manages the
|
||||
/// lifetime of the data and can optionally call a user-supplied callback to deallocate the data
|
||||
/// when the Buffer is destroyed.
|
||||
///
|
||||
class UExport Buffer : public RefCounted {
|
||||
public:
|
||||
///
|
||||
/// Create a Buffer from existing, user-owned data without any copies. An optional, user-supplied
|
||||
/// callback will be called to deallocate data upon destruction.
|
||||
///
|
||||
/// @param data A pointer to the data.
|
||||
///
|
||||
/// @param size Size of the data in bytes.
|
||||
///
|
||||
/// @param user_data Optional user data that will be passed to destruction_callback
|
||||
/// when the returned Buffer is destroyed.
|
||||
///
|
||||
/// @param destruction_callback Optional callback that will be called upon destruction. Pass a
|
||||
/// null pointer if you don't want to be informed of destruction.
|
||||
///
|
||||
///
|
||||
/// @return A ref-counted Buffer object that wraps the existing data.
|
||||
///
|
||||
static RefPtr<Buffer> Create(void* data, size_t size, void* user_data,
|
||||
DestroyBufferCallback destruction_callback);
|
||||
|
||||
///
|
||||
/// Create a Buffer from existing data, a deep copy of data will be made.
|
||||
///
|
||||
static RefPtr<Buffer> CreateFromCopy(const void* data, size_t size);
|
||||
|
||||
///
|
||||
/// Get a pointer to the raw byte data.
|
||||
///
|
||||
virtual void* data() = 0;
|
||||
|
||||
///
|
||||
/// Get the size in bytes.
|
||||
///
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
///
|
||||
/// Get the user data associated with this Buffer, if any.
|
||||
///
|
||||
virtual void* user_data() = 0;
|
||||
|
||||
///
|
||||
/// Check whether this Buffer owns its own data (Buffer was created via CreateFromCopy).
|
||||
/// If this is false, Buffer will call the user-supplied destruction callback to deallocate data
|
||||
/// when this Buffer instance is destroyed.
|
||||
///
|
||||
virtual bool owns_data() const = 0;
|
||||
|
||||
protected:
|
||||
Buffer();
|
||||
virtual ~Buffer();
|
||||
Buffer(const Buffer&);
|
||||
void operator=(const Buffer&);
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,41 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#ifndef ULTRALIGHT_CAPI_H
|
||||
#define ULTRALIGHT_CAPI_H
|
||||
|
||||
/**************************************************************************************************
|
||||
* API Note:
|
||||
*
|
||||
* You should only destroy objects that you explicitly create. Do not destroy any objects returned
|
||||
* from the API or callbacks unless otherwise noted.
|
||||
**************************************************************************************************/
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
#include <Ultralight/CAPI/CAPI_Bitmap.h>
|
||||
#include <Ultralight/CAPI/CAPI_Buffer.h>
|
||||
#include <Ultralight/CAPI/CAPI_Clipboard.h>
|
||||
#include <Ultralight/CAPI/CAPI_Config.h>
|
||||
#include <Ultralight/CAPI/CAPI_FileSystem.h>
|
||||
#include <Ultralight/CAPI/CAPI_FontFile.h>
|
||||
#include <Ultralight/CAPI/CAPI_FontLoader.h>
|
||||
#include <Ultralight/CAPI/CAPI_Geometry.h>
|
||||
#include <Ultralight/CAPI/CAPI_GPUDriver.h>
|
||||
#include <Ultralight/CAPI/CAPI_ImageSource.h>
|
||||
#include <Ultralight/CAPI/CAPI_KeyEvent.h>
|
||||
#include <Ultralight/CAPI/CAPI_Logger.h>
|
||||
#include <Ultralight/CAPI/CAPI_MouseEvent.h>
|
||||
#include <Ultralight/CAPI/CAPI_Platform.h>
|
||||
#include <Ultralight/CAPI/CAPI_Renderer.h>
|
||||
#include <Ultralight/CAPI/CAPI_ScrollEvent.h>
|
||||
#include <Ultralight/CAPI/CAPI_GamepadEvent.h>
|
||||
#include <Ultralight/CAPI/CAPI_Session.h>
|
||||
#include <Ultralight/CAPI/CAPI_String.h>
|
||||
#include <Ultralight/CAPI/CAPI_Surface.h>
|
||||
#include <Ultralight/CAPI/CAPI_View.h>
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_H
|
||||
@@ -0,0 +1,150 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_Bitmap.h
|
||||
///
|
||||
/// A thread-safe container for pixel data.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_Bitmap.h>`
|
||||
///
|
||||
/// The bitmap class is used to store pixel data in a variety of formats. It intelligently manages
|
||||
/// the lifetime of the pixel buffer and provides thread-safe access to the pixel data.
|
||||
///
|
||||
/// ## Accessing Pixel Data
|
||||
///
|
||||
/// To access the pixel data, you must first lock the pixels using ulBitmapLockPixels(). This will
|
||||
/// return a pointer to the pixel buffer. An example follows:
|
||||
///
|
||||
/// ```
|
||||
/// void* pixels = ulBitmapLockPixels(bitmap);
|
||||
/// if (pixels) {
|
||||
/// // Zero out the pixel buffer
|
||||
/// memset(pixels, 0, ulBitmapGetSize(bitmap));
|
||||
/// }
|
||||
///
|
||||
/// // Unlock the pixels when you're done.
|
||||
/// ulBitmapUnlockPixels(bitmap);
|
||||
/// ```
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_BITMAP_H
|
||||
#define ULTRALIGHT_CAPI_BITMAP_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Bitmap
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create empty bitmap.
|
||||
///
|
||||
ULExport ULBitmap ulCreateEmptyBitmap();
|
||||
|
||||
///
|
||||
/// Create bitmap with certain dimensions and pixel format.
|
||||
///
|
||||
ULExport ULBitmap ulCreateBitmap(unsigned int width, unsigned int height, ULBitmapFormat format);
|
||||
|
||||
///
|
||||
/// Create bitmap from existing pixel buffer. @see Bitmap for help using this function.
|
||||
///
|
||||
ULExport ULBitmap ulCreateBitmapFromPixels(unsigned int width, unsigned int height,
|
||||
ULBitmapFormat format, unsigned int row_bytes,
|
||||
const void* pixels, size_t size, bool should_copy);
|
||||
|
||||
///
|
||||
/// Create bitmap from copy.
|
||||
///
|
||||
ULExport ULBitmap ulCreateBitmapFromCopy(ULBitmap existing_bitmap);
|
||||
|
||||
///
|
||||
/// Destroy a bitmap (you should only destroy Bitmaps you have explicitly created via one of the
|
||||
/// creation functions above.
|
||||
///
|
||||
ULExport void ulDestroyBitmap(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Get the width in pixels.
|
||||
///
|
||||
ULExport unsigned int ulBitmapGetWidth(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Get the height in pixels.
|
||||
///
|
||||
ULExport unsigned int ulBitmapGetHeight(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Get the pixel format.
|
||||
///
|
||||
ULExport ULBitmapFormat ulBitmapGetFormat(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Get the bytes per pixel.
|
||||
///
|
||||
ULExport unsigned int ulBitmapGetBpp(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Get the number of bytes per row.
|
||||
///
|
||||
ULExport unsigned int ulBitmapGetRowBytes(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Get the size in bytes of the underlying pixel buffer.
|
||||
///
|
||||
ULExport size_t ulBitmapGetSize(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Whether or not this bitmap owns its own pixel buffer.
|
||||
///
|
||||
ULExport bool ulBitmapOwnsPixels(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Lock pixels for reading/writing, returns pointer to pixel buffer.
|
||||
///
|
||||
ULExport void* ulBitmapLockPixels(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Unlock pixels after locking.
|
||||
///
|
||||
ULExport void ulBitmapUnlockPixels(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Get raw pixel buffer-- you should only call this if Bitmap is already locked.
|
||||
///
|
||||
ULExport void* ulBitmapRawPixels(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Whether or not this bitmap is empty.
|
||||
///
|
||||
ULExport bool ulBitmapIsEmpty(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Reset bitmap pixels to 0.
|
||||
///
|
||||
ULExport void ulBitmapErase(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Write bitmap to a PNG on disk.
|
||||
///
|
||||
ULExport bool ulBitmapWritePNG(ULBitmap bitmap, const char* path);
|
||||
|
||||
///
|
||||
/// This converts a BGRA bitmap to RGBA bitmap and vice-versa by swapping the red and blue channels.
|
||||
///
|
||||
ULExport void ulBitmapSwapRedBlueChannels(ULBitmap bitmap);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_BITMAP_H
|
||||
@@ -0,0 +1,84 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_Buffer.h
|
||||
///
|
||||
/// A fixed-size container for raw byte data.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_Buffer.h>`
|
||||
///
|
||||
/// This class is used to represent raw data buffers in Ultralight. It intelligently manages the
|
||||
/// lifetime of the data and can optionally call a user-supplied callback to deallocate the data
|
||||
/// when the Buffer is destroyed.
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_BUFFER_H
|
||||
#define ULTRALIGHT_CAPI_BUFFER_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*ulDestroyBufferCallback)(void* user_data, void* data);
|
||||
|
||||
///
|
||||
/// Create a Buffer from existing, user-owned data without any copies. An optional, user-supplied
|
||||
/// callback will be called to deallocate data upon destruction.
|
||||
///
|
||||
/// @param data A pointer to the data.
|
||||
///
|
||||
/// @param size Size of the data in bytes.
|
||||
///
|
||||
/// @param user_data Optional user data that will be passed to destruction_callback
|
||||
/// when the returned Buffer is destroyed.
|
||||
///
|
||||
/// @param destruction_callback Optional callback that will be called upon destruction. Pass a
|
||||
/// null pointer if you don't want to be informed of destruction.
|
||||
///
|
||||
ULExport ULBuffer ulCreateBuffer(void* data, size_t size, void* user_data,
|
||||
ulDestroyBufferCallback destruction_callback);
|
||||
|
||||
///
|
||||
/// Create a Buffer from existing data, a deep copy of data will be made.
|
||||
///
|
||||
ULExport ULBuffer ulCreateBufferFromCopy(const void* data, size_t size);
|
||||
|
||||
///
|
||||
/// Destroy buffer (you should destroy any buffers you explicitly Create).
|
||||
///
|
||||
ULExport void ulDestroyBuffer(ULBuffer buffer);
|
||||
|
||||
///
|
||||
/// Get a pointer to the raw byte data.
|
||||
///
|
||||
ULExport void* ulBufferGetData(ULBuffer buffer);
|
||||
|
||||
///
|
||||
/// Get the size in bytes.
|
||||
///
|
||||
ULExport size_t ulBufferGetSize(ULBuffer buffer);
|
||||
|
||||
///
|
||||
/// Get the user data associated with this Buffer, if any.
|
||||
///
|
||||
ULExport void* ulBufferGetUserData(ULBuffer buffer);
|
||||
|
||||
///
|
||||
/// Check whether this Buffer owns its own data (Buffer was created via ulCreateBufferFromCopy).
|
||||
/// If this is false, Buffer will call the user-supplied destruction callback to deallocate data
|
||||
/// when this Buffer instance is destroyed.
|
||||
///
|
||||
ULExport bool ulBufferOwnsData(ULBuffer buffer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_BUFFER_H
|
||||
@@ -0,0 +1,66 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_Clipboard.h
|
||||
///
|
||||
/// User-defined clipboard interface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_Clipboard.h>`
|
||||
///
|
||||
/// The library uses this to read and write data to the system's clipboard.
|
||||
///
|
||||
/// @see ulPlatformSetClipboard()
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_CLIPBOARD_H
|
||||
#define ULTRALIGHT_CAPI_CLIPBOARD_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Clipboard
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// The callback invoked when the library wants to clear the system's clipboard.
|
||||
///
|
||||
typedef void (*ULClipboardClearCallback)();
|
||||
|
||||
///
|
||||
/// The callback invoked when the library wants to read from the system's clipboard.
|
||||
///
|
||||
/// You should store the result (if any) in 'result'.
|
||||
///
|
||||
typedef void (*ULClipboardReadPlainTextCallback)(ULString result);
|
||||
|
||||
///
|
||||
/// The callback invoked when the library wants to write to the system's clipboard.
|
||||
///
|
||||
typedef void (*ULClipboardWritePlainTextCallback)(ULString text);
|
||||
|
||||
///
|
||||
/// User-defined clipboard interface.
|
||||
///
|
||||
/// You should implement each of these callbacks, then pass an instance of this struct containing
|
||||
/// your callbacks to ulPlatformSetClipboard().
|
||||
///
|
||||
typedef struct {
|
||||
ULClipboardClearCallback clear;
|
||||
ULClipboardReadPlainTextCallback read_plain_text;
|
||||
ULClipboardWritePlainTextCallback write_plain_text;
|
||||
} ULClipboard;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_CLIPBOARD_H
|
||||
@@ -0,0 +1,235 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_Config.h
|
||||
///
|
||||
/// Core configuration for the renderer.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_Config.h>`
|
||||
///
|
||||
/// These are various configuration options that can be used to customize the behavior of the
|
||||
/// library. These options can only be set once before creating the Renderer.
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_CONFIG_H
|
||||
#define ULTRALIGHT_CAPI_CONFIG_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Config
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create config with default values (see <Ultralight/platform/Config.h>).
|
||||
///
|
||||
ULExport ULConfig ulCreateConfig();
|
||||
|
||||
///
|
||||
/// Destroy config.
|
||||
///
|
||||
ULExport void ulDestroyConfig(ULConfig config);
|
||||
|
||||
///
|
||||
/// A writable OS file path to store persistent Session data in.
|
||||
///
|
||||
/// This data may include cookies, cached network resources, indexed DB, etc.
|
||||
///
|
||||
/// @note Files are only written to the path when using a persistent Session.
|
||||
///
|
||||
ULExport void ulConfigSetCachePath(ULConfig config, ULString cache_path);
|
||||
|
||||
///
|
||||
/// The relative path to the resources folder (loaded via the FileSystem API).
|
||||
///
|
||||
/// The library loads certain resources (SSL certs, ICU data, etc.) from the FileSystem API
|
||||
/// during runtime (eg, `file:///resources/cacert.pem`).
|
||||
///
|
||||
/// You can customize the relative file path to the resources folder by modifying this setting.
|
||||
///
|
||||
/// (Default = "resources/")
|
||||
///
|
||||
ULExport void ulConfigSetResourcePathPrefix(ULConfig config, ULString resource_path_prefix);
|
||||
|
||||
///
|
||||
/// The winding order for front-facing triangles.
|
||||
///
|
||||
/// @pre Only used when GPU rendering is enabled for the View.
|
||||
///
|
||||
/// (Default = kFaceWinding_CounterClockwise)
|
||||
///
|
||||
ULExport void ulConfigSetFaceWinding(ULConfig config, ULFaceWinding winding);
|
||||
|
||||
///
|
||||
/// The hinting algorithm to use when rendering fonts. (Default = kFontHinting_Normal)
|
||||
///
|
||||
/// @see ULFontHinting
|
||||
///
|
||||
ULExport void ulConfigSetFontHinting(ULConfig config, ULFontHinting font_hinting);
|
||||
|
||||
///
|
||||
/// The gamma to use when compositing font glyphs, change this value to adjust contrast (Adobe and
|
||||
/// Apple prefer 1.8, others may prefer 2.2). (Default = 1.8)
|
||||
///
|
||||
ULExport void ulConfigSetFontGamma(ULConfig config, double font_gamma);
|
||||
|
||||
///
|
||||
/// Global user-defined CSS string (included before any CSS on the page).
|
||||
///
|
||||
/// You can use this to override default styles for various elements on the page.
|
||||
///
|
||||
/// @note This is an actual string of CSS, not a file path.
|
||||
///
|
||||
ULExport void ulConfigSetUserStylesheet(ULConfig config, ULString css_string);
|
||||
|
||||
///
|
||||
/// Whether or not to continuously repaint any Views, regardless if they are dirty.
|
||||
///
|
||||
/// This is mainly used to diagnose painting/shader issues and profile performance.
|
||||
///
|
||||
/// (Default = False)
|
||||
///
|
||||
ULExport void ulConfigSetForceRepaint(ULConfig config, bool enabled);
|
||||
|
||||
///
|
||||
/// The delay (in seconds) between every tick of a CSS animation.
|
||||
///
|
||||
/// (Default = 1.0 / 60.0)
|
||||
///
|
||||
ULExport void ulConfigSetAnimationTimerDelay(ULConfig config, double delay);
|
||||
|
||||
///
|
||||
/// The delay (in seconds) between every tick of a smooth scroll animation.
|
||||
///
|
||||
/// (Default = 1.0 / 60.0)
|
||||
///
|
||||
ULExport void ulConfigSetScrollTimerDelay(ULConfig config, double delay);
|
||||
|
||||
///
|
||||
/// The delay (in seconds) between every call to the recycler.
|
||||
///
|
||||
/// The library attempts to reclaim excess memory during calls to the internal recycler. You can
|
||||
/// change how often this is run by modifying this value.
|
||||
///
|
||||
/// (Default = 4.0)
|
||||
///
|
||||
ULExport void ulConfigSetRecycleDelay(ULConfig config, double delay);
|
||||
|
||||
///
|
||||
/// The size of WebCore's memory cache in bytes.
|
||||
///
|
||||
/// @note You should increase this if you anticipate handling pages with large resources, Safari
|
||||
/// typically uses 128+ MiB for its cache.
|
||||
///
|
||||
/// (Default = 64 * 1024 * 1024)
|
||||
///
|
||||
ULExport void ulConfigSetMemoryCacheSize(ULConfig config, unsigned int size);
|
||||
|
||||
///
|
||||
/// The number of pages to keep in the cache. (Default: 0, none)
|
||||
///
|
||||
/// @note
|
||||
/// \parblock
|
||||
///
|
||||
/// Safari typically caches about 5 pages and maintains an on-disk cache to support typical
|
||||
/// web-browsing activities.
|
||||
///
|
||||
/// If you increase this, you should probably increase the memory cache size as well.
|
||||
///
|
||||
/// \endparblock
|
||||
///
|
||||
/// (Default = 0)
|
||||
///
|
||||
ULExport void ulConfigSetPageCacheSize(ULConfig config, unsigned int size);
|
||||
|
||||
///
|
||||
/// The system's physical RAM size in bytes.
|
||||
///
|
||||
/// JavaScriptCore tries to detect the system's physical RAM size to set reasonable allocation
|
||||
/// limits. Set this to anything other than 0 to override the detected value. Size is in bytes.
|
||||
///
|
||||
/// This can be used to force JavaScriptCore to be more conservative with its allocation strategy
|
||||
/// (at the cost of some performance).
|
||||
///
|
||||
ULExport void ulConfigSetOverrideRAMSize(ULConfig config, unsigned int size);
|
||||
|
||||
///
|
||||
/// The minimum size of large VM heaps in JavaScriptCore.
|
||||
///
|
||||
/// Set this to a lower value to make these heaps start with a smaller initial value.
|
||||
///
|
||||
/// (Default = 32 * 1024 * 1024)
|
||||
///
|
||||
ULExport void ulConfigSetMinLargeHeapSize(ULConfig config, unsigned int size);
|
||||
|
||||
///
|
||||
/// The minimum size of small VM heaps in JavaScriptCore.
|
||||
///
|
||||
/// Set this to a lower value to make these heaps start with a smaller initial value.
|
||||
///
|
||||
/// (Default = 1 * 1024 * 1024)
|
||||
///
|
||||
ULExport void ulConfigSetMinSmallHeapSize(ULConfig config, unsigned int size);
|
||||
|
||||
///
|
||||
/// The number of threads to use in the Renderer (for parallel painting on the CPU, etc.).
|
||||
///
|
||||
/// You can set this to a certain number to limit the number of threads to spawn.
|
||||
///
|
||||
/// @note
|
||||
/// \parblock
|
||||
///
|
||||
/// If this value is 0, the number of threads will be determined at runtime using the following
|
||||
/// formula:
|
||||
///
|
||||
/// ```
|
||||
/// max(PhysicalProcessorCount() - 1, 1)
|
||||
/// ```
|
||||
///
|
||||
/// \endparblock
|
||||
///
|
||||
ULExport void ulConfigSetNumRendererThreads(ULConfig config, unsigned int num_renderer_threads);
|
||||
|
||||
///
|
||||
/// The max amount of time (in seconds) to allow repeating timers to run during each call to
|
||||
/// Renderer::Update.
|
||||
///
|
||||
/// The library will attempt to throttle timers if this time budget is exceeded.
|
||||
///
|
||||
/// (Default = 1.0 / 200.0)
|
||||
///
|
||||
ULExport void ulConfigSetMaxUpdateTime(ULConfig config, double max_update_time);
|
||||
|
||||
///
|
||||
/// The alignment (in bytes) of the BitmapSurface when using the CPU renderer.
|
||||
///
|
||||
/// The underlying bitmap associated with each BitmapSurface will have row_bytes padded to reach
|
||||
/// this alignment.
|
||||
///
|
||||
/// Aligning the bitmap helps improve performance when using the CPU renderer. Determining the
|
||||
/// proper value to use depends on the CPU architecture and max SIMD instruction set used.
|
||||
///
|
||||
/// We generally target the 128-bit SSE2 instruction set across most PC platforms so '16' is a safe
|
||||
/// value to use.
|
||||
///
|
||||
/// You can set this to '0' to perform no padding (row_bytes will always be width * 4) at a slight
|
||||
/// cost to performance.
|
||||
///
|
||||
/// (Default = 16)
|
||||
///
|
||||
ULExport void ulConfigSetBitmapAlignment(ULConfig config, unsigned int bitmap_alignment);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_CONFIG_H
|
||||
@@ -0,0 +1,318 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_Defines.h
|
||||
///
|
||||
/// Various defines and utility functions for the C API.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_Defines.h>`
|
||||
///
|
||||
/// This file contains various defines, structures, and utility functions for the C API.
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_DEFINES_H
|
||||
#define ULTRALIGHT_CAPI_DEFINES_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <JavaScriptCore/JavaScript.h>
|
||||
#ifdef __OBJC__
|
||||
#import <AppKit/NSEvent.h>
|
||||
#endif
|
||||
|
||||
#if defined(ULTRALIGHT_STATIC_BUILD)
|
||||
#define ULExport
|
||||
#else
|
||||
#if defined(__WIN32__) || defined(_WIN32)
|
||||
#if defined(ULTRALIGHT_IMPLEMENTATION)
|
||||
#define ULExport __declspec(dllexport)
|
||||
#else
|
||||
#define ULExport __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define ULExport __attribute__((visibility("default")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__WIN32__) || defined(_WIN32)
|
||||
#define _thread_local __declspec(thread)
|
||||
#ifndef _NATIVE_WCHAR_T_DEFINED
|
||||
#define DISABLE_NATIVE_WCHAR_T
|
||||
typedef unsigned short ULChar16;
|
||||
#else
|
||||
typedef wchar_t ULChar16;
|
||||
#endif
|
||||
#else
|
||||
#define _thread_local __thread
|
||||
typedef unsigned short ULChar16;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct C_Config* ULConfig;
|
||||
typedef struct C_Renderer* ULRenderer;
|
||||
typedef struct C_Session* ULSession;
|
||||
typedef struct C_ViewConfig* ULViewConfig;
|
||||
typedef struct C_View* ULView;
|
||||
typedef struct C_Bitmap* ULBitmap;
|
||||
typedef struct C_String* ULString;
|
||||
typedef struct C_Buffer* ULBuffer;
|
||||
typedef struct C_KeyEvent* ULKeyEvent;
|
||||
typedef struct C_MouseEvent* ULMouseEvent;
|
||||
typedef struct C_ScrollEvent* ULScrollEvent;
|
||||
typedef struct C_GamepadEvent* ULGamepadEvent;
|
||||
typedef struct C_GamepadAxisEvent* ULGamepadAxisEvent;
|
||||
typedef struct C_GamepadButtonEvent* ULGamepadButtonEvent;
|
||||
typedef struct C_Surface* ULSurface;
|
||||
typedef struct C_Surface* ULBitmapSurface;
|
||||
typedef struct C_FontFile* ULFontFile;
|
||||
typedef struct C_ImageSource* ULImageSource;
|
||||
|
||||
typedef enum {
|
||||
kMessageSource_XML = 0,
|
||||
kMessageSource_JS,
|
||||
kMessageSource_Network,
|
||||
kMessageSource_ConsoleAPI,
|
||||
kMessageSource_Storage,
|
||||
kMessageSource_AppCache,
|
||||
kMessageSource_Rendering,
|
||||
kMessageSource_CSS,
|
||||
kMessageSource_Security,
|
||||
kMessageSource_ContentBlocker,
|
||||
kMessageSource_Media,
|
||||
kMessageSource_MediaSource,
|
||||
kMessageSource_WebRTC,
|
||||
kMessageSource_ITPDebug,
|
||||
kMessageSource_PrivateClickMeasurement,
|
||||
kMessageSource_PaymentRequest,
|
||||
kMessageSource_Other,
|
||||
} ULMessageSource;
|
||||
|
||||
typedef enum {
|
||||
kMessageLevel_Log = 0,
|
||||
kMessageLevel_Warning,
|
||||
kMessageLevel_Error,
|
||||
kMessageLevel_Debug,
|
||||
kMessageLevel_Info,
|
||||
} ULMessageLevel;
|
||||
|
||||
typedef enum {
|
||||
kCursor_Pointer = 0,
|
||||
kCursor_Cross,
|
||||
kCursor_Hand,
|
||||
kCursor_IBeam,
|
||||
kCursor_Wait,
|
||||
kCursor_Help,
|
||||
kCursor_EastResize,
|
||||
kCursor_NorthResize,
|
||||
kCursor_NorthEastResize,
|
||||
kCursor_NorthWestResize,
|
||||
kCursor_SouthResize,
|
||||
kCursor_SouthEastResize,
|
||||
kCursor_SouthWestResize,
|
||||
kCursor_WestResize,
|
||||
kCursor_NorthSouthResize,
|
||||
kCursor_EastWestResize,
|
||||
kCursor_NorthEastSouthWestResize,
|
||||
kCursor_NorthWestSouthEastResize,
|
||||
kCursor_ColumnResize,
|
||||
kCursor_RowResize,
|
||||
kCursor_MiddlePanning,
|
||||
kCursor_EastPanning,
|
||||
kCursor_NorthPanning,
|
||||
kCursor_NorthEastPanning,
|
||||
kCursor_NorthWestPanning,
|
||||
kCursor_SouthPanning,
|
||||
kCursor_SouthEastPanning,
|
||||
kCursor_SouthWestPanning,
|
||||
kCursor_WestPanning,
|
||||
kCursor_Move,
|
||||
kCursor_VerticalText,
|
||||
kCursor_Cell,
|
||||
kCursor_ContextMenu,
|
||||
kCursor_Alias,
|
||||
kCursor_Progress,
|
||||
kCursor_NoDrop,
|
||||
kCursor_Copy,
|
||||
kCursor_None,
|
||||
kCursor_NotAllowed,
|
||||
kCursor_ZoomIn,
|
||||
kCursor_ZoomOut,
|
||||
kCursor_Grab,
|
||||
kCursor_Grabbing,
|
||||
kCursor_Custom
|
||||
} ULCursor;
|
||||
|
||||
typedef enum {
|
||||
///
|
||||
/// Alpha channel only, 8-bits per pixel.
|
||||
///
|
||||
/// Encoding: 8-bits per channel, unsigned normalized.
|
||||
///
|
||||
/// Color-space: Linear (no gamma), alpha-coverage only.
|
||||
///
|
||||
kBitmapFormat_A8_UNORM,
|
||||
|
||||
///
|
||||
/// Blue Green Red Alpha channels, 32-bits per pixel.
|
||||
///
|
||||
/// Encoding: 8-bits per channel, unsigned normalized.
|
||||
///
|
||||
/// Color-space: sRGB gamma with premultiplied linear alpha channel.
|
||||
///
|
||||
kBitmapFormat_BGRA8_UNORM_SRGB
|
||||
} ULBitmapFormat;
|
||||
|
||||
typedef enum {
|
||||
///
|
||||
/// Key-Down event type. This type does **not** trigger accelerator commands in WebCore (eg,
|
||||
/// Ctrl+C for copy is an accelerator command).
|
||||
///
|
||||
/// @warning You should probably use kKeyEventType_RawKeyDown instead. This type is only here for
|
||||
/// historic compatibility with WebCore's key event types.
|
||||
///
|
||||
kKeyEventType_KeyDown,
|
||||
|
||||
///
|
||||
/// Key-Up event type. Use this when a physical key is released.
|
||||
///
|
||||
kKeyEventType_KeyUp,
|
||||
|
||||
///
|
||||
/// Raw Key-Down type. Use this when a physical key is pressed.
|
||||
///
|
||||
kKeyEventType_RawKeyDown,
|
||||
|
||||
///
|
||||
/// Character input event type. Use this when the OS generates text from
|
||||
/// a physical key being pressed (eg, WM_CHAR on Windows).
|
||||
///
|
||||
kKeyEventType_Char,
|
||||
} ULKeyEventType;
|
||||
|
||||
typedef enum {
|
||||
kMouseEventType_MouseMoved,
|
||||
kMouseEventType_MouseDown,
|
||||
kMouseEventType_MouseUp,
|
||||
} ULMouseEventType;
|
||||
|
||||
typedef enum {
|
||||
kMouseButton_None = 0,
|
||||
kMouseButton_Left,
|
||||
kMouseButton_Middle,
|
||||
kMouseButton_Right,
|
||||
} ULMouseButton;
|
||||
|
||||
typedef enum {
|
||||
kScrollEventType_ScrollByPixel,
|
||||
kScrollEventType_ScrollByPage,
|
||||
} ULScrollEventType;
|
||||
|
||||
typedef enum {
|
||||
kGamepadEventType_Connected,
|
||||
kGamepadEventType_Disconnected,
|
||||
} ULGamepadEventType;
|
||||
|
||||
typedef enum {
|
||||
kFaceWinding_Clockwise,
|
||||
kFaceWinding_CounterClockwise,
|
||||
} ULFaceWinding;
|
||||
|
||||
typedef enum {
|
||||
///
|
||||
/// Lighter hinting algorithm-- glyphs are slightly fuzzier but better
|
||||
/// resemble their original shape. This is achieved by snapping glyphs to the
|
||||
/// pixel grid only vertically which better preserves inter-glyph spacing.
|
||||
///
|
||||
kFontHinting_Smooth,
|
||||
|
||||
///
|
||||
/// Default hinting algorithm-- offers a good balance between sharpness and
|
||||
/// shape at smaller font sizes.
|
||||
///
|
||||
kFontHinting_Normal,
|
||||
|
||||
///
|
||||
/// Strongest hinting algorithm-- outputs only black/white glyphs. The result
|
||||
/// is usually unpleasant if the underlying TTF does not contain hints for
|
||||
/// this type of rendering.
|
||||
///
|
||||
kFontHinting_Monochrome,
|
||||
} ULFontHinting;
|
||||
|
||||
typedef struct {
|
||||
float left;
|
||||
float top;
|
||||
float right;
|
||||
float bottom;
|
||||
} ULRect;
|
||||
|
||||
typedef struct {
|
||||
int left;
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
} ULIntRect;
|
||||
|
||||
///
|
||||
/// Offscreen render target, used when rendering Views via the GPU renderer.
|
||||
///
|
||||
/// When a View is rendered via the GPU renderer (see ulViewIsAccelerated()), it will be rendered to
|
||||
/// an offscreen render target (ulViewGetRenderTarget()) that you can display in your application.
|
||||
///
|
||||
/// This is intended to be used with a custom ULGPUDriver implementation in a game or similar
|
||||
/// application (ulPlatformSetGPUDriver()).
|
||||
///
|
||||
typedef struct {
|
||||
bool is_empty;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int texture_id;
|
||||
unsigned int texture_width;
|
||||
unsigned int texture_height;
|
||||
ULBitmapFormat texture_format;
|
||||
ULRect uv_coords;
|
||||
unsigned int render_buffer_id;
|
||||
} ULRenderTarget;
|
||||
|
||||
/******************************************************************************
|
||||
* Version
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Get the version string of the library in MAJOR.MINOR.PATCH format.
|
||||
///
|
||||
ULExport const char* ulVersionString();
|
||||
|
||||
///
|
||||
/// Get the numeric major version of the library.
|
||||
///
|
||||
ULExport unsigned int ulVersionMajor();
|
||||
|
||||
///
|
||||
/// Get the numeric minor version of the library.
|
||||
///
|
||||
ULExport unsigned int ulVersionMinor();
|
||||
|
||||
///
|
||||
/// Get the numeric patch version of the library.
|
||||
///
|
||||
ULExport unsigned int ulVersionPatch();
|
||||
|
||||
///
|
||||
/// Get the full WebKit version string.
|
||||
///
|
||||
ULExport const char* ulWebKitVersionString();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_DEFINES_H
|
||||
@@ -0,0 +1,94 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_FileSystem.h
|
||||
///
|
||||
/// User-defined file system interface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_FileSystem.h>`
|
||||
///
|
||||
/// The library uses this to load file data (ie, raw file bytes) for a given file URL
|
||||
/// (eg, `file:///page.html`) .
|
||||
///
|
||||
/// You can provide the library with your own FileSystem implementation (ULFileSystem) so that file
|
||||
/// data is provided directly by your application (eg, from memory, from a virtual file system,
|
||||
/// etc).
|
||||
///
|
||||
/// @see ulPlatformSetFileSystem
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_FILESYSTEM_H
|
||||
#define ULTRALIGHT_CAPI_FILESYSTEM_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* File System
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// The callback invoked when the FileSystem wants to check if a file path exists, return true if it
|
||||
/// exists.
|
||||
///
|
||||
typedef bool (*ULFileSystemFileExistsCallback)(ULString path);
|
||||
|
||||
///
|
||||
/// Get the mime-type of the file (eg "text/html").
|
||||
///
|
||||
/// This is usually determined by analyzing the file extension.
|
||||
///
|
||||
/// If a mime-type cannot be determined, you should return "application/unknown" for this value.
|
||||
///
|
||||
/// The library will consume the result and call ulDestroyString() after this call returns.
|
||||
///
|
||||
typedef ULString (*ULFileSystemGetFileMimeTypeCallback)(ULString path);
|
||||
|
||||
///
|
||||
/// Get the charset / encoding of the file (eg "utf-8").
|
||||
///
|
||||
/// This is only important for text-based files and is usually determined by analyzing the
|
||||
/// contents of the file.
|
||||
///
|
||||
/// If a charset cannot be determined, it's usually safe to return "utf-8" for this value.
|
||||
///
|
||||
/// The library will consume the result and call ulDestroyString() after this call returns.
|
||||
///
|
||||
typedef ULString (*ULFileSystemGetFileCharsetCallback)(ULString path);
|
||||
|
||||
///
|
||||
/// Open file for reading and map it to a Buffer.
|
||||
///
|
||||
/// To minimize copies, you should map the requested file into memory and use ulCreateBuffer()
|
||||
/// to wrap the data pointer (unmapping should be performed in the destruction callback).
|
||||
///
|
||||
/// If the file was unable to be opened, you should return NULL for this value.
|
||||
///
|
||||
typedef ULBuffer (*ULFileSystemOpenFileCallback)(ULString path);
|
||||
|
||||
///
|
||||
/// User-defined file system interface.
|
||||
///
|
||||
/// You should implement each of these callbacks, then pass an instance of this struct containing
|
||||
/// your callbacks to ulPlatformSetFileSystem().
|
||||
///
|
||||
typedef struct {
|
||||
ULFileSystemFileExistsCallback file_exists;
|
||||
ULFileSystemGetFileMimeTypeCallback get_file_mime_type;
|
||||
ULFileSystemGetFileCharsetCallback get_file_charset;
|
||||
ULFileSystemOpenFileCallback open_file;
|
||||
} ULFileSystem;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_FILESYSTEM_H
|
||||
@@ -0,0 +1,52 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_FontFile.h
|
||||
///
|
||||
/// Font file interface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_FontFile.h>`
|
||||
///
|
||||
/// The font file interface represents a font file: either on-disk path or in-memory file contents.
|
||||
///
|
||||
/// @see ULFontLoader
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_FONTFILE_H
|
||||
#define ULTRALIGHT_CAPI_FONTFILE_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
#include <Ultralight/CAPI/CAPI_String.h>
|
||||
#include <Ultralight/CAPI/CAPI_Buffer.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Create a font file from an on-disk file path.
|
||||
///
|
||||
/// @note The file path should already exist.
|
||||
///
|
||||
ULExport ULFontFile ulFontFileCreateFromFilePath(ULString file_path);
|
||||
|
||||
///
|
||||
/// Create a font file from an in-memory buffer.
|
||||
///
|
||||
ULExport ULFontFile ulFontFileCreateFromBuffer(ULBuffer buffer);
|
||||
|
||||
///
|
||||
/// Destroy font file
|
||||
///
|
||||
ULExport void ulDestroyFontFile(ULFontFile font_file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_FONTFILE_H
|
||||
@@ -0,0 +1,99 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_FontLoader.h
|
||||
///
|
||||
/// User-defined font loader interface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_FontLoader.h>`
|
||||
///
|
||||
/// The library uses this to load a font file (eg, `Arial.ttf`) for a given font description (eg,
|
||||
/// `font-family: Arial;`).
|
||||
///
|
||||
/// Every OS has its own library of installed system fonts. The FontLoader interface is used to
|
||||
/// lookup these fonts and fetch the actual font data (raw TTF/OTF file data) for a given font
|
||||
/// description.
|
||||
///
|
||||
/// You can provide the library with your own font loader implementation so that you can bundle
|
||||
/// fonts with your application rather than relying on the system's installed fonts.
|
||||
///
|
||||
/// @see ulPlatformSetFontLoader
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_FONTLOADER_H
|
||||
#define ULTRALIGHT_CAPI_FONTLOADER_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
#include <Ultralight/CAPI/CAPI_FontFile.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Font Loader
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Fallback font family name. Will be used if all other fonts fail to load.
|
||||
///
|
||||
/// @note This font should be guaranteed to exist (eg, ULFontLoader::load should not fail when
|
||||
/// when passed this font family name).
|
||||
///
|
||||
/// @note The returned ULString instance will be consumed (ulDestroyString will be called on it).
|
||||
///
|
||||
typedef ULString (*ULFontLoaderGetFallbackFont)();
|
||||
|
||||
///
|
||||
/// Fallback font family name that can render the specified characters. This is mainly used to
|
||||
/// support CJK (Chinese, Japanese, Korean) text display.
|
||||
///
|
||||
/// @param characters One or more UTF-16 characters. This is almost always a single character.
|
||||
///
|
||||
/// @param weight Font weight.
|
||||
///
|
||||
/// @param italic Whether or not italic is requested.
|
||||
///
|
||||
/// @return Should return a font family name that can render the text. The returned ULString
|
||||
/// instance will be consumed (ulDestroyString will be called on it).
|
||||
///
|
||||
typedef ULString (*ULFontLoaderGetFallbackFontForCharacters)(ULString characters, int weight,
|
||||
bool italic);
|
||||
|
||||
///
|
||||
/// Get the actual font file data (TTF/OTF) for a given font description.
|
||||
///
|
||||
/// @param family Font family name.
|
||||
///
|
||||
/// @param weight Font weight.
|
||||
///
|
||||
/// @param italic Whether or not italic is requested.
|
||||
///
|
||||
/// @return A font file matching the given description (either an on-disk font filepath or an
|
||||
/// in-memory file buffer). You can return NULL here and the loader will fallback to
|
||||
/// another font.
|
||||
///
|
||||
typedef ULFontFile (*ULFontLoaderLoad)(ULString family, int weight, bool italic);
|
||||
|
||||
///
|
||||
/// User-defined font loader interface.
|
||||
///
|
||||
/// You should implement each of these callbacks, then pass an instance of this struct containing
|
||||
/// your callbacks to ulPlatformSetFontLoader().
|
||||
///
|
||||
typedef struct {
|
||||
ULFontLoaderGetFallbackFont get_fallback_font;
|
||||
ULFontLoaderGetFallbackFontForCharacters get_fallback_font_for_characters;
|
||||
ULFontLoaderLoad load;
|
||||
} ULFontLoader;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_FONTLOADER_H
|
||||
@@ -0,0 +1,478 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
// clang-format off
|
||||
|
||||
///
|
||||
/// @file CAPI_GPUDriver.h
|
||||
///
|
||||
/// User-defined GPU driver interface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_GPUDriver.h>`
|
||||
///
|
||||
/// The library uses this to optionally render Views on the GPU (see ulViewIsAccelerated()).
|
||||
///
|
||||
/// You can provide the library with your own GPU driver implementation so that all rendering is
|
||||
/// performed using an existing GPU context (useful for game engines).
|
||||
///
|
||||
/// When a View is rendered on the GPU, you can retrieve the backing texture ID via
|
||||
/// ulViewGetRenderTarget().
|
||||
///
|
||||
/// @see ulPlatformSetGPUDriver()
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_GPUDRIVER_H
|
||||
#define ULTRALIGHT_CAPI_GPUDRIVER_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* GPUDriver
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Render buffer description.
|
||||
///
|
||||
/// This structure describes a render buffer that can be used as a target for drawing commands.
|
||||
///
|
||||
typedef struct {
|
||||
unsigned int texture_id; ///< The backing texture for this RenderBuffer
|
||||
unsigned int width; ///< The width of the RenderBuffer texture
|
||||
unsigned int height; ///< The height of the RenderBuffer texture
|
||||
bool has_stencil_buffer; ///< Currently unused, always false.
|
||||
bool has_depth_buffer; ///< Currently unsued, always false.
|
||||
} ULRenderBuffer;
|
||||
|
||||
/// \cond ignore
|
||||
/// This pragma pack(push, 1) command is important!
|
||||
/// GPU structs should not be padded with any bytes.
|
||||
/// \endcond
|
||||
#pragma pack(push, 1)
|
||||
|
||||
///
|
||||
/// Vertex layout for path vertices.
|
||||
///
|
||||
/// This struct is the in-memory layout for each path vertex (useful for synthesizing or modifying
|
||||
/// your own vertex data).
|
||||
///
|
||||
typedef struct {
|
||||
float pos[2];
|
||||
unsigned char color[4];
|
||||
float obj[2];
|
||||
} ULVertex_2f_4ub_2f;
|
||||
|
||||
///
|
||||
/// Vertex layout for quad vertices.
|
||||
///
|
||||
/// This struct is the in-memory layout for each quad vertex (useful for synthesizing or modifying
|
||||
/// your own vertex data).
|
||||
///
|
||||
typedef struct {
|
||||
float pos[2];
|
||||
unsigned char color[4];
|
||||
float tex[2];
|
||||
float obj[2];
|
||||
float data0[4];
|
||||
float data1[4];
|
||||
float data2[4];
|
||||
float data3[4];
|
||||
float data4[4];
|
||||
float data5[4];
|
||||
float data6[4];
|
||||
} ULVertex_2f_4ub_2f_2f_28f;
|
||||
|
||||
///
|
||||
/// End single-byte alignment.
|
||||
///
|
||||
#pragma pack(pop)
|
||||
|
||||
///
|
||||
/// Vertex buffer formats.
|
||||
///
|
||||
/// This enumeration describes the format of a vertex buffer.
|
||||
///
|
||||
typedef enum {
|
||||
kVertexBufferFormat_2f_4ub_2f, ///< Vertex_2f_4ub_2f (used for path rendering)
|
||||
kVertexBufferFormat_2f_4ub_2f_2f_28f, ///< Vertex_2f_4ub_2f_2f_28f (used for quad rendering)
|
||||
} ULVertexBufferFormat;
|
||||
|
||||
///
|
||||
/// Vertex buffer description.
|
||||
///
|
||||
/// @see ULGPUDriver::create_geometry
|
||||
///
|
||||
typedef struct {
|
||||
ULVertexBufferFormat format; ///< The format of the vertex buffer.
|
||||
unsigned int size; ///< The size of the vertex buffer in bytes.
|
||||
unsigned char* data; ///< The raw vertex buffer data.
|
||||
} ULVertexBuffer;
|
||||
|
||||
///
|
||||
/// Vertex index type.
|
||||
///
|
||||
typedef unsigned int ULIndexType;
|
||||
|
||||
///
|
||||
/// Index buffer description.
|
||||
///
|
||||
/// This structure describes an index buffer that can be used to index into a vertex buffer.
|
||||
///
|
||||
/// @note The index buffer is a simple array of IndexType values.
|
||||
///
|
||||
typedef struct {
|
||||
unsigned int size; ///< The size of the index buffer in bytes.
|
||||
unsigned char* data; ///< The raw index buffer data.
|
||||
} ULIndexBuffer;
|
||||
|
||||
///
|
||||
/// Shader program types, used with ULGPUState::shader_type
|
||||
///
|
||||
/// Each of these correspond to a vertex/pixel shader pair. You can find stock shader code for these
|
||||
/// in the `shaders` folder of the AppCore repo.
|
||||
///
|
||||
typedef enum {
|
||||
kShaderType_Fill, ///< Shader program for filling quad geometry.
|
||||
kShaderType_FillPath, ///< Shader program for filling tesselated path geometry.
|
||||
} ULShaderType;
|
||||
|
||||
///
|
||||
/// Raw 4x4 matrix as an array of floats in column-major order.
|
||||
///
|
||||
typedef struct {
|
||||
float data[16];
|
||||
} ULMatrix4x4;
|
||||
|
||||
///
|
||||
/// 4-component float vector
|
||||
///
|
||||
typedef struct {
|
||||
float value[4];
|
||||
} ULvec4;
|
||||
|
||||
///
|
||||
/// The state of the GPU for a given draw command.
|
||||
///
|
||||
/// This structure describes the current state of the GPU for a given draw command.
|
||||
///
|
||||
typedef struct {
|
||||
/// Viewport width in pixels
|
||||
unsigned int viewport_width;
|
||||
|
||||
/// Viewport height in pixels
|
||||
unsigned int viewport_height;
|
||||
|
||||
/// Transform matrix-- you should multiply this with the screen-space orthographic projection
|
||||
/// matrix then pass to the vertex shader.
|
||||
ULMatrix4x4 transform;
|
||||
|
||||
/// Whether or not we should enable texturing for the current draw command.
|
||||
bool enable_texturing;
|
||||
|
||||
/// Whether or not we should enable blending for the current draw command. If blending is
|
||||
/// disabled, any drawn pixels should overwrite existing. Mainly used so we can modify alpha
|
||||
/// values of the RenderBuffer during scissored clears.
|
||||
bool enable_blend;
|
||||
|
||||
/// The vertex/pixel shader program pair to use for the current draw command. You should cast this
|
||||
/// to ShaderType to get the corresponding enum.
|
||||
unsigned char shader_type;
|
||||
|
||||
/// The render buffer to use for the current draw command.
|
||||
unsigned int render_buffer_id;
|
||||
|
||||
/// The texture id to bind to slot #1. (Will be 0 if none)
|
||||
unsigned int texture_1_id;
|
||||
|
||||
/// The texture id to bind to slot #2. (Will be 0 if none)
|
||||
unsigned int texture_2_id;
|
||||
|
||||
/// The texture id to bind to slot #3. (Will be 0 if none)
|
||||
unsigned int texture_3_id;
|
||||
|
||||
/// The uniform scalars (passed to the pixel shader via uniforms).
|
||||
float uniform_scalar[8];
|
||||
|
||||
/// The uniform vectors (passed to the pixel shader via uniforms).
|
||||
ULvec4 uniform_vector[8];
|
||||
|
||||
/// The clip size (passed to the pixel shader via uniforms).
|
||||
unsigned char clip_size;
|
||||
|
||||
/// The clip stack (passed to the pixel shader via uniforms).
|
||||
ULMatrix4x4 clip[8];
|
||||
|
||||
/// Whether or not scissor testing should be used for the current draw command.
|
||||
bool enable_scissor;
|
||||
|
||||
/// The scissor rect to use for scissor testing (units in pixels)
|
||||
ULIntRect scissor_rect;
|
||||
} ULGPUState;
|
||||
|
||||
///
|
||||
/// The types of commands.
|
||||
///
|
||||
/// This enumeration describes the type of command to execute on the GPU. Used with
|
||||
/// ULCommand::command_type
|
||||
///
|
||||
typedef enum {
|
||||
kCommandType_ClearRenderBuffer, ///< Clear the specified render buffer.
|
||||
kCommandType_DrawGeometry, ///< Draw the specified geometry to the specified render buffer.
|
||||
} ULCommandType;
|
||||
|
||||
///
|
||||
/// A command to execute on the GPU.
|
||||
///
|
||||
/// This structure describes a command to be executed on the GPU.
|
||||
///
|
||||
/// Commands are dispatched to the GPU driver asynchronously via ULGPUDriver::update_command_list,
|
||||
/// the GPU driver should consume these commands and execute them at an appropriate time.
|
||||
///
|
||||
/// @see ULCommandList
|
||||
///
|
||||
typedef struct {
|
||||
unsigned char command_type; ///< The type of command to dispatch.
|
||||
ULGPUState gpu_state; ///< The current GPU state.
|
||||
unsigned int geometry_id; ///< The geometry ID to bind. (used with kCommandType_DrawGeometry)
|
||||
unsigned int indices_count; ///< The number of indices. (used with kCommandType_DrawGeometry)
|
||||
unsigned int indices_offset; ///< The index to start from. (used with kCommandType_DrawGeometry)
|
||||
} ULCommand;
|
||||
|
||||
///
|
||||
/// List of commands to execute on the GPU.
|
||||
///
|
||||
/// @see ULGPUDriver::update_command_list
|
||||
///
|
||||
typedef struct {
|
||||
unsigned int size; ///< The number of commands in the list.
|
||||
ULCommand* commands; ///< The raw command list data.
|
||||
} ULCommandList;
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::begin_synchronize.
|
||||
///
|
||||
/// Called before any state (eg, create_texture(), update_texture(), destroy_texture(), etc.) is
|
||||
/// updated during a call to ulRender().
|
||||
///
|
||||
/// This is a good time to prepare the GPU for any state updates.
|
||||
///
|
||||
typedef void (*ULGPUDriverBeginSynchronizeCallback)();
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::end_synchronize.
|
||||
///
|
||||
/// Called after all state has been updated during a call to ulRender().
|
||||
///
|
||||
typedef void (*ULGPUDriverEndSynchronizeCallback)();
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::next_texture_id.
|
||||
///
|
||||
/// Get the next available texture ID.
|
||||
///
|
||||
/// This is used to generate a unique texture ID for each texture created by the library. The
|
||||
/// GPU driver implementation is responsible for mapping these IDs to a native ID.
|
||||
///
|
||||
/// @note Numbering should start at 1, 0 is reserved for "no texture".
|
||||
///
|
||||
/// @return Returns the next available texture ID.
|
||||
///
|
||||
typedef unsigned int (*ULGPUDriverNextTextureIdCallback)();
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::create_texture.
|
||||
///
|
||||
/// Create a texture with a certain ID and optional bitmap.
|
||||
///
|
||||
/// @param texture_id The texture ID to use for the new texture.
|
||||
///
|
||||
/// @param bitmap The bitmap to initialize the texture with (can be empty).
|
||||
///
|
||||
/// @note If the Bitmap is empty (ulBitmapIsEmpty()), then a RTT Texture should be created instead.
|
||||
/// This will be used as a backing texture for a new RenderBuffer.
|
||||
///
|
||||
/// @warning A deep copy of the bitmap data should be made if you are uploading it to the GPU
|
||||
/// asynchronously, it will not persist beyond this call.
|
||||
///
|
||||
typedef void (*ULGPUDriverCreateTextureCallback)(unsigned int texture_id, ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::update_texture.
|
||||
///
|
||||
/// Update an existing non-RTT texture with new bitmap data.
|
||||
///
|
||||
/// @param texture_id The texture to update.
|
||||
///
|
||||
/// @param bitmap The new bitmap data.
|
||||
///
|
||||
/// @warning A deep copy of the bitmap data should be made if you are uploading it to the GPU
|
||||
/// asynchronously, it will not persist beyond this call.
|
||||
///
|
||||
typedef void (*ULGPUDriverUpdateTextureCallback)(unsigned int texture_id, ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::destroy_texture.
|
||||
///
|
||||
/// Destroy a texture.
|
||||
///
|
||||
/// @param texture_id The texture to destroy.
|
||||
///
|
||||
typedef void (*ULGPUDriverDestroyTextureCallback)(unsigned int texture_id);
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::next_render_buffer_id.
|
||||
///
|
||||
/// Get the next available render buffer ID.
|
||||
///
|
||||
/// This is used to generate a unique render buffer ID for each render buffer created by the
|
||||
/// library. The GPU driver implementation is responsible for mapping these IDs to a native ID.
|
||||
///
|
||||
/// @note Numbering should start at 1, 0 is reserved for "no render buffer".
|
||||
///
|
||||
/// @return Returns the next available render buffer ID.
|
||||
///
|
||||
typedef unsigned int (*ULGPUDriverNextRenderBufferIdCallback)();
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::create_render_buffer.
|
||||
///
|
||||
/// Create a render buffer with certain ID and buffer description.
|
||||
///
|
||||
/// @param render_buffer_id The render buffer ID to use for the new render buffer.
|
||||
///
|
||||
/// @param buffer The render buffer description.
|
||||
///
|
||||
typedef void (*ULGPUDriverCreateRenderBufferCallback)(unsigned int render_buffer_id,
|
||||
ULRenderBuffer buffer);
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::destroy_render_buffer.
|
||||
///
|
||||
/// Destroy a render buffer.
|
||||
///
|
||||
/// @param render_buffer_id The render buffer to destroy.
|
||||
///
|
||||
typedef void (*ULGPUDriverDestroyRenderBufferCallback)(unsigned int render_buffer_id);
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::next_geometry_id.
|
||||
///
|
||||
/// Get the next available geometry ID.
|
||||
///
|
||||
/// This is used to generate a unique geometry ID for each geometry created by the library. The
|
||||
/// GPU driver implementation is responsible for mapping these IDs to a native ID.
|
||||
///
|
||||
/// @note Numbering should start at 1, 0 is reserved for "no geometry".
|
||||
///
|
||||
/// @return Returns the next available geometry ID.
|
||||
///
|
||||
typedef unsigned int (*ULGPUDriverNextGeometryIdCallback)();
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::create_geometry.
|
||||
///
|
||||
/// Create geometry with certain ID and vertex/index data.
|
||||
///
|
||||
/// @param geometry_id The geometry ID to use for the new geometry.
|
||||
///
|
||||
/// @param vertices The vertex buffer data.
|
||||
///
|
||||
/// @param indices The index buffer data.
|
||||
///
|
||||
/// @warning A deep copy of the vertex/index data should be made if you are uploading it to the
|
||||
/// GPU asynchronously, it will not persist beyond this call.
|
||||
///
|
||||
typedef void (*ULGPUDriverCreateGeometryCallback)(unsigned int geometry_id, ULVertexBuffer vertices,
|
||||
ULIndexBuffer indices);
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::update_geometry.
|
||||
///
|
||||
/// Update existing geometry with new vertex/index data.
|
||||
///
|
||||
/// @param geometry_id The geometry to update.
|
||||
///
|
||||
/// @param vertices The new vertex buffer data.
|
||||
///
|
||||
/// @param indices The new index buffer data.
|
||||
///
|
||||
/// @warning A deep copy of the vertex/index data should be made if you are uploading it to the
|
||||
/// GPU asynchronously, it will not persist beyond this call.
|
||||
///
|
||||
typedef void (*ULGPUDriverUpdateGeometryCallback)(unsigned int geometry_id, ULVertexBuffer vertices,
|
||||
ULIndexBuffer indices);
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::destroy_geometry.
|
||||
///
|
||||
/// Destroy geometry.
|
||||
///
|
||||
/// @param geometry_id The geometry to destroy.
|
||||
///
|
||||
typedef void (*ULGPUDriverDestroyGeometryCallback)(unsigned int geometry_id);
|
||||
|
||||
///
|
||||
/// Callback for users to implement ULGPUDriver::update_command_list.
|
||||
///
|
||||
/// Update the pending command list with commands to execute on the GPU.
|
||||
///
|
||||
/// Commands are dispatched to the GPU driver asynchronously via this method. The GPU driver
|
||||
/// implementation should consume these commands and execute them at an appropriate time.
|
||||
///
|
||||
/// @param list The list of commands to execute.
|
||||
///
|
||||
/// @warning Implementations should make a deep copy of the command list, it will not persist
|
||||
/// beyond this call.
|
||||
///
|
||||
typedef void (*ULGPUDriverUpdateCommandListCallback)(ULCommandList list);
|
||||
|
||||
///
|
||||
/// User-defined GPU driver interface.
|
||||
///
|
||||
/// You should implement each of these callbacks, then pass an instance of this struct containing
|
||||
/// your callbacks to ulPlatformSetGPUDriver().
|
||||
///
|
||||
typedef struct {
|
||||
ULGPUDriverBeginSynchronizeCallback begin_synchronize;
|
||||
ULGPUDriverEndSynchronizeCallback end_synchronize;
|
||||
ULGPUDriverNextTextureIdCallback next_texture_id;
|
||||
ULGPUDriverCreateTextureCallback create_texture;
|
||||
ULGPUDriverUpdateTextureCallback update_texture;
|
||||
ULGPUDriverDestroyTextureCallback destroy_texture;
|
||||
ULGPUDriverNextRenderBufferIdCallback next_render_buffer_id;
|
||||
ULGPUDriverCreateRenderBufferCallback create_render_buffer;
|
||||
ULGPUDriverDestroyRenderBufferCallback destroy_render_buffer;
|
||||
ULGPUDriverNextGeometryIdCallback next_geometry_id;
|
||||
ULGPUDriverCreateGeometryCallback create_geometry;
|
||||
ULGPUDriverUpdateGeometryCallback update_geometry;
|
||||
ULGPUDriverDestroyGeometryCallback destroy_geometry;
|
||||
ULGPUDriverUpdateCommandListCallback update_command_list;
|
||||
} ULGPUDriver;
|
||||
|
||||
///
|
||||
/// Sets up an orthographic projection matrix with a certain viewport width and height, multiplies
|
||||
/// it by 'transform', and returns the result.
|
||||
///
|
||||
/// This should be used to calculate the model-view projection matrix for the vertex shaders using
|
||||
/// the current ULGPUState.
|
||||
///
|
||||
/// The 'flip_y' can be optionally used to flip the Y coordinate-space. (Usually flip_y == true for
|
||||
/// OpenGL)
|
||||
///
|
||||
ULExport ULMatrix4x4 ulApplyProjection(ULMatrix4x4 transform, float viewport_width,
|
||||
float viewport_height, bool flip_y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_GPUDRIVER_H
|
||||
|
||||
// clang-format on
|
||||
@@ -0,0 +1,77 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_GamepadEvent.h
|
||||
///
|
||||
/// Gamepad event interface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_GamepadEvent.h>`
|
||||
///
|
||||
/// This file defines the C API for gamepad events.
|
||||
///
|
||||
/// @see ulFireGamepadEvent
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_GAMEPADEVENT_H
|
||||
#define ULTRALIGHT_CAPI_GAMEPADEVENT_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Gamepad Event
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create a gamepad event, see GamepadEvent for help using this function.
|
||||
///
|
||||
ULExport ULGamepadEvent ulCreateGamepadEvent(unsigned int index, ULGamepadEventType type);
|
||||
|
||||
///
|
||||
/// Destroy a gamepad event.
|
||||
///
|
||||
ULExport void ulDestroyGamepadEvent(ULGamepadEvent evt);
|
||||
|
||||
/******************************************************************************
|
||||
* Gamepad Axis Event
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create a gamepad axis event, see GamepadAxisEvent for help using this function.
|
||||
///
|
||||
ULExport ULGamepadAxisEvent ulCreateGamepadAxisEvent(unsigned int index, unsigned int axis_index,
|
||||
double value);
|
||||
|
||||
///
|
||||
/// Destroy a gamepad axis event.
|
||||
///
|
||||
ULExport void ulDestroyGamepadAxisEvent(ULGamepadAxisEvent evt);
|
||||
|
||||
/******************************************************************************
|
||||
* Gamepad Button Event
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create a gamepad button event, see GamepadButtonEvent for help using this function.
|
||||
///
|
||||
ULExport ULGamepadButtonEvent ulCreateGamepadButtonEvent(unsigned int index,
|
||||
unsigned int button_index, double value);
|
||||
|
||||
///
|
||||
/// Destroy a gamepad button event.
|
||||
///
|
||||
ULExport void ulDestroyGamepadButtonEvent(ULGamepadButtonEvent evt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_GAMEPADEVENT_H
|
||||
@@ -0,0 +1,59 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_Geometry.h
|
||||
///
|
||||
/// Geometry utilities.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_Geometry.h>`
|
||||
///
|
||||
/// This file defines the C API for various geometry utilities.
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_GEOMETRY_H
|
||||
#define ULTRALIGHT_CAPI_GEOMETRY_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Rect
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Whether or not a ULRect is empty (all members equal to 0)
|
||||
///
|
||||
ULExport bool ulRectIsEmpty(ULRect rect);
|
||||
|
||||
///
|
||||
/// Create an empty ULRect (all members equal to 0)
|
||||
///
|
||||
ULExport ULRect ulRectMakeEmpty();
|
||||
|
||||
/******************************************************************************
|
||||
* IntRect
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Whether or not a ULIntRect is empty (all members equal to 0)
|
||||
///
|
||||
ULExport bool ulIntRectIsEmpty(ULIntRect rect);
|
||||
|
||||
///
|
||||
/// Create an empty ULIntRect (all members equal to 0)
|
||||
///
|
||||
ULExport ULIntRect ulIntRectMakeEmpty();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_GEOMETRY_H
|
||||
@@ -0,0 +1,147 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_ImageSource.h
|
||||
///
|
||||
/// User-defined image source to display custom images on a web-page.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_ImageSource.h>`
|
||||
///
|
||||
/// This API allows you to composite your own images into a web-page. This is useful for displaying
|
||||
/// in-game textures, external image assets, or other custom content.
|
||||
///
|
||||
/// ## ImageSource File Format
|
||||
///
|
||||
/// To use an ImageSource, you must first create an `.imgsrc` file containing a string identifying
|
||||
/// the image source. This string will be used to lookup the ImageSource from ImageSourceProvider
|
||||
/// when it is loaded on a web-page.
|
||||
///
|
||||
/// The file format is as follows:
|
||||
///
|
||||
/// ```
|
||||
/// IMGSRC-V1
|
||||
/// <identifier>
|
||||
/// ```
|
||||
///
|
||||
/// You can use the `.imgsrc` file anywhere in your web-page that typically accepts an image URL.
|
||||
/// For example:
|
||||
///
|
||||
/// ```html
|
||||
/// <img src="my_custom_image.imgsrc" />
|
||||
/// ```
|
||||
///
|
||||
/// ## Creating from a GPU Texture
|
||||
///
|
||||
/// To composite your own GPU texture on a web-page, you should first reserve a texture ID from
|
||||
/// ULGPUDriver::next_texture_id and then create an ImageSource from that texture ID. Next, you
|
||||
/// should register the ImageSource with ImageSourceProvider using the identifier from the `.imgsrc`
|
||||
/// file.
|
||||
///
|
||||
/// When the image element is drawn on the web-page, the library will draw geometry using the
|
||||
/// specified texture ID and UV coordinates. You should bind your own texture when the specified
|
||||
/// texture ID is used.
|
||||
///
|
||||
/// If the GPU renderer is not enabled for the View or pixel data is needed for other purposes, the
|
||||
/// library will sample the backing bitmap instead.
|
||||
///
|
||||
/// ## Creating from a Bitmap
|
||||
///
|
||||
/// To composite your own bitmap on a web-page, you should create an ImageSource from a Bitmap.
|
||||
/// Next, you should register the ImageSource with ImageSourceProvider using the identifier from
|
||||
/// the `.imgsrc` file.
|
||||
///
|
||||
/// When the image element is drawn on the web-page, the library will sample this bitmap directly.
|
||||
///
|
||||
/// ## Invalidating Images
|
||||
///
|
||||
/// If you modify the texture or bitmap after creating the ImageSource, you should call
|
||||
/// ulImageSourceInvalidate() to notify the library that the image should be redrawn.
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_IMAGESOURCE_H
|
||||
#define ULTRALIGHT_CAPI_IMAGESOURCE_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* ImageSource
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create an image source from a GPU texture with optional backing bitmap.
|
||||
///
|
||||
/// @param width The width of the image in pixels (used for layout).
|
||||
///
|
||||
/// @param height The height of the image in pixels (used for layout).
|
||||
///
|
||||
/// @param texture_id The GPU texture identifier to bind when drawing the quad for this image.
|
||||
/// This should be non-zero and obtained from ULGPUDriver::next_texture_id.
|
||||
///
|
||||
/// @param texture_uv The UV coordinates of the texture.
|
||||
///
|
||||
/// @param bitmap Optional backing bitmap for this image source. This is used when drawing
|
||||
/// the image using the CPU renderer or when pixel data is needed for other
|
||||
/// purposes. You should update this bitmap when the texture changes.
|
||||
///
|
||||
/// @return A new image source instance.
|
||||
///
|
||||
ULExport ULImageSource ulCreateImageSourceFromTexture(unsigned int width, unsigned int height,
|
||||
unsigned int texture_id, ULRect texture_uv,
|
||||
ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Create an image source from a bitmap.
|
||||
///
|
||||
/// @param bitmap The backing bitmap for this image source.
|
||||
///
|
||||
/// @return A new image source instance.
|
||||
///
|
||||
ULExport ULImageSource ulCreateImageSourceFromBitmap(ULBitmap bitmap);
|
||||
|
||||
///
|
||||
/// Destroy an image source.
|
||||
///
|
||||
/// @param image_source The image source to destroy.
|
||||
///
|
||||
ULExport void ulDestroyImageSource(ULImageSource image_source);
|
||||
|
||||
///
|
||||
/// Invalidate the image source, notifying the library that the image has changed
|
||||
/// and should be redrawn.
|
||||
///
|
||||
ULExport void ulImageSourceInvalidate(ULImageSource image_source);
|
||||
|
||||
/******************************************************************************
|
||||
* ImageSourceProvider
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Add an image source to the provider.
|
||||
///
|
||||
/// @param id The identifier of the image source.
|
||||
///
|
||||
/// @param image_source The image source to add.
|
||||
///
|
||||
ULExport void ulImageSourceProviderAddImageSource(ULString id, ULImageSource image_source);
|
||||
|
||||
///
|
||||
/// Remove an image source from the provider.
|
||||
///
|
||||
/// @param id The identifier of the image source.
|
||||
///
|
||||
ULExport void ulImageSourceProviderRemoveImageSource(ULString id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_IMAGESOURCE_H
|
||||
@@ -0,0 +1,63 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_KeyEvent.h
|
||||
///
|
||||
/// Key event interface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_KeyEvent.h>`
|
||||
///
|
||||
/// This file defines the C API for various key events.
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_KEYEVENT_H
|
||||
#define ULTRALIGHT_CAPI_KEYEVENT_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Key Event
|
||||
******************************************************************************/
|
||||
|
||||
///
|
||||
/// Create a key event, see KeyEvent in the C++ API for help with the parameters.
|
||||
///
|
||||
ULExport ULKeyEvent ulCreateKeyEvent(ULKeyEventType type, unsigned int modifiers,
|
||||
int virtual_key_code, int native_key_code, ULString text,
|
||||
ULString unmodified_text, bool is_keypad, bool is_auto_repeat,
|
||||
bool is_system_key);
|
||||
|
||||
#ifdef _WIN32
|
||||
///
|
||||
/// Create a key event from native Windows event.
|
||||
///
|
||||
ULExport ULKeyEvent ulCreateKeyEventWindows(ULKeyEventType type, uintptr_t wparam, intptr_t lparam,
|
||||
bool is_system_key);
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
///
|
||||
/// Create a key event from native macOS event.
|
||||
///
|
||||
ULExport ULKeyEvent ulCreateKeyEventMacOS(NSEvent* evt);
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Destroy a key event.
|
||||
///
|
||||
ULExport void ulDestroyKeyEvent(ULKeyEvent evt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_KEYEVENT_H
|
||||
@@ -0,0 +1,50 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_Logger.h
|
||||
///
|
||||
/// User-defined logging interface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_Logger.h>`
|
||||
///
|
||||
/// The library uses this to display log messages for debugging during development.
|
||||
///
|
||||
/// This is intended to be implemented by users and defined before creating the Renderer.
|
||||
///
|
||||
/// @see ulPlatformSetLogger()
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_LOGGER_H
|
||||
#define ULTRALIGHT_CAPI_LOGGER_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Logger
|
||||
*****************************************************************************/
|
||||
|
||||
typedef enum { kLogLevel_Error = 0, kLogLevel_Warning, kLogLevel_Info } ULLogLevel;
|
||||
|
||||
///
|
||||
/// The callback invoked when the library wants to print a message to the log.
|
||||
///
|
||||
typedef void (*ULLoggerLogMessageCallback)(ULLogLevel log_level, ULString message);
|
||||
|
||||
typedef struct {
|
||||
ULLoggerLogMessageCallback log_message;
|
||||
} ULLogger;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_LOGGER_H
|
||||
@@ -0,0 +1,45 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_MouseEvent.h
|
||||
///
|
||||
/// Mouse event interface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_MouseEvent.h>`
|
||||
///
|
||||
/// This file defines the C API for mouse events.
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_MOUSEEVENT_H
|
||||
#define ULTRALIGHT_CAPI_MOUSEEVENT_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Mouse Event
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create a mouse event, see MouseEvent in the C++ API for help using this function.
|
||||
///
|
||||
ULExport ULMouseEvent ulCreateMouseEvent(ULMouseEventType type, int x, int y, ULMouseButton button);
|
||||
|
||||
///
|
||||
/// Destroy a mouse event.
|
||||
///
|
||||
ULExport void ulDestroyMouseEvent(ULMouseEvent evt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_MOUSEEVENT_H
|
||||
@@ -0,0 +1,168 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_Platform.h
|
||||
///
|
||||
/// Global platform singleton, manages user-defined platform handlers..
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_Platform.h>`
|
||||
///
|
||||
/// The library uses the Platform API for most platform-specific operations (eg, file access,
|
||||
/// clipboard, font loading, GPU access, pixel buffer transport, etc.).
|
||||
///
|
||||
/// ## Motivation
|
||||
///
|
||||
/// Ultralight is designed to work in as many platforms and environments as possible. To achieve
|
||||
/// this, we've factored out most platform-specific code into a set of interfaces that you can
|
||||
/// implement and set on the Platform singleton.
|
||||
///
|
||||
/// ## Default Implementations
|
||||
///
|
||||
/// We provide a number of default implementations for desktop platforms (eg, Windows, macOS, Linux)
|
||||
/// for you when you call ulCreateApp(). These implementations are defined in the
|
||||
/// [AppCore repository](https://github.com/ultralight-ux/AppCore/tree/master/src), we recommend
|
||||
/// using their source code as a starting point for your own implementations.
|
||||
///
|
||||
/// ## Required Handlers
|
||||
///
|
||||
/// When using ulCreateRenderer() directly, you'll need to provide your own implementations for
|
||||
/// ULFileSystem and ULFontLoader at a minimum.
|
||||
///
|
||||
/// @par Overview of which platform handlers are required / optional / provided:
|
||||
///
|
||||
/// | | ulCreateRenderer() | ulCreateApp() |
|
||||
/// |---------------------|--------------------|---------------|
|
||||
/// | ULFileSystem | **Required** | *Provided* |
|
||||
/// | ULFontLoader | **Required** | *Provided* |
|
||||
/// | ULClipboard | *Optional* | *Provided* |
|
||||
/// | ULGPUDriver | *Optional* | *Provided* |
|
||||
/// | ULLogger | *Optional* | *Provided* |
|
||||
/// | ULSurfaceDefinition | *Provided* | *Provided* |
|
||||
///
|
||||
/// @note This singleton should be set up before creating the Renderer or App.
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_PLATFORM_H
|
||||
#define ULTRALIGHT_CAPI_PLATFORM_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
#include <Ultralight/CAPI/CAPI_Logger.h>
|
||||
#include <Ultralight/CAPI/CAPI_FileSystem.h>
|
||||
#include <Ultralight/CAPI/CAPI_FontLoader.h>
|
||||
#include <Ultralight/CAPI/CAPI_Surface.h>
|
||||
#include <Ultralight/CAPI/CAPI_GPUDriver.h>
|
||||
#include <Ultralight/CAPI/CAPI_Clipboard.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Platform
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Set a custom Logger implementation.
|
||||
///
|
||||
/// This is used to log debug messages to the console or to a log file.
|
||||
///
|
||||
/// You should call this before ulCreateRenderer() or ulCreateApp().
|
||||
///
|
||||
/// @note ulCreateApp() will use the default logger if you never call this.
|
||||
///
|
||||
/// @note If you're not using ulCreateApp(), (eg, using ulCreateRenderer()) you can still use the
|
||||
/// default logger by calling ulEnableDefaultLogger() (@see <AppCore/CAPI.h>)
|
||||
///
|
||||
ULExport void ulPlatformSetLogger(ULLogger logger);
|
||||
|
||||
///
|
||||
/// Set a custom FileSystem implementation.
|
||||
///
|
||||
/// The library uses this to load all file URLs (eg, <file:///page.html>).
|
||||
///
|
||||
/// You can provide the library with your own FileSystem implementation so that file assets are
|
||||
/// loaded from your own pipeline.
|
||||
///
|
||||
/// You should call this before ulCreateRenderer() or ulCreateApp().
|
||||
///
|
||||
/// @warning This is required to be defined before calling ulCreateRenderer()
|
||||
///
|
||||
/// @note ulCreateApp() will use the default platform file system if you never call this.
|
||||
///
|
||||
/// @note If you're not using ulCreateApp(), (eg, using ulCreateRenderer()) you can still use the
|
||||
/// default platform file system by calling ulEnablePlatformFileSystem()'
|
||||
/// (@see <AppCore/CAPI.h>)
|
||||
///
|
||||
ULExport void ulPlatformSetFileSystem(ULFileSystem file_system);
|
||||
|
||||
///
|
||||
/// Set a custom FontLoader implementation.
|
||||
///
|
||||
/// The library uses this to load all system fonts.
|
||||
///
|
||||
/// Every operating system has its own library of installed system fonts. The FontLoader interface
|
||||
/// is used to lookup these fonts and fetch the actual font data (raw TTF/OTF file data) for a given
|
||||
/// given font description.
|
||||
///
|
||||
/// You should call this before ulCreateRenderer() or ulCreateApp().
|
||||
///
|
||||
/// @warning This is required to be defined before calling ulCreateRenderer()
|
||||
///
|
||||
/// @note ulCreateApp() will use the default platform font loader if you never call this.
|
||||
///
|
||||
/// @note If you're not using ulCreateApp(), (eg, using ulCreateRenderer()) you can still use the
|
||||
/// default platform font loader by calling ulEnablePlatformFontLoader()'
|
||||
/// (@see <AppCore/CAPI.h>)
|
||||
///
|
||||
ULExport void ulPlatformSetFontLoader(ULFontLoader font_loader);
|
||||
|
||||
///
|
||||
/// Set a custom Surface implementation.
|
||||
///
|
||||
/// This can be used to wrap a platform-specific GPU texture, Windows DIB, macOS CGImage, or any
|
||||
/// other pixel buffer target for display on screen.
|
||||
///
|
||||
/// By default, the library uses a bitmap surface for all surfaces but you can override this by
|
||||
/// providing your own surface definition here.
|
||||
///
|
||||
/// You should call this before ulCreateRenderer() or ulCreateApp().
|
||||
///
|
||||
ULExport void ulPlatformSetSurfaceDefinition(ULSurfaceDefinition surface_definition);
|
||||
|
||||
///
|
||||
/// Set a custom GPUDriver implementation.
|
||||
///
|
||||
/// This should be used if you have enabled the GPU renderer in the Config and are using
|
||||
/// ulCreateRenderer() (which does not provide its own GPUDriver implementation).
|
||||
///
|
||||
/// The GPUDriver interface is used by the library to dispatch GPU calls to your native GPU context
|
||||
/// (eg, D3D11, Metal, OpenGL, Vulkan, etc.) There are reference implementations for this interface
|
||||
/// in the AppCore repo.
|
||||
///
|
||||
/// You should call this before ulCreateRenderer().
|
||||
///
|
||||
ULExport void ulPlatformSetGPUDriver(ULGPUDriver gpu_driver);
|
||||
|
||||
///
|
||||
/// Set a custom Clipboard implementation.
|
||||
///
|
||||
/// This should be used if you are using ulCreateRenderer() (which does not provide its own
|
||||
/// clipboard implementation).
|
||||
///
|
||||
/// The Clipboard interface is used by the library to make calls to the system's native clipboard
|
||||
/// (eg, cut, copy, paste).
|
||||
///
|
||||
/// You should call this before ulCreateRenderer().
|
||||
///
|
||||
ULExport void ulPlatformSetClipboard(ULClipboard clipboard);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_PLATFORM_H
|
||||
@@ -0,0 +1,278 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_Renderer.h
|
||||
///
|
||||
/// Core renderer singleton for the library, coordinates all library functions.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_Renderer.h>`
|
||||
///
|
||||
/// The Renderer class is responsible for creating and painting Views, managing Sessions, as well
|
||||
/// as coordinating network requests, events, JavaScript execution, and more.
|
||||
///
|
||||
/// ## Creating the Renderer
|
||||
///
|
||||
/// @note A Renderer will be created for you automatically when you call ulCreateApp (access it
|
||||
/// via ulAppGetRenderer()).
|
||||
///
|
||||
/// @note ulCreateApp() is part of the AppCore API and automatically manages window creation, run
|
||||
/// loop, input, painting, and most platform-specific functionality. (Available on desktop
|
||||
/// platforms only)
|
||||
/// \endparblock
|
||||
///
|
||||
/// ### Defining Platform Handlers
|
||||
///
|
||||
/// Before creating the Renderer, you should define your platform handlers via the Platform
|
||||
/// singleton (see CAPI_Platform.h). This can be used to customize file loading, font loading,
|
||||
/// clipboard access, and other functionality typically provided by the OS.
|
||||
///
|
||||
/// Default implementations for most platform handlers are available in the
|
||||
/// [AppCore repo](https://github.com/ultralight-ux/AppCore/tree/master/src). You can use these
|
||||
/// stock implementations by copying the code into your project, or you can write your own.
|
||||
///
|
||||
/// At a minimum, you should provide a ULFileSystem and ULFontLoader otherwise Renderer creation will
|
||||
/// fail.
|
||||
///
|
||||
/// ### Creating the Renderer
|
||||
///
|
||||
/// Once you've set up the Platform handlers you can create the Renderer by calling
|
||||
/// `ulCreateRenderer()`.
|
||||
///
|
||||
/// @par Example creation code
|
||||
/// ```
|
||||
/// // Setup our config.
|
||||
/// ULConfig config = ulCreateConfig();
|
||||
///
|
||||
/// // Use AppCore's font loader.
|
||||
/// ulEnablePlatformFontLoader();
|
||||
///
|
||||
/// // Use AppCore's file system to load file:/// URLs from the OS.
|
||||
/// ULString base_dir = ulCreateString("./assets/");
|
||||
/// ulEnablePlatformFileSystem(base_dir);
|
||||
/// ulDestroyString(base_dir);
|
||||
///
|
||||
/// // Create the renderer.
|
||||
/// ULRenderer renderer = ulCreateRenderer(config);
|
||||
///
|
||||
/// // Destroy the config.
|
||||
/// ulDestroyConfig(config);
|
||||
///
|
||||
/// // Set up Views here...
|
||||
/// ```
|
||||
///
|
||||
/// ## Updating Renderer Logic
|
||||
///
|
||||
/// You should call ulUpdate() from your main update loop as often as possible to give the
|
||||
/// library an opportunity to dispatch events and timers:
|
||||
///
|
||||
/// @par Example update code
|
||||
/// ```
|
||||
/// void mainLoop()
|
||||
/// {
|
||||
/// while(true)
|
||||
/// {
|
||||
/// // Update program logic here
|
||||
/// ulUpdate(renderer);
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ## Rendering Each Frame
|
||||
///
|
||||
/// When your program is ready to display a new frame (usually in synchrony with the monitor
|
||||
/// refresh rate), you should call `ulRefreshDisplay()` and `ulRender` so the
|
||||
/// library can render all active Views as needed.
|
||||
///
|
||||
/// @par Example per-frame render code
|
||||
/// ```
|
||||
/// void displayFrame()
|
||||
/// {
|
||||
/// // Notify the renderer that the main display has refreshed. This will update animations,
|
||||
/// // smooth scroll, and window.requestAnimationFrame() for all Views matching the display id.
|
||||
/// ulRefreshDisplay(renderer, 0);
|
||||
///
|
||||
/// // Render all Views as needed
|
||||
/// ulRender(renderer);
|
||||
///
|
||||
/// // Each View will render to a
|
||||
/// // - Pixel-Buffer Surface (ulViewGetSurface())
|
||||
/// // or
|
||||
/// // - GPU texture (ulViewGetRenderTarget())
|
||||
/// // based on whether CPU or GPU rendering is used.
|
||||
/// //
|
||||
/// // You will need to display the image data here as needed.
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_RENDERER_H
|
||||
#define ULTRALIGHT_CAPI_RENDERER_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Create the core renderer singleton for the library.
|
||||
///
|
||||
/// You should set up the Platform singleton (see CAPI_Platform.h) before calling this function.
|
||||
///
|
||||
/// @note You do not need to the call this if you're using ulCreateApp() from AppCore.
|
||||
///
|
||||
/// \parblock
|
||||
/// @warning You'll need to define a ULFontLoader and ULFileSystem within the Platform singleton
|
||||
/// or else this call will fail.
|
||||
/// \endparblock
|
||||
///
|
||||
/// \parblock
|
||||
/// @warning You should only create one Renderer during the lifetime of your program.
|
||||
/// \endparblock
|
||||
///
|
||||
/// @param config The configuration to use for the renderer.
|
||||
///
|
||||
/// @return Returns the new renderer instance.
|
||||
///
|
||||
ULExport ULRenderer ulCreateRenderer(ULConfig config);
|
||||
|
||||
///
|
||||
/// Destroy the renderer.
|
||||
///
|
||||
/// @param renderer The renderer instance to destroy.
|
||||
///
|
||||
ULExport void ulDestroyRenderer(ULRenderer renderer);
|
||||
|
||||
///
|
||||
/// Update timers and dispatch internal callbacks (JavaScript and network).
|
||||
///
|
||||
/// @param renderer The active renderer instance.
|
||||
///
|
||||
ULExport void ulUpdate(ULRenderer renderer);
|
||||
|
||||
///
|
||||
/// Notify the renderer that a display has refreshed (you should call this after vsync).
|
||||
///
|
||||
/// This updates animations, smooth scroll, and window.requestAnimationFrame() for all Views
|
||||
/// matching the display id.
|
||||
///
|
||||
/// @param renderer The active renderer instance.
|
||||
///
|
||||
/// @param display_id The display ID to refresh (0 by default).
|
||||
///
|
||||
ULExport void ulRefreshDisplay(ULRenderer renderer, unsigned int display_id);
|
||||
|
||||
///
|
||||
/// Render all active Views to their respective surfaces and render targets.
|
||||
///
|
||||
/// @param renderer The active renderer instance.
|
||||
///
|
||||
ULExport void ulRender(ULRenderer renderer);
|
||||
|
||||
///
|
||||
/// Attempt to release as much memory as possible. Don't call this from any callbacks or driver
|
||||
/// code.
|
||||
///
|
||||
/// @param renderer The active renderer instance.
|
||||
///
|
||||
ULExport void ulPurgeMemory(ULRenderer renderer);
|
||||
|
||||
///
|
||||
/// Print detailed memory usage statistics to the log. (@see ulPlatformSetLogger)
|
||||
///
|
||||
/// @param renderer The active renderer instance.
|
||||
///
|
||||
ULExport void ulLogMemoryUsage(ULRenderer renderer);
|
||||
|
||||
///
|
||||
/// Start the remote inspector server.
|
||||
///
|
||||
/// While the remote inspector is active, Views that are loaded into this renderer
|
||||
/// will be able to be remotely inspected from another Ultralight instance either locally
|
||||
/// (another app on same machine) or remotely (over the network) by navigating a View to:
|
||||
///
|
||||
/// \code
|
||||
/// inspector://<ADDRESS>:<PORT>
|
||||
/// \endcode
|
||||
///
|
||||
/// @param renderer The active renderer instance.
|
||||
///
|
||||
/// @param address The address for the server to listen on (eg, "127.0.0.1")
|
||||
///
|
||||
/// @param port The port for the server to listen on (eg, 9222)
|
||||
///
|
||||
/// @return Returns whether the server started successfully or not.
|
||||
///
|
||||
ULExport bool ulStartRemoteInspectorServer(ULRenderer renderer, const char* address,
|
||||
unsigned short port);
|
||||
|
||||
///
|
||||
/// Describe the details of a gamepad, to be used with ulFireGamepadEvent and related
|
||||
/// events below. This can be called multiple times with the same index if the details change.
|
||||
///
|
||||
/// @param renderer The active renderer instance.
|
||||
///
|
||||
/// @param index The unique index (or "connection slot") of the gamepad. For example,
|
||||
/// controller #1 would be "1", controller #2 would be "2" and so on.
|
||||
///
|
||||
/// @param id A string ID representing the device, this will be made available
|
||||
/// in JavaScript as gamepad.id
|
||||
///
|
||||
/// @param axis_count The number of axes on the device.
|
||||
///
|
||||
/// @param button_count The number of buttons on the device.
|
||||
///
|
||||
ULExport void ulSetGamepadDetails(ULRenderer renderer, unsigned int index, ULString id,
|
||||
unsigned int axis_count, unsigned int button_count);
|
||||
|
||||
///
|
||||
/// Fire a gamepad event (connection / disconnection).
|
||||
///
|
||||
/// @note The gamepad should first be described via ulSetGamepadDetails before calling this
|
||||
/// function.
|
||||
///
|
||||
/// @param renderer The active renderer instance.
|
||||
///
|
||||
/// @param evt The event to fire.
|
||||
///
|
||||
/// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad>
|
||||
///
|
||||
ULExport void ulFireGamepadEvent(ULRenderer renderer, ULGamepadEvent evt);
|
||||
|
||||
///
|
||||
/// Fire a gamepad axis event (to be called when an axis value is changed).
|
||||
///
|
||||
/// @note The gamepad should be connected via a previous call to ulFireGamepadEvent.
|
||||
///
|
||||
/// @param renderer The active renderer instance.
|
||||
///
|
||||
/// @param evt The event to fire.
|
||||
///
|
||||
/// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad/axes>
|
||||
///
|
||||
ULExport void ulFireGamepadAxisEvent(ULRenderer renderer, ULGamepadAxisEvent evt);
|
||||
|
||||
///
|
||||
/// Fire a gamepad button event (to be called when a button value is changed).
|
||||
///
|
||||
/// @note The gamepad should be connected via a previous call to ulFireGamepadEvent.
|
||||
///
|
||||
/// @param renderer The active renderer instance.
|
||||
///
|
||||
/// @param evt The event to fire.
|
||||
///
|
||||
/// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad/buttons>
|
||||
///
|
||||
ULExport void ulFireGamepadButtonEvent(ULRenderer renderer, ULGamepadButtonEvent evt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_RENDERER_H
|
||||
@@ -0,0 +1,45 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_ScrollEvent.h
|
||||
///
|
||||
/// Scroll event interface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_ScrollEvent.h>`
|
||||
///
|
||||
/// This file defines the C API for scroll events.
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_SCROLLEVENT_H
|
||||
#define ULTRALIGHT_CAPI_SCROLLEVENT_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Scroll Event
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create a scroll event, see ScrollEvent in the C++ API for help using this function.
|
||||
///
|
||||
ULExport ULScrollEvent ulCreateScrollEvent(ULScrollEventType type, int delta_x, int delta_y);
|
||||
|
||||
///
|
||||
/// Destroy a scroll event.
|
||||
///
|
||||
ULExport void ulDestroyScrollEvent(ULScrollEvent evt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_SCROLLEVENT_H
|
||||
@@ -0,0 +1,84 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_Session.h
|
||||
///
|
||||
/// Storage for a browsing session (cookies, local storage, etc.).
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_Session.h>`
|
||||
///
|
||||
/// This class stores data for a unique browsing session (cookies, local storage, application cache,
|
||||
/// indexed db. etc.). You can create multiple sessions to isolate data between different browsing
|
||||
/// contexts.
|
||||
///
|
||||
/// ## Default Session
|
||||
///
|
||||
/// The library has a default session named "default" that is used if no session is specified when
|
||||
/// when creating a View.
|
||||
///
|
||||
/// ## Session Lifetime
|
||||
///
|
||||
/// Sessions can be either temporary (in-memory only) or persistent (backed to disk).
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_SESSION_H
|
||||
#define ULTRALIGHT_CAPI_SESSION_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Session
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create a Session to store local data in (such as cookies, local storage, application cache,
|
||||
/// indexed db, etc).
|
||||
///
|
||||
ULExport ULSession ulCreateSession(ULRenderer renderer, bool is_persistent, ULString name);
|
||||
|
||||
///
|
||||
/// Destroy a Session.
|
||||
///
|
||||
ULExport void ulDestroySession(ULSession session);
|
||||
|
||||
///
|
||||
/// Get the default session (persistent session named "default").
|
||||
///
|
||||
/// @note This session is owned by the Renderer, you shouldn't destroy it.
|
||||
///
|
||||
ULExport ULSession ulDefaultSession(ULRenderer renderer);
|
||||
|
||||
///
|
||||
/// Whether or not is persistent (backed to disk).
|
||||
///
|
||||
ULExport bool ulSessionIsPersistent(ULSession session);
|
||||
|
||||
///
|
||||
/// Unique name identifying the session (used for unique disk path).
|
||||
///
|
||||
ULExport ULString ulSessionGetName(ULSession session);
|
||||
|
||||
///
|
||||
/// Unique numeric Id for the session.
|
||||
///
|
||||
ULExport unsigned long long ulSessionGetId(ULSession session);
|
||||
|
||||
///
|
||||
/// The disk path to write to (used by persistent sessions only).
|
||||
///
|
||||
ULExport ULString ulSessionGetDiskPath(ULSession session);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_SESSION_H
|
||||
@@ -0,0 +1,86 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_String.h
|
||||
///
|
||||
/// Unicode string container (natively UTF-8).
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_String.h>`
|
||||
///
|
||||
/// This class is used to represent strings in Ultralight. It can be created from a variety of
|
||||
/// string types (ASCII, UTF-8, UTF-16) and accessed as a null-terminated UTF-8 buffer.
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_STRING_H
|
||||
#define ULTRALIGHT_CAPI_STRING_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* String
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create string from null-terminated ASCII C-string.
|
||||
///
|
||||
ULExport ULString ulCreateString(const char* str);
|
||||
|
||||
///
|
||||
/// Create string from UTF-8 buffer.
|
||||
///
|
||||
ULExport ULString ulCreateStringUTF8(const char* str, size_t len);
|
||||
|
||||
///
|
||||
/// Create string from UTF-16 buffer.
|
||||
///
|
||||
ULExport ULString ulCreateStringUTF16(ULChar16* str, size_t len);
|
||||
|
||||
///
|
||||
/// Create string from copy of existing string.
|
||||
///
|
||||
ULExport ULString ulCreateStringFromCopy(ULString str);
|
||||
|
||||
///
|
||||
/// Destroy string (you should destroy any strings you explicitly Create).
|
||||
///
|
||||
ULExport void ulDestroyString(ULString str);
|
||||
|
||||
///
|
||||
/// Get native UTF-8 buffer data (always null-terminated).
|
||||
///
|
||||
ULExport char* ulStringGetData(ULString str);
|
||||
|
||||
///
|
||||
/// Get length (in bytes) of the UTF-8 buffer data, not including null terminator.
|
||||
///
|
||||
ULExport size_t ulStringGetLength(ULString str);
|
||||
|
||||
///
|
||||
/// Whether this string is empty or not.
|
||||
///
|
||||
ULExport bool ulStringIsEmpty(ULString str);
|
||||
|
||||
///
|
||||
/// Replaces the contents of 'str' with the contents of 'new_str'
|
||||
///
|
||||
ULExport void ulStringAssignString(ULString str, ULString new_str);
|
||||
|
||||
///
|
||||
/// Replaces the contents of 'str' with the contents of a C-string.
|
||||
///
|
||||
ULExport void ulStringAssignCString(ULString str, const char* c_str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_STRING_H
|
||||
@@ -0,0 +1,250 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_Surface.h
|
||||
///
|
||||
/// User-defined pixel buffer surface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_Surface.h>`
|
||||
///
|
||||
/// The library uses this to store pixel data when rendering Views on the CPU (see
|
||||
/// ulViewIsAccelerated()).
|
||||
///
|
||||
/// You can provide the library with your own Surface implementation to reduce the latency of
|
||||
/// displaying pixels in your application (Views will be drawn directly to a block of memory
|
||||
/// controlled by you).
|
||||
///
|
||||
/// When a View is rendered on the CPU, you can retrieve the backing Surface via ulViewGetSurface().
|
||||
///
|
||||
/// @pre This is automatically managed for you when using ulCreateApp(), if you want to override
|
||||
/// ULSurfaceDefinition, you'll need to use ulCreateRenderer() instead.
|
||||
///
|
||||
/// ## Default Implementation
|
||||
///
|
||||
/// A default Surface implementation, BitmapSurface, is automatically provided by the library when
|
||||
/// you call ulCreateRenderer() without defining a custom ULSurfaceDefinition.
|
||||
///
|
||||
/// You should cast the ULSurface to a ULBitmapSurface and call ulBitmapSurfaceGetBitmap() to access
|
||||
/// the underlying Bitmap.
|
||||
///
|
||||
/// ## Setting the Surface Implementation
|
||||
///
|
||||
/// To define your own implementation, you should implement the ULSurfaceDefinition callbacks,
|
||||
/// and then pass an instance of ULSurfaceDefinition containing your callbacks to
|
||||
/// ulPlatformSetSurfaceDefinition() before calling ulCreateRenderer().
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_SURFACE_H
|
||||
#define ULTRALIGHT_CAPI_SURFACE_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Surface
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Width (in pixels).
|
||||
///
|
||||
ULExport unsigned int ulSurfaceGetWidth(ULSurface surface);
|
||||
|
||||
///
|
||||
/// Height (in pixels).
|
||||
///
|
||||
ULExport unsigned int ulSurfaceGetHeight(ULSurface surface);
|
||||
|
||||
///
|
||||
/// Number of bytes between rows (usually width * 4)
|
||||
///
|
||||
ULExport unsigned int ulSurfaceGetRowBytes(ULSurface surface);
|
||||
|
||||
///
|
||||
/// Size in bytes.
|
||||
///
|
||||
ULExport size_t ulSurfaceGetSize(ULSurface surface);
|
||||
|
||||
///
|
||||
/// Lock the pixel buffer and get a pointer to the beginning of the data for reading/writing.
|
||||
///
|
||||
/// Native pixel format is premultiplied BGRA 32-bit (8 bits per channel).
|
||||
///
|
||||
ULExport void* ulSurfaceLockPixels(ULSurface surface);
|
||||
|
||||
///
|
||||
/// Unlock the pixel buffer.
|
||||
///
|
||||
ULExport void ulSurfaceUnlockPixels(ULSurface surface);
|
||||
|
||||
///
|
||||
/// Resize the pixel buffer to a certain width and height (both in pixels).
|
||||
///
|
||||
/// This should never be called while pixels are locked.
|
||||
///
|
||||
ULExport void ulSurfaceResize(ULSurface surface, unsigned int width, unsigned int height);
|
||||
|
||||
///
|
||||
/// Set the dirty bounds to a certain value.
|
||||
///
|
||||
/// This is called after the Renderer paints to an area of the pixel buffer. (The new value will be
|
||||
/// joined with the existing dirty_bounds())
|
||||
///
|
||||
ULExport void ulSurfaceSetDirtyBounds(ULSurface surface, ULIntRect bounds);
|
||||
|
||||
///
|
||||
/// Get the dirty bounds.
|
||||
///
|
||||
/// This value can be used to determine which portion of the pixel buffer has been updated since the
|
||||
/// last call to ulSurfaceClearDirtyBounds().
|
||||
///
|
||||
/// The general algorithm to determine if a Surface needs display is:
|
||||
/// <pre>
|
||||
/// if (!ulIntRectIsEmpty(ulSurfaceGetDirtyBounds(surface))) {
|
||||
/// // Surface pixels are dirty and needs display.
|
||||
/// // Cast Surface to native Surface and use it here (pseudo code)
|
||||
/// DisplaySurface(surface);
|
||||
///
|
||||
/// // Once you're done, clear the dirty bounds:
|
||||
/// ulSurfaceClearDirtyBounds(surface);
|
||||
/// }
|
||||
/// </pre>
|
||||
///
|
||||
ULExport ULIntRect ulSurfaceGetDirtyBounds(ULSurface surface);
|
||||
|
||||
///
|
||||
/// Clear the dirty bounds.
|
||||
///
|
||||
/// You should call this after you're done displaying the Surface.
|
||||
///
|
||||
ULExport void ulSurfaceClearDirtyBounds(ULSurface surface);
|
||||
|
||||
///
|
||||
/// Get the underlying user data pointer (this is only valid if you have set a custom surface
|
||||
/// implementation via ulPlatformSetSurfaceDefinition).
|
||||
///
|
||||
/// This will return nullptr if this surface is the default ULBitmapSurface.
|
||||
///
|
||||
ULExport void* ulSurfaceGetUserData(ULSurface surface);
|
||||
|
||||
/******************************************************************************
|
||||
* BitmapSurface
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Get the underlying Bitmap from the default Surface.
|
||||
///
|
||||
/// @note Do not call ulDestroyBitmap() on the returned value, it is owned by the surface.
|
||||
///
|
||||
ULExport ULBitmap ulBitmapSurfaceGetBitmap(ULBitmapSurface surface);
|
||||
|
||||
/******************************************************************************
|
||||
* Surface Definition
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// The callback invoked when a Surface is created.
|
||||
///
|
||||
/// @param width The width in pixels.
|
||||
/// @param height The height in pixels.
|
||||
///
|
||||
/// @return This callback should return a pointer to user-defined data for the instance. This user
|
||||
/// data pointer will be passed to all other callbacks when operating on the instance.
|
||||
///
|
||||
typedef void* (*ULSurfaceDefinitionCreateCallback)(unsigned int width, unsigned int height);
|
||||
|
||||
///
|
||||
/// The callback invoked when a Surface is destroyed.
|
||||
///
|
||||
/// @param user_data User data pointer uniquely identifying the surface.
|
||||
///
|
||||
typedef void (*ULSurfaceDefinitionDestroyCallback)(void* user_data);
|
||||
|
||||
///
|
||||
/// The callback invoked when a Surface's width (in pixels) is requested.
|
||||
///
|
||||
/// @param user_data User data pointer uniquely identifying the surface.
|
||||
///
|
||||
typedef unsigned int (*ULSurfaceDefinitionGetWidthCallback)(void* user_data);
|
||||
|
||||
///
|
||||
/// The callback invoked when a Surface's height (in pixels) is requested.
|
||||
///
|
||||
/// @param user_data User data pointer uniquely identifying the surface.
|
||||
///
|
||||
typedef unsigned int (*ULSurfaceDefinitionGetHeightCallback)(void* user_data);
|
||||
|
||||
///
|
||||
/// The callback invoked when a Surface's row bytes is requested.
|
||||
///
|
||||
/// @note This value is also known as "stride". Usually width * 4.
|
||||
///
|
||||
/// @param user_data User data pointer uniquely identifying the surface.
|
||||
///
|
||||
typedef unsigned int (*ULSurfaceDefinitionGetRowBytesCallback)(void* user_data);
|
||||
|
||||
///
|
||||
/// The callback invoked when a Surface's size (in bytes) is requested.
|
||||
///
|
||||
/// @param user_data User data pointer uniquely identifying the surface.
|
||||
///
|
||||
typedef size_t (*ULSurfaceDefinitionGetSizeCallback)(void* user_data);
|
||||
|
||||
///
|
||||
/// The callback invoked when a Surface's pixel buffer is requested to be locked for reading/writing
|
||||
/// (should return a pointer to locked bytes).
|
||||
///
|
||||
/// @param user_data User data pointer uniquely identifying the surface.
|
||||
///
|
||||
typedef void* (*ULSurfaceDefinitionLockPixelsCallback)(void* user_data);
|
||||
|
||||
///
|
||||
/// The callback invoked when a Surface's pixel buffer is requested to be unlocked after previously
|
||||
/// being locked.
|
||||
///
|
||||
/// @param user_data User data pointer uniquely identifying the surface.
|
||||
///
|
||||
typedef void (*ULSurfaceDefinitionUnlockPixelsCallback)(void* user_data);
|
||||
|
||||
///
|
||||
/// The callback invoked when a Surface is requested to be resized to a certain width/height.
|
||||
///
|
||||
/// @param user_data User data pointer uniquely identifying the surface.
|
||||
///
|
||||
/// @param width Width in pixels.
|
||||
///
|
||||
/// @param height Height in pixels.
|
||||
///
|
||||
typedef void (*ULSurfaceDefinitionResizeCallback)(void* user_data, unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
///
|
||||
/// User-defined surface interface.
|
||||
///
|
||||
/// You should implement each of these callbacks, then pass an instance of this struct containing
|
||||
/// your callbacks to ulPlatformSetSurfaceDefinition().
|
||||
///
|
||||
typedef struct {
|
||||
ULSurfaceDefinitionCreateCallback create;
|
||||
ULSurfaceDefinitionDestroyCallback destroy;
|
||||
ULSurfaceDefinitionGetWidthCallback get_width;
|
||||
ULSurfaceDefinitionGetHeightCallback get_height;
|
||||
ULSurfaceDefinitionGetRowBytesCallback get_row_bytes;
|
||||
ULSurfaceDefinitionGetSizeCallback get_size;
|
||||
ULSurfaceDefinitionLockPixelsCallback lock_pixels;
|
||||
ULSurfaceDefinitionUnlockPixelsCallback unlock_pixels;
|
||||
ULSurfaceDefinitionResizeCallback resize;
|
||||
} ULSurfaceDefinition;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_SURFACE_H
|
||||
@@ -0,0 +1,554 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
///
|
||||
/// @file CAPI_View.h
|
||||
///
|
||||
/// Web-page container rendered to an offscreen surface.
|
||||
///
|
||||
/// `#include <Ultralight/CAPI/CAPI_View.h>`
|
||||
///
|
||||
/// The View class is responsible for loading and rendering web-pages to an offscreen surface. It
|
||||
/// is completely isolated from the OS windowing system, you must forward all input events to it
|
||||
/// from your application.
|
||||
///
|
||||
/// ## Creating a View
|
||||
///
|
||||
/// You can create a View by calling ulCreateView():
|
||||
///
|
||||
/// ```
|
||||
/// // Create a ULViewConfig with default values
|
||||
/// ULViewConfig view_config = ulCreateViewConfig();
|
||||
///
|
||||
/// // Create a View, 500 by 500 pixels in size, using the default Session
|
||||
/// ULView view = ulCreateView(renderer, 500, 500, view_config, NULL);
|
||||
///
|
||||
/// // Clean up the ULViewConfig
|
||||
/// ulDestroyViewConfig(view_config);
|
||||
/// ```
|
||||
///
|
||||
/// @note When using ulCreateApp(), the library will automatically create a View for you when you
|
||||
/// call ulCreateOverlay().
|
||||
///
|
||||
#ifndef ULTRALIGHT_CAPI_VIEW_H
|
||||
#define ULTRALIGHT_CAPI_VIEW_H
|
||||
|
||||
#include <Ultralight/CAPI/CAPI_Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* ViewConfig
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create view configuration with default values (see <Ultralight/platform/View.h>).
|
||||
///
|
||||
ULExport ULViewConfig ulCreateViewConfig();
|
||||
|
||||
///
|
||||
/// Destroy view configuration.
|
||||
///
|
||||
ULExport void ulDestroyViewConfig(ULViewConfig config);
|
||||
|
||||
///
|
||||
/// Set a user-generated id of the display (monitor, TV, or screen) that the View will be shown on.
|
||||
///
|
||||
/// Animations are driven based on the physical refresh rate of the display. Multiple Views can
|
||||
/// share the same display.
|
||||
///
|
||||
///
|
||||
/// @note This is automatically managed for you when ulCreateApp() is used.
|
||||
///
|
||||
/// @see ulRefreshDisplay()
|
||||
///
|
||||
ULExport void ulViewConfigSetDisplayId(ULViewConfig config, unsigned int display_id);
|
||||
|
||||
///
|
||||
/// Set whether to render using the GPU renderer (accelerated) or the CPU renderer (unaccelerated).
|
||||
///
|
||||
/// This option is only valid if you're managing the Renderer yourself (eg, you've previously
|
||||
/// called ulCreateRenderer() instead of ulCreateApp()).
|
||||
///
|
||||
/// When true, the View will be rendered to an offscreen GPU texture using the GPU driver set in
|
||||
/// ulPlatformSetGPUDriver(). You can fetch details for the texture via ulViewGetRenderTarget().
|
||||
///
|
||||
/// When false (the default), the View will be rendered to an offscreen pixel buffer using the
|
||||
/// multithreaded CPU renderer. This pixel buffer can optionally be provided by the user--
|
||||
/// for more info see ulViewGetSurface().
|
||||
///
|
||||
ULExport void ulViewConfigSetIsAccelerated(ULViewConfig config, bool is_accelerated);
|
||||
|
||||
///
|
||||
/// Set whether images should be enabled (Default = True).
|
||||
///
|
||||
ULExport void ulViewConfigSetIsTransparent(ULViewConfig config, bool is_transparent);
|
||||
|
||||
///
|
||||
/// Set the initial device scale, ie. the amount to scale page units to screen pixels. This should be
|
||||
/// set to the scaling factor of the device that the View is displayed on. (Default = 1.0)
|
||||
///
|
||||
/// @note 1.0 is equal to 100% zoom (no scaling), 2.0 is equal to 200% zoom (2x scaling)
|
||||
///
|
||||
ULExport void ulViewConfigSetInitialDeviceScale(ULViewConfig config, double initial_device_scale);
|
||||
|
||||
///
|
||||
/// Set whether or not the View should initially have input focus. (Default = True)
|
||||
///
|
||||
ULExport void ulViewConfigSetInitialFocus(ULViewConfig config, bool is_focused);
|
||||
|
||||
///
|
||||
/// Set whether images should be enabled (Default = True).
|
||||
///
|
||||
ULExport void ulViewConfigSetEnableImages(ULViewConfig config, bool enabled);
|
||||
|
||||
///
|
||||
/// Set whether JavaScript should be enabled (Default = True).
|
||||
///
|
||||
ULExport void ulViewConfigSetEnableJavaScript(ULViewConfig config, bool enabled);
|
||||
|
||||
///
|
||||
/// Set default font-family to use (Default = Times New Roman).
|
||||
///
|
||||
ULExport void ulViewConfigSetFontFamilyStandard(ULViewConfig config, ULString font_name);
|
||||
|
||||
///
|
||||
/// Set default font-family to use for fixed fonts, eg <pre> and <code>
|
||||
/// (Default = Courier New).
|
||||
///
|
||||
ULExport void ulViewConfigSetFontFamilyFixed(ULViewConfig config, ULString font_name);
|
||||
|
||||
///
|
||||
/// Set default font-family to use for serif fonts (Default = Times New Roman).
|
||||
///
|
||||
ULExport void ulViewConfigSetFontFamilySerif(ULViewConfig config, ULString font_name);
|
||||
|
||||
///
|
||||
/// Set default font-family to use for sans-serif fonts (Default = Arial).
|
||||
///
|
||||
ULExport void ulViewConfigSetFontFamilySansSerif(ULViewConfig config, ULString font_name);
|
||||
|
||||
///
|
||||
/// Set user agent string (See <Ultralight/platform/Config.h> for the default).
|
||||
///
|
||||
ULExport void ulViewConfigSetUserAgent(ULViewConfig config, ULString agent_string);
|
||||
|
||||
/******************************************************************************
|
||||
* View
|
||||
*****************************************************************************/
|
||||
|
||||
///
|
||||
/// Create a View with certain size (in pixels).
|
||||
///
|
||||
/// @note You can pass null to 'session' to use the default session.
|
||||
///
|
||||
ULExport ULView ulCreateView(ULRenderer renderer, unsigned int width, unsigned int height,
|
||||
ULViewConfig view_config, ULSession session);
|
||||
|
||||
///
|
||||
/// Destroy a View.
|
||||
///
|
||||
ULExport void ulDestroyView(ULView view);
|
||||
|
||||
///
|
||||
/// Get current URL.
|
||||
///
|
||||
/// @note Don't destroy the returned string, it is owned by the View.
|
||||
///
|
||||
ULExport ULString ulViewGetURL(ULView view);
|
||||
|
||||
///
|
||||
/// Get current title.
|
||||
///
|
||||
/// @note Don't destroy the returned string, it is owned by the View.
|
||||
///
|
||||
ULExport ULString ulViewGetTitle(ULView view);
|
||||
|
||||
///
|
||||
/// Get the width, in pixels.
|
||||
///
|
||||
ULExport unsigned int ulViewGetWidth(ULView view);
|
||||
|
||||
///
|
||||
/// Get the height, in pixels.
|
||||
///
|
||||
ULExport unsigned int ulViewGetHeight(ULView view);
|
||||
|
||||
///
|
||||
// Get the display id of the View.
|
||||
///
|
||||
ULExport unsigned int ulViewGetDisplayId(ULView view);
|
||||
|
||||
///
|
||||
/// Set the display id of the View.
|
||||
///
|
||||
/// This should be called when the View is moved to another display.
|
||||
///
|
||||
ULExport void ulViewSetDisplayId(ULView view, unsigned int display_id);
|
||||
|
||||
///
|
||||
/// Get the device scale, ie. the amount to scale page units to screen pixels.
|
||||
///
|
||||
/// For example, a value of 1.0 is equivalent to 100% zoom. A value of 2.0 is 200% zoom.
|
||||
///
|
||||
ULExport double ulViewGetDeviceScale(ULView view);
|
||||
|
||||
///
|
||||
/// Set the device scale.
|
||||
///
|
||||
ULExport void ulViewSetDeviceScale(ULView view, double scale);
|
||||
|
||||
///
|
||||
/// Whether or not the View is GPU-accelerated. If this is false, the page will be rendered
|
||||
/// via the CPU renderer.
|
||||
///
|
||||
ULExport bool ulViewIsAccelerated(ULView view);
|
||||
|
||||
///
|
||||
/// Whether or not the View supports transparent backgrounds.
|
||||
///
|
||||
ULExport bool ulViewIsTransparent(ULView view);
|
||||
|
||||
///
|
||||
/// Check if the main frame of the page is currrently loading.
|
||||
///
|
||||
ULExport bool ulViewIsLoading(ULView view);
|
||||
|
||||
///
|
||||
/// Get the RenderTarget for the View.
|
||||
///
|
||||
/// @note Only valid if this View is GPU accelerated.
|
||||
///
|
||||
/// You can use this with your GPUDriver implementation to bind and display the
|
||||
/// corresponding texture in your application.
|
||||
///
|
||||
ULExport ULRenderTarget ulViewGetRenderTarget(ULView view);
|
||||
|
||||
///
|
||||
/// Get the Surface for the View (native pixel buffer that the CPU renderer draws into).
|
||||
///
|
||||
/// @note This operation is only valid if you're managing the Renderer yourself (eg, you've
|
||||
/// previously called ulCreateRenderer() instead of ulCreateApp()).
|
||||
///
|
||||
/// This function will return NULL if this View is GPU accelerated.
|
||||
///
|
||||
/// The default Surface is BitmapSurface but you can provide your own Surface implementation
|
||||
/// via ulPlatformSetSurfaceDefinition.
|
||||
///
|
||||
/// When using the default Surface, you can retrieve the underlying bitmap by casting
|
||||
/// ULSurface to ULBitmapSurface and calling ulBitmapSurfaceGetBitmap().
|
||||
///
|
||||
ULExport ULSurface ulViewGetSurface(ULView view);
|
||||
|
||||
///
|
||||
/// Load a raw string of HTML.
|
||||
///
|
||||
ULExport void ulViewLoadHTML(ULView view, ULString html_string);
|
||||
|
||||
///
|
||||
/// Load a URL into main frame.
|
||||
///
|
||||
ULExport void ulViewLoadURL(ULView view, ULString url_string);
|
||||
|
||||
///
|
||||
/// Resize view to a certain width and height (in pixels).
|
||||
///
|
||||
ULExport void ulViewResize(ULView view, unsigned int width, unsigned int height);
|
||||
|
||||
///
|
||||
/// Acquire the page's JSContext for use with JavaScriptCore API.
|
||||
///
|
||||
/// @note This call locks the context for the current thread. You should call
|
||||
/// ulViewUnlockJSContext() after using the context so other worker threads can modify
|
||||
/// JavaScript state.
|
||||
///
|
||||
/// @note The lock is recusive, it's okay to call this multiple times as long as you call
|
||||
/// ulViewUnlockJSContext() the same number of times.
|
||||
///
|
||||
ULExport JSContextRef ulViewLockJSContext(ULView view);
|
||||
|
||||
///
|
||||
/// Unlock the page's JSContext after a previous call to ulViewLockJSContext().
|
||||
///
|
||||
ULExport void ulViewUnlockJSContext(ULView view);
|
||||
|
||||
///
|
||||
/// Evaluate a string of JavaScript and return result.
|
||||
///
|
||||
/// @param js_string The string of JavaScript to evaluate.
|
||||
///
|
||||
/// @param exception The address of a ULString to store a description of the last exception. Pass
|
||||
/// NULL to ignore this. Don't destroy the exception string returned, it's owned
|
||||
/// by the View.
|
||||
///
|
||||
/// @note Don't destroy the returned string, it's owned by the View. This value is reset with every
|
||||
/// call-- if you want to retain it you should copy the result to a new string via
|
||||
/// ulCreateStringFromCopy().
|
||||
///
|
||||
/// @note An example of using this API:
|
||||
/// <pre>
|
||||
/// ULString script = ulCreateString("1 + 1");
|
||||
/// ULString exception;
|
||||
/// ULString result = ulViewEvaluateScript(view, script, &exception);
|
||||
/// /* Use the result ("2") and exception description (if any) here. */
|
||||
/// ulDestroyString(script);
|
||||
/// </pre>
|
||||
///
|
||||
ULExport ULString ulViewEvaluateScript(ULView view, ULString js_string, ULString* exception);
|
||||
|
||||
///
|
||||
/// Check if can navigate backwards in history.
|
||||
///
|
||||
ULExport bool ulViewCanGoBack(ULView view);
|
||||
|
||||
///
|
||||
/// Check if can navigate forwards in history.
|
||||
///
|
||||
ULExport bool ulViewCanGoForward(ULView view);
|
||||
|
||||
///
|
||||
/// Navigate backwards in history.
|
||||
///
|
||||
ULExport void ulViewGoBack(ULView view);
|
||||
|
||||
///
|
||||
/// Navigate forwards in history.
|
||||
///
|
||||
ULExport void ulViewGoForward(ULView view);
|
||||
|
||||
///
|
||||
/// Navigate to arbitrary offset in history.
|
||||
///
|
||||
ULExport void ulViewGoToHistoryOffset(ULView view, int offset);
|
||||
|
||||
///
|
||||
/// Reload current page.
|
||||
///
|
||||
ULExport void ulViewReload(ULView view);
|
||||
|
||||
///
|
||||
/// Stop all page loads.
|
||||
///
|
||||
ULExport void ulViewStop(ULView view);
|
||||
|
||||
///
|
||||
/// Give focus to the View.
|
||||
///
|
||||
/// You should call this to give visual indication that the View has input focus (changes active
|
||||
/// text selection colors, for example).
|
||||
///
|
||||
ULExport void ulViewFocus(ULView view);
|
||||
|
||||
///
|
||||
/// Remove focus from the View and unfocus any focused input elements.
|
||||
///
|
||||
/// You should call this to give visual indication that the View has lost input focus.
|
||||
///
|
||||
ULExport void ulViewUnfocus(ULView view);
|
||||
|
||||
///
|
||||
/// Whether or not the View has focus.
|
||||
///
|
||||
ULExport bool ulViewHasFocus(ULView view);
|
||||
|
||||
///
|
||||
/// Whether or not the View has an input element with visible keyboard focus (indicated by a
|
||||
/// blinking caret).
|
||||
///
|
||||
/// You can use this to decide whether or not the View should consume keyboard input events (useful
|
||||
/// in games with mixed UI and key handling).
|
||||
///
|
||||
ULExport bool ulViewHasInputFocus(ULView view);
|
||||
|
||||
///
|
||||
/// Fire a keyboard event.
|
||||
///
|
||||
ULExport void ulViewFireKeyEvent(ULView view, ULKeyEvent key_event);
|
||||
|
||||
///
|
||||
/// Fire a mouse event.
|
||||
///
|
||||
ULExport void ulViewFireMouseEvent(ULView view, ULMouseEvent mouse_event);
|
||||
|
||||
///
|
||||
/// Fire a scroll event.
|
||||
///
|
||||
ULExport void ulViewFireScrollEvent(ULView view, ULScrollEvent scroll_event);
|
||||
|
||||
typedef void (*ULChangeTitleCallback)(void* user_data, ULView caller, ULString title);
|
||||
|
||||
///
|
||||
/// Set callback for when the page title changes.
|
||||
///
|
||||
ULExport void ulViewSetChangeTitleCallback(ULView view, ULChangeTitleCallback callback,
|
||||
void* user_data);
|
||||
|
||||
typedef void (*ULChangeURLCallback)(void* user_data, ULView caller, ULString url);
|
||||
|
||||
///
|
||||
/// Set callback for when the page URL changes.
|
||||
///
|
||||
ULExport void ulViewSetChangeURLCallback(ULView view, ULChangeURLCallback callback,
|
||||
void* user_data);
|
||||
|
||||
typedef void (*ULChangeTooltipCallback)(void* user_data, ULView caller, ULString tooltip);
|
||||
|
||||
///
|
||||
/// Set callback for when the tooltip changes (usually result of a mouse hover).
|
||||
///
|
||||
ULExport void ulViewSetChangeTooltipCallback(ULView view, ULChangeTooltipCallback callback,
|
||||
void* user_data);
|
||||
|
||||
typedef void (*ULChangeCursorCallback)(void* user_data, ULView caller, ULCursor cursor);
|
||||
|
||||
///
|
||||
/// Set callback for when the mouse cursor changes.
|
||||
///
|
||||
ULExport void ulViewSetChangeCursorCallback(ULView view, ULChangeCursorCallback callback,
|
||||
void* user_data);
|
||||
|
||||
typedef void (*ULAddConsoleMessageCallback)(void* user_data, ULView caller, ULMessageSource source,
|
||||
ULMessageLevel level, ULString message,
|
||||
unsigned int line_number, unsigned int column_number,
|
||||
ULString source_id);
|
||||
|
||||
///
|
||||
/// Set callback for when a message is added to the console (useful for JavaScript / network errors
|
||||
/// and debugging).
|
||||
///
|
||||
ULExport void ulViewSetAddConsoleMessageCallback(ULView view, ULAddConsoleMessageCallback callback,
|
||||
void* user_data);
|
||||
|
||||
typedef ULView (*ULCreateChildViewCallback)(void* user_data, ULView caller, ULString opener_url,
|
||||
ULString target_url, bool is_popup,
|
||||
ULIntRect popup_rect);
|
||||
|
||||
///
|
||||
/// Set callback for when the page wants to create a new View.
|
||||
///
|
||||
/// This is usually the result of a user clicking a link with target="_blank" or by JavaScript
|
||||
/// calling window.open(url).
|
||||
///
|
||||
/// To allow creation of these new Views, you should create a new View in this callback, resize it
|
||||
/// to your container, and return it. You are responsible for displaying the returned View.
|
||||
///
|
||||
/// You should return NULL if you want to block the action.
|
||||
///
|
||||
ULExport void ulViewSetCreateChildViewCallback(ULView view, ULCreateChildViewCallback callback,
|
||||
void* user_data);
|
||||
|
||||
typedef ULView (*ULCreateInspectorViewCallback)(void* user_data, ULView caller, bool is_local,
|
||||
ULString inspected_url);
|
||||
|
||||
///
|
||||
/// Set callback for when the page wants to create a new View to display the local inspector in.
|
||||
///
|
||||
/// You should create a new View in this callback, resize it to your
|
||||
/// container, and return it. You are responsible for displaying the returned View.
|
||||
///
|
||||
ULExport void ulViewSetCreateInspectorViewCallback(ULView view, ULCreateInspectorViewCallback callback,
|
||||
void* user_data);
|
||||
|
||||
typedef void (*ULBeginLoadingCallback)(void* user_data, ULView caller, unsigned long long frame_id,
|
||||
bool is_main_frame, ULString url);
|
||||
|
||||
///
|
||||
/// Set callback for when the page begins loading a new URL into a frame.
|
||||
///
|
||||
ULExport void ulViewSetBeginLoadingCallback(ULView view, ULBeginLoadingCallback callback,
|
||||
void* user_data);
|
||||
|
||||
typedef void (*ULFinishLoadingCallback)(void* user_data, ULView caller, unsigned long long frame_id,
|
||||
bool is_main_frame, ULString url);
|
||||
|
||||
///
|
||||
/// Set callback for when the page finishes loading a URL into a frame.
|
||||
///
|
||||
ULExport void ulViewSetFinishLoadingCallback(ULView view, ULFinishLoadingCallback callback,
|
||||
void* user_data);
|
||||
|
||||
typedef void (*ULFailLoadingCallback)(void* user_data, ULView caller, unsigned long long frame_id,
|
||||
bool is_main_frame, ULString url, ULString description,
|
||||
ULString error_domain, int error_code);
|
||||
|
||||
///
|
||||
/// Set callback for when an error occurs while loading a URL into a frame.
|
||||
///
|
||||
ULExport void ulViewSetFailLoadingCallback(ULView view, ULFailLoadingCallback callback,
|
||||
void* user_data);
|
||||
|
||||
typedef void (*ULWindowObjectReadyCallback)(void* user_data, ULView caller,
|
||||
unsigned long long frame_id, bool is_main_frame,
|
||||
ULString url);
|
||||
|
||||
///
|
||||
/// Set callback for when the JavaScript window object is reset for a new page load.
|
||||
///
|
||||
/// This is called before any scripts are executed on the page and is the earliest time to setup any
|
||||
/// initial JavaScript state or bindings.
|
||||
///
|
||||
/// The document is not guaranteed to be loaded/parsed at this point. If you need to make any
|
||||
/// JavaScript calls that are dependent on DOM elements or scripts on the page, use DOMReady
|
||||
/// instead.
|
||||
///
|
||||
/// The window object is lazily initialized (this will not be called on pages with no scripts).
|
||||
///
|
||||
ULExport void ulViewSetWindowObjectReadyCallback(ULView view, ULWindowObjectReadyCallback callback,
|
||||
void* user_data);
|
||||
|
||||
typedef void (*ULDOMReadyCallback)(void* user_data, ULView caller, unsigned long long frame_id,
|
||||
bool is_main_frame, ULString url);
|
||||
|
||||
///
|
||||
/// Set callback for when all JavaScript has been parsed and the document is ready.
|
||||
///
|
||||
/// This is the best time to make any JavaScript calls that are dependent on DOM elements or scripts
|
||||
/// on the page.
|
||||
///
|
||||
ULExport void ulViewSetDOMReadyCallback(ULView view, ULDOMReadyCallback callback, void* user_data);
|
||||
|
||||
typedef void (*ULUpdateHistoryCallback)(void* user_data, ULView caller);
|
||||
|
||||
///
|
||||
/// Set callback for when the history (back/forward state) is modified.
|
||||
///
|
||||
ULExport void ulViewSetUpdateHistoryCallback(ULView view, ULUpdateHistoryCallback callback,
|
||||
void* user_data);
|
||||
|
||||
///
|
||||
/// Set whether or not a view should be repainted during the next call to ulRender.
|
||||
///
|
||||
/// @note This flag is automatically set whenever the page content changes but you can set it
|
||||
/// directly in case you need to force a repaint.
|
||||
///
|
||||
ULExport void ulViewSetNeedsPaint(ULView view, bool needs_paint);
|
||||
|
||||
///
|
||||
/// Whether or not a view should be painted during the next call to ulRender.
|
||||
///
|
||||
ULExport bool ulViewGetNeedsPaint(ULView view);
|
||||
|
||||
///
|
||||
/// Create an Inspector View to inspect / debug this View locally.
|
||||
///
|
||||
/// This will only succeed if you have the inspector assets in your filesystem-- the inspector
|
||||
/// will look for file:///inspector/Main.html when it first loads.
|
||||
///
|
||||
/// You must handle ulViewSetCreateInspectorViewCallback so that the library has a View to display
|
||||
/// the inspector in. This function will call the callback only if an inspector view is not
|
||||
/// currently active.
|
||||
///
|
||||
ULExport void ulViewCreateLocalInspectorView(ULView view);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_CAPI_VIEW_H
|
||||
@@ -0,0 +1,25 @@
|
||||
// Generated by CMake - DO NOT EDIT
|
||||
#pragma once
|
||||
|
||||
// Current edition level (see UltralightEdition enum below)
|
||||
#define ULTRALIGHT_EDITION_LEVEL 0
|
||||
|
||||
// Edition name string
|
||||
#define ULTRALIGHT_EDITION_NAME "Free"
|
||||
|
||||
// Edition defines
|
||||
#define ULTRALIGHT_EDITION_FREE 0
|
||||
#define ULTRALIGHT_EDITION_PLUS 1
|
||||
#define ULTRALIGHT_EDITION_PRO 2
|
||||
#define ULTRALIGHT_EDITION_ENTERPRISE 3
|
||||
#define ULTRALIGHT_EDITION_UNLIMITED 4
|
||||
|
||||
// Edition check macros
|
||||
#define UL_EDITION(x) (ULTRALIGHT_EDITION_LEVEL == ULTRALIGHT_EDITION_##x)
|
||||
#define UL_EDITION_AT_LEAST(x) (ULTRALIGHT_EDITION_LEVEL >= ULTRALIGHT_EDITION_##x)
|
||||
|
||||
// Maximum FPS each View can render at (0 is uncapped)
|
||||
#define ULTRALIGHT_EDITION_MAX_FPS 60
|
||||
|
||||
// Whether or not this is an evaluation build
|
||||
#define ULTRALIGHT_EVALUATION 0
|
||||
@@ -0,0 +1,125 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/String.h>
|
||||
#include <JavaScriptCore/JavaScript.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// MessageSource types
|
||||
///
|
||||
enum MessageSource {
|
||||
kMessageSource_XML = 0,
|
||||
kMessageSource_JS,
|
||||
kMessageSource_Network,
|
||||
kMessageSource_ConsoleAPI,
|
||||
kMessageSource_Storage,
|
||||
kMessageSource_AppCache,
|
||||
kMessageSource_Rendering,
|
||||
kMessageSource_CSS,
|
||||
kMessageSource_Security,
|
||||
kMessageSource_ContentBlocker,
|
||||
kMessageSource_Media,
|
||||
kMessageSource_MediaSource,
|
||||
kMessageSource_WebRTC,
|
||||
kMessageSource_ITPDebug,
|
||||
kMessageSource_PrivateClickMeasurement,
|
||||
kMessageSource_PaymentRequest,
|
||||
kMessageSource_Other,
|
||||
};
|
||||
|
||||
enum MessageType {
|
||||
kMessageType_Log = 0,
|
||||
kMessageType_Dir,
|
||||
kMessageType_DirXML,
|
||||
kMessageType_Table,
|
||||
kMessageType_Trace,
|
||||
kMessageType_StartGroup,
|
||||
kMessageType_StartGroupCollapsed,
|
||||
kMessageType_EndGroup,
|
||||
kMessageType_Clear,
|
||||
kMessageType_Assert,
|
||||
kMessageType_Timing,
|
||||
kMessageType_Profile,
|
||||
kMessageType_ProfileEnd,
|
||||
kMessageType_Image,
|
||||
};
|
||||
|
||||
///
|
||||
/// MessageLevel types
|
||||
///
|
||||
enum MessageLevel {
|
||||
kMessageLevel_Log = 0,
|
||||
kMessageLevel_Warning,
|
||||
kMessageLevel_Error,
|
||||
kMessageLevel_Debug,
|
||||
kMessageLevel_Info,
|
||||
};
|
||||
|
||||
///
|
||||
/// @brief Interface for console messages.
|
||||
///
|
||||
class UExport ConsoleMessage {
|
||||
public:
|
||||
virtual ~ConsoleMessage() = default;
|
||||
|
||||
///
|
||||
/// The source of the message.
|
||||
///
|
||||
virtual MessageSource source() const = 0;
|
||||
|
||||
///
|
||||
/// The type of content displayed.
|
||||
///
|
||||
virtual MessageType type() const = 0;
|
||||
|
||||
///
|
||||
/// The log level for the message.
|
||||
///
|
||||
virtual MessageLevel level() const = 0;
|
||||
|
||||
///
|
||||
/// The message as a string-- for multi-argument calls to console.log() this just converts the
|
||||
/// first parameter to a string.
|
||||
///
|
||||
virtual String message() const = 0;
|
||||
|
||||
///
|
||||
/// The line number of the JavaScript associated with this call, if any.
|
||||
///
|
||||
virtual uint32_t line_number() const = 0;
|
||||
|
||||
///
|
||||
/// The column number of the JavaScript associated with this call, if any.
|
||||
///
|
||||
virtual uint32_t column_number() const = 0;
|
||||
|
||||
///
|
||||
/// The source id (eg, URL) of the page associated with this call, if any.
|
||||
///
|
||||
virtual String source_id() const = 0;
|
||||
|
||||
///
|
||||
/// The JavaScript execution context for the arguments, if any.
|
||||
///
|
||||
virtual JSContextRef argument_context() const = 0;
|
||||
|
||||
///
|
||||
/// The number of JavaScript arguments passed to console.log(), if any.
|
||||
///
|
||||
virtual uint32_t num_arguments() const = 0;
|
||||
|
||||
///
|
||||
/// Get the JavaScript argument at a specific index (numbering starts at 0).
|
||||
///
|
||||
virtual JSValueRef argument_at(uint32_t idx) const = 0;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,139 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2025 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
// Needed for limit defines, like INTMAX_MAX, which is used by the std C++ library
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef SWIG
|
||||
#define UExport
|
||||
#else
|
||||
|
||||
#include <Ultralight/Config.h>
|
||||
#include <Ultralight/Exports.h>
|
||||
|
||||
// Require C++11 Support
|
||||
#if defined(_MSC_VER)
|
||||
# if _MSC_VER < 1800
|
||||
# error This project needs at least Visual Studio 2013 to build
|
||||
# endif
|
||||
#elif __cplusplus <= 199711L
|
||||
# error This project can only be compiled with a compiler that supports C++11
|
||||
#endif
|
||||
|
||||
#if INTPTR_MAX == INT32_MAX
|
||||
# define UL_ARCH_32_BIT
|
||||
#elif INTPTR_MAX == INT64_MAX
|
||||
# define UL_ARCH_64_BIT
|
||||
#else
|
||||
# error "Unknown CPU architecture: environment not 32 or 64-bit."
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__)
|
||||
# define UL_ARCH_ARM64
|
||||
# if defined(__APPLE__)
|
||||
# define UL_ARCH_ARM64_APPLE_SILICON
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__WIN32__) || defined(_WIN32)
|
||||
# define _thread_local __declspec(thread)
|
||||
# ifndef _NATIVE_WCHAR_T_DEFINED
|
||||
# define DISABLE_NATIVE_WCHAR_T
|
||||
# endif
|
||||
#else
|
||||
# define _thread_local __thread
|
||||
#endif
|
||||
|
||||
#ifndef UL_COMPILER_GCC_LIKE
|
||||
# if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
|
||||
# define UL_COMPILER_GCC_LIKE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef UL_ALWAYS_INLINE
|
||||
#if defined(UL_COMPILER_GCC_LIKE) && defined(NDEBUG)
|
||||
# define UL_ALWAYS_INLINE inline __attribute__((__always_inline__))
|
||||
# elif defined(_MSC_VER) && defined(NDEBUG)
|
||||
# define UL_ALWAYS_INLINE __forceinline
|
||||
# else
|
||||
# define UL_ALWAYS_INLINE inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef UL_UNLIKELY
|
||||
# if defined(UL_COMPILER_GCC_LIKE)
|
||||
# define UL_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
# else
|
||||
# define UL_UNLIKELY(x) (x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef UL_ALIGN
|
||||
#if defined(UL_COMPILER_GCC_LIKE)
|
||||
#define UL_ALIGN(x) __attribute__((aligned(x)))
|
||||
#elif defined(__cplusplus) && __cplusplus >= 201103L
|
||||
#define UL_ALIGN(x) alignas(x)
|
||||
#elif defined(_MSC_VER)
|
||||
#define UL_ALIGN(x) __declspec(align(x))
|
||||
#else
|
||||
#define UL_ALIGN(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // #ifdef SWIG
|
||||
|
||||
#define ULTRALIGHT_VERSION "1.4.0"
|
||||
#define ULTRALIGHT_VERSION_MAJOR 1
|
||||
#define ULTRALIGHT_VERSION_MINOR 4
|
||||
#define ULTRALIGHT_VERSION_PATCH 0
|
||||
|
||||
#define WEBKIT_VERSION "615.1.18.100.1"
|
||||
#define WEBKIT_VERSION_MAJOR 615
|
||||
#define WEBKIT_VERSION_MINOR 1
|
||||
#define WEBKIT_VERSION_TINY 18
|
||||
#define WEBKIT_VERSION_MICRO 100
|
||||
#define WEBKIT_VERSION_NANO 1
|
||||
|
||||
#define ULTRALIGHT_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " \
|
||||
"AppleWebKit/615.1.18.100.1 (KHTML, like Gecko) " \
|
||||
"Ultralight/1.4.0 Version/16.4.1 Safari/615.1.18.100.1"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Full library version string (corresponds to ULTRALIGHT_VERSION)
|
||||
///
|
||||
UExport const char* UltralightVersionString();
|
||||
|
||||
UExport uint32_t UltralightVersionMajor();
|
||||
UExport uint32_t UltralightVersionMinor();
|
||||
UExport uint32_t UltralightVersionPatch();
|
||||
|
||||
///
|
||||
/// Full WebKit version string (corresponds to WEBKIT_VERSION)
|
||||
///
|
||||
UExport const char* WebKitVersionString();
|
||||
|
||||
UExport uint32_t WebKitVersionMajor();
|
||||
UExport uint32_t WebKitVersionMinor();
|
||||
UExport uint32_t WebKitVersionTiny();
|
||||
UExport uint32_t WebKitVersionMicro();
|
||||
UExport uint32_t WebKitVersionNano();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#ifndef __ULTRALIGHT_EXPORTS_H__
|
||||
#define __ULTRALIGHT_EXPORTS_H__
|
||||
|
||||
#if defined(__WIN32__) || defined(_WIN32)
|
||||
# if defined(ULTRALIGHT_STATIC_BUILD)
|
||||
# define UExport
|
||||
# else
|
||||
# if defined(ULTRALIGHT_IMPLEMENTATION)
|
||||
# define UExport __declspec(dllexport)
|
||||
# else
|
||||
# define UExport __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# if defined(ULTRALIGHT_STATIC_BUILD)
|
||||
# define UExport
|
||||
# else
|
||||
# define UExport __attribute__((visibility("default")))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// UCExport is for symbols that are exported strictly by UltralightCore
|
||||
#if defined(__WIN32__) || defined(_WIN32)
|
||||
# if defined(ULTRALIGHT_STATIC_BUILD)
|
||||
# define UCExport
|
||||
# else
|
||||
# if defined(ULTRALIGHT_IMPLEMENTATION) && defined(ULTRALIGHT_MODULE_ULTRALIGHTCORE)
|
||||
# define UCExport __declspec(dllexport)
|
||||
# else
|
||||
# define UCExport __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# if defined(ULTRALIGHT_STATIC_BUILD)
|
||||
# define UCExport
|
||||
# else
|
||||
# define UCExport __attribute__((visibility("default")))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // __ULTRALIGHT_EXPORTS_H__
|
||||
@@ -0,0 +1,109 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/String.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Event representing a change in gamepad connection state.
|
||||
///
|
||||
/// @see Renderer::FireGamepadEvent
|
||||
///
|
||||
class UExport GamepadEvent {
|
||||
public:
|
||||
///
|
||||
/// The various GamepadEvent types.
|
||||
///
|
||||
enum Type {
|
||||
///
|
||||
/// This event type should be fired when a gamepad is connected.
|
||||
///
|
||||
/// @note You will need to previously declare the gamepad, its index, and details about
|
||||
/// its axis and button layout via Renderer::SetGamepadDetails prior to calling
|
||||
/// Renderer::FireGamepadEvent.
|
||||
///
|
||||
kType_GamepadConnected,
|
||||
|
||||
///
|
||||
/// This event type should be fired when a gamepad is disconnected.
|
||||
///
|
||||
kType_GamepadDisconnected,
|
||||
};
|
||||
|
||||
///
|
||||
// The type of this GamepadEvent
|
||||
///
|
||||
Type type;
|
||||
|
||||
///
|
||||
/// The index of the gamepad, this should match the value previously set in
|
||||
/// Renderer::SetGamepadDetails.
|
||||
///
|
||||
uint32_t index;
|
||||
};
|
||||
|
||||
///
|
||||
/// Event representing a change in gamepad axis state (eg, pressing a stick in a certain direction).
|
||||
///
|
||||
/// @see Renderer::FireGamepadAxisEvent
|
||||
///
|
||||
class UExport GamepadAxisEvent {
|
||||
public:
|
||||
///
|
||||
/// The index of the gamepad, this should match the value previously set in
|
||||
/// Renderer::SetGamepadDetails.
|
||||
///
|
||||
uint32_t index;
|
||||
|
||||
///
|
||||
/// The index of the axis whose value has changed.
|
||||
///
|
||||
/// This value should be in the range previously set in Renderer::SetGamepadDetails.
|
||||
///
|
||||
uint32_t axis_index;
|
||||
|
||||
///
|
||||
/// The new value of the axis.
|
||||
///
|
||||
/// This value should be normalized to the range [-1.0, 1.0].
|
||||
///
|
||||
double value;
|
||||
};
|
||||
|
||||
///
|
||||
/// Event representing a change in gamepad button state (eg, pressing a button on a gamepad).
|
||||
///
|
||||
/// @see Renderer::FireGamepadButtonEvent
|
||||
///
|
||||
class UExport GamepadButtonEvent {
|
||||
public:
|
||||
///
|
||||
/// The index of the gamepad, this should match the value previously set in
|
||||
/// Renderer::SetGamepadDetails.
|
||||
///
|
||||
uint32_t index;
|
||||
|
||||
///
|
||||
/// The index of the button whose value has changed.
|
||||
///
|
||||
/// This value should be in the range previously set in Renderer::SetGamepadDetails.
|
||||
///
|
||||
uint32_t button_index;
|
||||
|
||||
///
|
||||
/// The new value of the button.
|
||||
///
|
||||
/// This value should be normalized to the range [-1.0, 1.0], with any value greater than
|
||||
/// 0.0 to be considered "pressed".
|
||||
///
|
||||
double value;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,660 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <memory.h>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// 2D Vector Helper
|
||||
///
|
||||
struct UExport vec2 {
|
||||
float x, y;
|
||||
|
||||
inline vec2() : x(0.0f), y(0.0f) { }
|
||||
|
||||
inline vec2(float x, float y) : x(x), y(y) {}
|
||||
|
||||
inline vec2(float x) : x(x), y(x) {}
|
||||
|
||||
inline vec2 yx() const { return { y, x }; }
|
||||
|
||||
inline vec2 xx() const { return { x, x }; }
|
||||
|
||||
inline vec2 yy() const { return { y, y }; }
|
||||
|
||||
inline friend vec2 operator+(vec2 lhs, const vec2& rhs) { lhs += rhs; return lhs; }
|
||||
|
||||
inline friend vec2 operator-(vec2 lhs, const vec2& rhs) { lhs -= rhs; return lhs; }
|
||||
|
||||
inline friend vec2 operator*(vec2 lhs, const vec2& rhs) { lhs *= rhs; return lhs; }
|
||||
|
||||
inline friend vec2 operator/(vec2 lhs, const vec2& rhs) { lhs /= rhs; return lhs; }
|
||||
|
||||
inline friend vec2 operator+(vec2 lhs, float rhs) { lhs += rhs; return lhs; }
|
||||
|
||||
inline friend vec2 operator-(vec2 lhs, float rhs) { lhs -= rhs; return lhs; }
|
||||
|
||||
inline friend vec2 operator*(vec2 lhs, float rhs) { lhs *= rhs; return lhs; }
|
||||
|
||||
inline friend vec2 operator/(vec2 lhs, float rhs) { lhs /= rhs; return lhs; }
|
||||
|
||||
inline vec2& operator+=(const vec2& rhs) {
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec2& operator-=(const vec2& rhs) {
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec2& operator*=(const vec2& rhs) {
|
||||
x *= rhs.x;
|
||||
y *= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec2& operator/=(const vec2& rhs) {
|
||||
x /= rhs.x;
|
||||
y /= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec2& operator+=(float rhs) {
|
||||
x += rhs;
|
||||
y += rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec2& operator-=(float rhs) {
|
||||
x -= rhs;
|
||||
y -= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec2& operator*=(float rhs) {
|
||||
x *= rhs;
|
||||
y *= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec2& operator/=(float rhs) {
|
||||
x /= rhs;
|
||||
y /= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline friend bool operator==(const vec2& a, const vec2& b) {
|
||||
return !memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
|
||||
inline friend bool operator!=(const vec2& a, const vec2& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline friend vec2 min_(const vec2& a, const vec2& b) {
|
||||
return{ (b.x < a.x) ? b.x : a.x,
|
||||
(b.y < a.y) ? b.y : a.y };
|
||||
}
|
||||
|
||||
inline friend vec2 max_(const vec2& a, const vec2& b) {
|
||||
return{ (a.x < b.x) ? b.x : a.x,
|
||||
(a.y < b.y) ? b.y : a.y };
|
||||
}
|
||||
|
||||
inline friend vec2 clamp(const vec2& x, const vec2& minVal, const vec2& maxVal) {
|
||||
return min_(max_(x, minVal), maxVal);
|
||||
}
|
||||
|
||||
inline friend vec2 mix(const vec2& a, const vec2& b, float t) {
|
||||
return a * (1.0f - t) + b * t;
|
||||
}
|
||||
|
||||
inline friend float length(const vec2& a) {
|
||||
return sqrtf(a.x * a.x + a.y * a.y);
|
||||
}
|
||||
|
||||
// squared length
|
||||
inline friend float length2(const vec2& a) {
|
||||
return dot(a, a);
|
||||
}
|
||||
|
||||
inline friend float distance(const vec2& a, const vec2& b) {
|
||||
return length(a - b);
|
||||
}
|
||||
|
||||
// squared distance
|
||||
inline friend float distance2(const vec2& a, const vec2& b) {
|
||||
return length2(a - b);
|
||||
}
|
||||
|
||||
inline friend vec2 normalize(const vec2& a) {
|
||||
return a / length(a);
|
||||
}
|
||||
|
||||
inline friend float dot(const vec2& a, const vec2& b) {
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// 3D Vector Helper
|
||||
///
|
||||
struct UExport vec3 {
|
||||
float x, y, z;
|
||||
|
||||
inline vec3() : x(0.0f), y(0.0f), z(0.0f) { }
|
||||
|
||||
inline vec3(float x, float y, float z) : x(x), y(y), z(z) {}
|
||||
|
||||
inline vec3(float x) : x(x), y(x), z(x) {}
|
||||
|
||||
inline friend vec3 operator+(vec3 lhs, const vec3& rhs) { lhs += rhs; return lhs; }
|
||||
|
||||
inline friend vec3 operator-(vec3 lhs, const vec3& rhs) { lhs -= rhs; return lhs; }
|
||||
|
||||
inline friend vec3 operator*(vec3 lhs, const vec3& rhs) { lhs *= rhs; return lhs; }
|
||||
|
||||
inline friend vec3 operator/(vec3 lhs, const vec3& rhs) { lhs /= rhs; return lhs; }
|
||||
|
||||
inline friend vec3 operator+(vec3 lhs, float rhs) { lhs += rhs; return lhs; }
|
||||
|
||||
inline friend vec3 operator-(vec3 lhs, float rhs) { lhs -= rhs; return lhs; }
|
||||
|
||||
inline friend vec3 operator*(vec3 lhs, float rhs) { lhs *= rhs; return lhs; }
|
||||
|
||||
inline friend vec3 operator/(vec3 lhs, float rhs) { lhs /= rhs; return lhs; }
|
||||
|
||||
inline vec3& operator+=(const vec3& rhs) {
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
z += rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec3& operator-=(const vec3& rhs) {
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
z -= rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec3& operator*=(const vec3& rhs) {
|
||||
x *= rhs.x;
|
||||
y *= rhs.y;
|
||||
z *= rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec3& operator/=(const vec3& rhs) {
|
||||
x /= rhs.x;
|
||||
y /= rhs.y;
|
||||
z /= rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec3& operator+=(float rhs) {
|
||||
x += rhs;
|
||||
y += rhs;
|
||||
z += rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec3& operator-=(float rhs) {
|
||||
x -= rhs;
|
||||
y -= rhs;
|
||||
z -= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec3& operator*=(float rhs) {
|
||||
x *= rhs;
|
||||
y *= rhs;
|
||||
z *= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec3& operator/=(float rhs) {
|
||||
x /= rhs;
|
||||
y /= rhs;
|
||||
z /= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline friend bool operator==(const vec3& a, const vec3& b) {
|
||||
return !memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
|
||||
inline friend bool operator!=(const vec3& a, const vec3& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline friend vec3 min_(const vec3& a, const vec3& b) {
|
||||
return{ (b.x < a.x) ? b.x : a.x,
|
||||
(b.y < a.y) ? b.y : a.y,
|
||||
(b.z < a.z) ? b.z : a.z };
|
||||
}
|
||||
|
||||
inline friend vec3 max_(const vec3& a, const vec3& b) {
|
||||
return{ (a.x < b.x) ? b.x : a.x,
|
||||
(a.y < b.y) ? b.y : a.y,
|
||||
(a.z < b.z) ? b.z : a.z };
|
||||
}
|
||||
inline friend vec3 clamp(const vec3& x, const vec3& minVal, const vec3& maxVal) {
|
||||
return min_(max_(x, minVal), maxVal);
|
||||
}
|
||||
|
||||
inline friend vec3 mix(const vec3& a, const vec3& b, float t) {
|
||||
return a * (1.0f - t) + b * t;
|
||||
}
|
||||
|
||||
inline friend float length(const vec3& a) {
|
||||
return sqrtf(a.x * a.x + a.y * a.y + a.z * a.z);
|
||||
}
|
||||
|
||||
inline friend float distance(const vec3& a, const vec3& b) {
|
||||
return length(a - b);
|
||||
}
|
||||
|
||||
inline friend vec3 normalize(const vec3& a) {
|
||||
return a / length(a);
|
||||
}
|
||||
|
||||
inline friend float dot(const vec3& a, const vec3& b) {
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// 4D Vector Helper
|
||||
///
|
||||
struct UExport vec4 {
|
||||
float x, y, z, w;
|
||||
|
||||
inline vec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { }
|
||||
|
||||
inline vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
|
||||
|
||||
inline vec4(float x) : x(x), y(x), z(x), w(x) {}
|
||||
|
||||
inline vec4(const float val[4]) : x(val[0]), y(val[1]), z(val[2]), w(val[3]) { }
|
||||
|
||||
inline friend bool operator==(const vec4& a, const vec4& b) {
|
||||
return !memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
|
||||
inline friend bool operator!=(const vec4& a, const vec4& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline friend vec4 operator+(vec4 lhs, const vec4& rhs) { lhs += rhs; return lhs; }
|
||||
|
||||
inline friend vec4 operator-(vec4 lhs, const vec4& rhs) { lhs -= rhs; return lhs; }
|
||||
|
||||
inline friend vec4 operator*(vec4 lhs, const vec4& rhs) { lhs *= rhs; return lhs; }
|
||||
|
||||
inline friend vec4 operator/(vec4 lhs, const vec4& rhs) { lhs /= rhs; return lhs; }
|
||||
|
||||
inline friend vec4 operator+(vec4 lhs, float rhs) { lhs += rhs; return lhs; }
|
||||
|
||||
inline friend vec4 operator-(vec4 lhs, float rhs) { lhs -= rhs; return lhs; }
|
||||
|
||||
inline friend vec4 operator*(vec4 lhs, float rhs) { lhs *= rhs; return lhs; }
|
||||
|
||||
inline friend vec4 operator/(vec4 lhs, float rhs) { lhs /= rhs; return lhs; }
|
||||
|
||||
inline vec4& operator+=(const vec4& rhs) {
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
z += rhs.z;
|
||||
w += rhs.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec4& operator-=(const vec4& rhs) {
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
z -= rhs.z;
|
||||
w -= rhs.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec4& operator*=(const vec4& rhs) {
|
||||
x *= rhs.x;
|
||||
y *= rhs.y;
|
||||
z *= rhs.z;
|
||||
w *= rhs.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec4& operator/=(const vec4& rhs) {
|
||||
x /= rhs.x;
|
||||
y /= rhs.y;
|
||||
z /= rhs.z;
|
||||
w /= rhs.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec4& operator+=(float rhs) {
|
||||
x += rhs;
|
||||
y += rhs;
|
||||
z += rhs;
|
||||
w += rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec4& operator-=(float rhs) {
|
||||
x -= rhs;
|
||||
y -= rhs;
|
||||
z -= rhs;
|
||||
w -= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec4& operator*=(float rhs) {
|
||||
x *= rhs;
|
||||
y *= rhs;
|
||||
z *= rhs;
|
||||
w *= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline vec4& operator/=(float rhs) {
|
||||
x /= rhs;
|
||||
y /= rhs;
|
||||
z /= rhs;
|
||||
w /= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline friend vec4 min_(const vec4& a, const vec4& b) {
|
||||
return{ (b.x < a.x) ? b.x : a.x,
|
||||
(b.y < a.y) ? b.y : a.y,
|
||||
(b.z < a.z) ? b.z : a.z,
|
||||
(b.w < a.w) ? b.w : a.w };
|
||||
}
|
||||
|
||||
inline friend vec4 max_(const vec4& a, const vec4& b) {
|
||||
return{ (a.x < b.x) ? b.x : a.x,
|
||||
(a.y < b.y) ? b.y : a.y,
|
||||
(a.z < b.z) ? b.z : a.z,
|
||||
(a.w < b.w) ? b.w : a.w };
|
||||
}
|
||||
|
||||
inline void load(const float* val) {
|
||||
x = val[0];
|
||||
y = val[1];
|
||||
z = val[2];
|
||||
w = val[3];
|
||||
}
|
||||
|
||||
inline void store(float* val) const {
|
||||
val[0] = x;
|
||||
val[1] = y;
|
||||
val[2] = z;
|
||||
val[3] = w;
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// Point is typedef'd to a 2D vector
|
||||
///
|
||||
typedef vec2 Point;
|
||||
|
||||
///
|
||||
/// Float Rectangle Helper
|
||||
///
|
||||
struct UExport Rect {
|
||||
float left, top, right, bottom;
|
||||
|
||||
static constexpr Rect MakeEmpty() { return Rect{ 0.0f, 0.0f, 0.0f, 0.0f }; }
|
||||
|
||||
inline float width() const { return right - left; }
|
||||
inline float height() const { return bottom - top; }
|
||||
inline float x() const { return left; }
|
||||
inline float y() const { return top; }
|
||||
inline float center_x() const { return (left + right) * 0.5f; }
|
||||
inline float center_y() const { return (top + bottom) * 0.5f; }
|
||||
|
||||
inline Point origin() const { return { left, top }; }
|
||||
|
||||
inline void SetEmpty() { *this = MakeEmpty(); }
|
||||
|
||||
inline bool IsEmpty() const {
|
||||
return *this == MakeEmpty();
|
||||
}
|
||||
|
||||
inline bool IsValid() const {
|
||||
return width() > 0 && height() > 0;
|
||||
}
|
||||
|
||||
inline void Inset(float dx, float dy) {
|
||||
left += dx;
|
||||
top += dy;
|
||||
right -= dx;
|
||||
bottom -= dy;
|
||||
}
|
||||
|
||||
inline void Outset(float dx, float dy) {
|
||||
Inset(-dx, -dy);
|
||||
}
|
||||
|
||||
inline void Move(float dx, float dy) {
|
||||
left += dx;
|
||||
top += dy;
|
||||
right += dx;
|
||||
bottom += dy;
|
||||
}
|
||||
|
||||
inline float area() const {
|
||||
return width() * height();
|
||||
}
|
||||
|
||||
inline void Join(const Rect& rhs) {
|
||||
// if we are empty, just assign
|
||||
if (IsEmpty()) {
|
||||
*this = rhs;
|
||||
}
|
||||
else {
|
||||
if (rhs.left < left) left = rhs.left;
|
||||
if (rhs.top < top) top = rhs.top;
|
||||
if (rhs.right > right) right = rhs.right;
|
||||
if (rhs.bottom > bottom) bottom = rhs.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Join(const Point& p) {
|
||||
// if we are empty, just assign
|
||||
if (IsEmpty()) {
|
||||
*this = { p.x, p.y, p.x, p.y };
|
||||
}
|
||||
else {
|
||||
if (p.x < left) left = p.x;
|
||||
if (p.y < top) top = p.y;
|
||||
if (p.x > right) right = p.x;
|
||||
if (p.y > bottom) bottom = p.y;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Contains(const Point& p) const {
|
||||
return p.x >= left && p.x <= right &&
|
||||
p.y >= top && p.y <= bottom;
|
||||
}
|
||||
|
||||
inline bool Contains(const Rect& r) const {
|
||||
return left <= r.left && top <= r.top &&
|
||||
right >= r.right && bottom >= r.bottom;
|
||||
}
|
||||
|
||||
inline bool Intersects(const Rect& rhs) const {
|
||||
return !(rhs.left > right ||
|
||||
rhs.right < left ||
|
||||
rhs.top > bottom ||
|
||||
rhs.bottom < top);
|
||||
}
|
||||
|
||||
inline Rect Intersect(const Rect& other) const {
|
||||
return{ (left < other.left) ? other.left : left,
|
||||
(top < other.top) ? other.top : top,
|
||||
(other.right < right) ? other.right : right,
|
||||
(other.bottom < bottom) ? other.bottom : bottom };
|
||||
}
|
||||
|
||||
friend inline bool operator==(const Rect& a, const Rect& b) {
|
||||
return !memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
|
||||
friend inline bool operator!=(const Rect& a, const Rect& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline vec4 ToVec4() { return vec4 { left, top, right, bottom }; }
|
||||
};
|
||||
|
||||
///
|
||||
/// Integer Rectangle Helper
|
||||
///
|
||||
struct UExport IntRect {
|
||||
int left, top, right, bottom;
|
||||
|
||||
static constexpr IntRect MakeEmpty() { return IntRect{ 0, 0, 0, 0 }; }
|
||||
|
||||
inline int width() const { return right - left; }
|
||||
inline int height() const { return bottom - top; }
|
||||
inline int x() const { return left; }
|
||||
inline int y() const { return top; }
|
||||
inline int center_x() const { return (int)std::round((left + right) * 0.5f); }
|
||||
inline int center_y() const { return (int)std::round((top + bottom) * 0.5f); }
|
||||
|
||||
inline Point origin() const { return Point{ (float)left, (float)top }; }
|
||||
|
||||
inline void SetEmpty() { *this = MakeEmpty(); }
|
||||
|
||||
inline bool IsEmpty() const {
|
||||
return *this == MakeEmpty();
|
||||
}
|
||||
|
||||
inline bool IsValid() const {
|
||||
return width() > 0 && height() > 0;
|
||||
}
|
||||
|
||||
inline void Inset(int dx, int dy) {
|
||||
left += dx;
|
||||
top += dy;
|
||||
right -= dx;
|
||||
bottom -= dy;
|
||||
}
|
||||
|
||||
inline void Outset(int dx, int dy) {
|
||||
Inset(-dx, -dy);
|
||||
}
|
||||
|
||||
inline void Move(int dx, int dy) {
|
||||
left += dx;
|
||||
top += dy;
|
||||
right += dx;
|
||||
bottom += dy;
|
||||
}
|
||||
|
||||
inline int area() const {
|
||||
return width() * height();
|
||||
}
|
||||
|
||||
inline void Join(const IntRect& rhs) {
|
||||
// if we are empty, just assign
|
||||
if (IsEmpty()) {
|
||||
*this = rhs;
|
||||
}
|
||||
else {
|
||||
if (rhs.left < left) left = rhs.left;
|
||||
if (rhs.top < top) top = rhs.top;
|
||||
if (rhs.right > right) right = rhs.right;
|
||||
if (rhs.bottom > bottom) bottom = rhs.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Join(const Point& p) {
|
||||
// if we are empty, just assign
|
||||
if (IsEmpty()) {
|
||||
*this = { (int)std::floor(p.x), (int)std::floor(p.y), (int)std::ceil(p.x), (int)std::ceil(p.y) };
|
||||
}
|
||||
else {
|
||||
if ((int)std::floor(p.x) < left) left = (int)std::floor(p.x);
|
||||
if ((int)std::floor(p.y) < top) top = (int)std::floor(p.y);
|
||||
if ((int)std::ceil(p.x) > right) right = (int)std::ceil(p.x);
|
||||
if ((int)std::ceil(p.y) > bottom) bottom = (int)std::ceil(p.y);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Contains(const Point& p) const {
|
||||
return p.x >= left && p.x <= right &&
|
||||
p.y >= top && p.y <= bottom;
|
||||
}
|
||||
|
||||
inline bool Contains(const IntRect& r) const {
|
||||
return left <= r.left && top <= r.top &&
|
||||
right >= r.right && bottom >= r.bottom;
|
||||
}
|
||||
|
||||
inline bool Intersects(const IntRect& rhs) const {
|
||||
// Since this is mostly used for pixel operations, we only count
|
||||
// intersections that have width and height >= 1.
|
||||
return !(rhs.left > right - 1 ||
|
||||
rhs.right < left ||
|
||||
rhs.top > bottom - 1 ||
|
||||
rhs.bottom < top);
|
||||
}
|
||||
|
||||
inline IntRect Intersect(const IntRect& other) const {
|
||||
return{ (left < other.left) ? other.left : left,
|
||||
(top < other.top) ? other.top : top,
|
||||
(other.right < right) ? other.right : right,
|
||||
(other.bottom < bottom) ? other.bottom : bottom };
|
||||
}
|
||||
|
||||
friend inline bool operator==(const IntRect& a, const IntRect& b) {
|
||||
return !memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
|
||||
friend inline bool operator!=(const IntRect& a, const IntRect& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// Rounded Rectangle Helper
|
||||
///
|
||||
struct UExport RoundedRect {
|
||||
Rect rect;
|
||||
float radii_x[4];
|
||||
float radii_y[4];
|
||||
|
||||
void SetEmpty();
|
||||
|
||||
bool IsRounded() const;
|
||||
|
||||
// Negative is inside, positive is outside.
|
||||
float GetSignedDistance(const Point& p) const;
|
||||
|
||||
// Returns whether or not intersection is found. Can fail if the resulting
|
||||
// geometry is not a rounded rectangle.
|
||||
bool Intersect(const RoundedRect& other, RoundedRect& result) const;
|
||||
|
||||
void SnapToPixels();
|
||||
|
||||
Rect CalculateInterior() const;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,257 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/Bitmap.h>
|
||||
#include <Ultralight/Geometry.h>
|
||||
#include <Ultralight/String.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
class ImageSourceListener;
|
||||
class ImageSourceProviderListener;
|
||||
|
||||
///
|
||||
/// User-defined image source to display custom images on a web-page.
|
||||
///
|
||||
/// This API allows you to composite your own images into a web-page. This is useful for displaying
|
||||
/// in-game textures, external image assets, or other custom content.
|
||||
///
|
||||
/// ## ImageSource File Format
|
||||
///
|
||||
/// To use an ImageSource, you must first create an `.imgsrc` file containing a string identifying
|
||||
/// the image source. This string will be used to lookup the ImageSource from ImageSourceProvider
|
||||
/// when it is loaded on a web-page.
|
||||
///
|
||||
/// The file format is as follows:
|
||||
///
|
||||
/// ```
|
||||
/// IMGSRC-V1
|
||||
/// <identifier>
|
||||
/// ```
|
||||
///
|
||||
/// You can use the `.imgsrc` file anywhere in your web-page that typically accepts an image URL.
|
||||
/// For example:
|
||||
///
|
||||
/// ```html
|
||||
/// <img src="my_custom_image.imgsrc" />
|
||||
/// ```
|
||||
///
|
||||
/// ## Creating from a GPU Texture
|
||||
///
|
||||
/// To composite your own GPU texture on a web-page, you should first reserve a texture ID from
|
||||
/// GPUDriver::NextTextureId() and then create an ImageSource from that texture ID. Next, you should
|
||||
/// register the ImageSource with ImageSourceProvider using the identifier from the `.imgsrc` file.
|
||||
///
|
||||
/// When the image element is drawn on the web-page, the library will draw geometry using the
|
||||
/// specified texture ID and UV coordinates. You should bind your own texture when the specified
|
||||
/// texture ID is used.
|
||||
///
|
||||
//// @note If the GPU renderer is not enabled for the View or pixel data is needed for other
|
||||
/// purposes, the library will sample the backing bitmap instead.
|
||||
///
|
||||
/// ## Creating from a Bitmap
|
||||
///
|
||||
/// To composite your own bitmap on a web-page, you should create an ImageSource from a Bitmap.
|
||||
/// Next, you should register the ImageSource with ImageSourceProvider using the identifier from
|
||||
/// the `.imgsrc` file.
|
||||
///
|
||||
/// When the image element is drawn on the web-page, the library will sample this bitmap directly.
|
||||
///
|
||||
/// ## Invalidating Images
|
||||
///
|
||||
/// If you modify the texture or bitmap pixels after creating the ImageSource, you should call
|
||||
/// ImageSource::Invalidate() to notify the library that the image should be redrawn.
|
||||
///
|
||||
class UExport ImageSource : public RefCounted {
|
||||
public:
|
||||
///
|
||||
/// Create an ImageSource from a GPU texture with optional backing bitmap.
|
||||
///
|
||||
/// @param width The width of the image in pixels (used for layout).
|
||||
///
|
||||
/// @param height The height of the image in pixels (used for layout).
|
||||
///
|
||||
/// @param texture_id The GPU texture identifier to bind when drawing the quad for this image.
|
||||
/// This should be non-zero and obtained from GPUDriver::NextTextureId().
|
||||
///
|
||||
/// @param texture_uv The UV coordinates of the texture.
|
||||
///
|
||||
/// @param bitmap Optional backing bitmap for this image source. This is used when drawing
|
||||
/// the image using the CPU renderer or when pixel data is needed for other
|
||||
/// purposes. You should update this bitmap when the texture changes.
|
||||
///
|
||||
/// @return A new ImageSource instance.
|
||||
///
|
||||
static RefPtr<ImageSource> CreateFromTexture(uint32_t width, uint32_t height, uint32_t texture_id,
|
||||
const Rect& texture_uv,
|
||||
RefPtr<Bitmap> bitmap = nullptr);
|
||||
|
||||
///
|
||||
/// Create an ImageSource from a Bitmap.
|
||||
///
|
||||
/// @param bitmap The backing bitmap for this image source.
|
||||
///
|
||||
/// @return A new ImageSource instance.
|
||||
///
|
||||
static RefPtr<ImageSource> CreateFromBitmap(RefPtr<Bitmap> bitmap);
|
||||
|
||||
///
|
||||
/// Get the width of the image in pixels.
|
||||
///
|
||||
virtual uint32_t width() const = 0;
|
||||
|
||||
///
|
||||
/// Get the height of the image in pixels.
|
||||
///
|
||||
virtual uint32_t height() const = 0;
|
||||
|
||||
///
|
||||
/// Get the GPU texture identifier to bind when drawing the quad for this image.
|
||||
///
|
||||
/// @note This will be zero (0) if the image source was created from a bitmap.
|
||||
///
|
||||
virtual uint32_t texture_id() const = 0;
|
||||
|
||||
///
|
||||
/// Get the UV coordinates of the texture.
|
||||
///
|
||||
virtual Rect texture_uv() const = 0;
|
||||
|
||||
///
|
||||
/// Get the backing bitmap for this image source.
|
||||
///
|
||||
virtual RefPtr<Bitmap> bitmap() = 0;
|
||||
|
||||
///
|
||||
/// Invalidate the image.
|
||||
///
|
||||
/// This will notify the library that the image has changed and should be redrawn.
|
||||
///
|
||||
virtual void Invalidate() = 0;
|
||||
|
||||
///
|
||||
/// Add a listener to the image source.
|
||||
///
|
||||
/// @param listener The listener to add.
|
||||
///
|
||||
virtual void AddListener(ImageSourceListener* listener) = 0;
|
||||
|
||||
///
|
||||
/// Remove a listener from the image source.
|
||||
///
|
||||
/// @param listener The listener to remove.
|
||||
///
|
||||
virtual void RemoveListener(ImageSourceListener* listener) = 0;
|
||||
|
||||
protected:
|
||||
ImageSource() = default;
|
||||
virtual ~ImageSource() = default;
|
||||
ImageSource(const ImageSource&) = delete;
|
||||
void operator=(const ImageSource&) = delete;
|
||||
};
|
||||
|
||||
///
|
||||
/// Listener for ImageSource events.
|
||||
///
|
||||
/// This is used to notify listeners when the image source is invalidated.
|
||||
///
|
||||
class UExport ImageSourceListener {
|
||||
public:
|
||||
virtual ~ImageSourceListener() = default;
|
||||
|
||||
///
|
||||
/// Called when the image source is invalidated.
|
||||
///
|
||||
/// @param image_source The image source that was invalidated.
|
||||
///
|
||||
virtual void OnInvalidateImageSource(ImageSource* image_source) = 0;
|
||||
};
|
||||
|
||||
///
|
||||
/// Maps image sources to string identifiers.
|
||||
///
|
||||
/// This is used to lookup ImageSource instances when they are requested by a web-page.
|
||||
///
|
||||
class UExport ImageSourceProvider {
|
||||
public:
|
||||
///
|
||||
/// Get the ImageSourceProvider singleton.
|
||||
///
|
||||
static ImageSourceProvider& instance();
|
||||
|
||||
///
|
||||
/// Get an ImageSource by its identifier.
|
||||
///
|
||||
/// @param id The identifier of the image source.
|
||||
///
|
||||
/// @return The ImageSource instance or nullptr if not found.
|
||||
///
|
||||
virtual RefPtr<ImageSource> GetImageSource(const String& id) = 0;
|
||||
|
||||
///
|
||||
/// Add an ImageSource to the provider.
|
||||
///
|
||||
/// @param id The identifier of the image source.
|
||||
///
|
||||
/// @param image_source The ImageSource instance.
|
||||
///
|
||||
virtual void AddImageSource(const String& id, RefPtr<ImageSource> image_source) = 0;
|
||||
|
||||
///
|
||||
/// Remove an ImageSource from the provider.
|
||||
///
|
||||
/// @param id The identifier of the image source.
|
||||
///
|
||||
virtual void RemoveImageSource(const String& id) = 0;
|
||||
|
||||
///
|
||||
/// Add a listener to the provider.
|
||||
///
|
||||
/// @param listener The listener to add.
|
||||
///
|
||||
virtual void AddListener(ImageSourceProviderListener* listener) = 0;
|
||||
|
||||
///
|
||||
/// Remove a listener from the provider.
|
||||
///
|
||||
/// @param listener The listener to remove.
|
||||
///
|
||||
virtual void RemoveListener(ImageSourceProviderListener* listener) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~ImageSourceProvider() = default;
|
||||
};
|
||||
|
||||
///
|
||||
/// Listener for ImageSourceProvider events.
|
||||
///
|
||||
/// This is used to notify listeners when an ImageSource is added or removed from the provider.
|
||||
///
|
||||
class ImageSourceProviderListener {
|
||||
public:
|
||||
virtual ~ImageSourceProviderListener() = default;
|
||||
|
||||
///
|
||||
/// Called when an ImageSource is added to the provider.
|
||||
///
|
||||
/// @param id The identifier of the image source.
|
||||
///
|
||||
/// @param image_source The ImageSource instance.
|
||||
///
|
||||
virtual void OnAddImageSource(const String& id, RefPtr<ImageSource> image_source) = 0;
|
||||
|
||||
///
|
||||
/// Called when an ImageSource is removed from the provider.
|
||||
///
|
||||
/// @param id The identifier of the image source.
|
||||
///
|
||||
virtual void OnRemoveImageSource(const String& id) = 0;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,32 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <JavaScriptCore/JavaScript.h>
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/RefPtr.h>
|
||||
#include <Ultralight/String.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// This class wraps a JSContextRef (a JavaScript execution context for use with JavaScriptCore)
|
||||
/// and locks the context on the current thread for the duration of its lifetime.
|
||||
///
|
||||
class UExport JSContext : public RefCounted {
|
||||
public:
|
||||
/// Get the underlying JSContextRef for use with JavaScriptCore C API
|
||||
virtual JSContextRef ctx() = 0;
|
||||
|
||||
/// Typecast to a JSContextRef for use with JavaScriptCore C API
|
||||
operator JSContextRef();
|
||||
|
||||
protected:
|
||||
virtual ~JSContext();
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,532 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Namespace containing all the key-code definitions for KeyboardEvent.
|
||||
/// Most of these correspond directly to the key-code values on Windows.
|
||||
///
|
||||
namespace KeyCodes {
|
||||
|
||||
// GK_BACK (08) BACKSPACE key
|
||||
const int GK_BACK = 0x08;
|
||||
|
||||
// GK_TAB (09) TAB key
|
||||
const int GK_TAB = 0x09;
|
||||
|
||||
// GK_CLEAR (0C) CLEAR key
|
||||
const int GK_CLEAR = 0x0C;
|
||||
|
||||
// GK_RETURN (0D)
|
||||
const int GK_RETURN = 0x0D;
|
||||
|
||||
// GK_SHIFT (10) SHIFT key
|
||||
const int GK_SHIFT = 0x10;
|
||||
|
||||
// GK_CONTROL (11) CTRL key
|
||||
const int GK_CONTROL = 0x11;
|
||||
|
||||
// GK_MENU (12) ALT key
|
||||
const int GK_MENU = 0x12;
|
||||
|
||||
// GK_PAUSE (13) PAUSE key
|
||||
const int GK_PAUSE = 0x13;
|
||||
|
||||
// GK_CAPITAL (14) CAPS LOCK key
|
||||
const int GK_CAPITAL = 0x14;
|
||||
|
||||
// GK_KANA (15) Input Method Editor (IME) Kana mode
|
||||
const int GK_KANA = 0x15;
|
||||
|
||||
// GK_HANGUEL (15) IME Hanguel mode (maintained for compatibility; use GK_HANGUL)
|
||||
// GK_HANGUL (15) IME Hangul mode
|
||||
const int GK_HANGUL = 0x15;
|
||||
|
||||
// GK_IME_ON (16) IME On
|
||||
const int GK_IME_ON = 0x16;
|
||||
|
||||
// GK_JUNJA (17) IME Junja mode
|
||||
const int GK_JUNJA = 0x17;
|
||||
|
||||
// GK_FINAL (18) IME final mode
|
||||
const int GK_FINAL = 0x18;
|
||||
|
||||
// GK_HANJA (19) IME Hanja mode
|
||||
const int GK_HANJA = 0x19;
|
||||
|
||||
// GK_KANJI (19) IME Kanji mode
|
||||
const int GK_KANJI = 0x19;
|
||||
|
||||
// GK_IME_OFF (1A) IME Off
|
||||
const int GK_IME_OFF = 0x1A;
|
||||
|
||||
// GK_ESCAPE (1B) ESC key
|
||||
const int GK_ESCAPE = 0x1B;
|
||||
|
||||
// GK_CONVERT (1C) IME convert
|
||||
const int GK_CONVERT = 0x1C;
|
||||
|
||||
// GK_NONCONVERT (1D) IME nonconvert
|
||||
const int GK_NONCONVERT = 0x1D;
|
||||
|
||||
// GK_ACCEPT (1E) IME accept
|
||||
const int GK_ACCEPT = 0x1E;
|
||||
|
||||
// GK_MODECHANGE (1F) IME mode change request
|
||||
const int GK_MODECHANGE = 0x1F;
|
||||
|
||||
// GK_SPACE (20) SPACEBAR
|
||||
const int GK_SPACE = 0x20;
|
||||
|
||||
// GK_PRIOR (21) PAGE UP key
|
||||
const int GK_PRIOR = 0x21;
|
||||
|
||||
// GK_NEXT (22) PAGE DOWN key
|
||||
const int GK_NEXT = 0x22;
|
||||
|
||||
// GK_END (23) END key
|
||||
const int GK_END = 0x23;
|
||||
|
||||
// GK_HOME (24) HOME key
|
||||
const int GK_HOME = 0x24;
|
||||
|
||||
// GK_LEFT (25) LEFT ARROW key
|
||||
const int GK_LEFT = 0x25;
|
||||
|
||||
// GK_UP (26) UP ARROW key
|
||||
const int GK_UP = 0x26;
|
||||
|
||||
// GK_RIGHT (27) RIGHT ARROW key
|
||||
const int GK_RIGHT = 0x27;
|
||||
|
||||
// GK_DOWN (28) DOWN ARROW key
|
||||
const int GK_DOWN = 0x28;
|
||||
|
||||
// GK_SELECT (29) SELECT key
|
||||
const int GK_SELECT = 0x29;
|
||||
|
||||
// GK_PRINT (2A) PRINT key
|
||||
const int GK_PRINT = 0x2A;
|
||||
|
||||
// GK_EXECUTE (2B) EXECUTE key
|
||||
const int GK_EXECUTE = 0x2B;
|
||||
|
||||
// GK_SNAPSHOT (2C) PRINT SCREEN key
|
||||
const int GK_SNAPSHOT = 0x2C;
|
||||
|
||||
// GK_INSERT (2D) INS key
|
||||
const int GK_INSERT = 0x2D;
|
||||
|
||||
// GK_DELETE (2E) DEL key
|
||||
const int GK_DELETE = 0x2E;
|
||||
|
||||
// GK_HELP (2F) HELP key
|
||||
const int GK_HELP = 0x2F;
|
||||
|
||||
// (30) 0 key
|
||||
const int GK_0 = 0x30;
|
||||
|
||||
// (31) 1 key
|
||||
const int GK_1 = 0x31;
|
||||
|
||||
// (32) 2 key
|
||||
const int GK_2 = 0x32;
|
||||
|
||||
// (33) 3 key
|
||||
const int GK_3 = 0x33;
|
||||
|
||||
// (34) 4 key
|
||||
const int GK_4 = 0x34;
|
||||
|
||||
// (35) 5 key;
|
||||
const int GK_5 = 0x35;
|
||||
|
||||
// (36) 6 key
|
||||
const int GK_6 = 0x36;
|
||||
|
||||
// (37) 7 key
|
||||
const int GK_7 = 0x37;
|
||||
|
||||
// (38) 8 key
|
||||
const int GK_8 = 0x38;
|
||||
|
||||
// (39) 9 key
|
||||
const int GK_9 = 0x39;
|
||||
|
||||
// (41) A key
|
||||
const int GK_A = 0x41;
|
||||
|
||||
// (42) B key
|
||||
const int GK_B = 0x42;
|
||||
|
||||
// (43) C key
|
||||
const int GK_C = 0x43;
|
||||
|
||||
// (44) D key
|
||||
const int GK_D = 0x44;
|
||||
|
||||
// (45) E key
|
||||
const int GK_E = 0x45;
|
||||
|
||||
// (46) F key
|
||||
const int GK_F = 0x46;
|
||||
|
||||
// (47) G key
|
||||
const int GK_G = 0x47;
|
||||
|
||||
// (48) H key
|
||||
const int GK_H = 0x48;
|
||||
|
||||
// (49) I key
|
||||
const int GK_I = 0x49;
|
||||
|
||||
// (4A) J key
|
||||
const int GK_J = 0x4A;
|
||||
|
||||
// (4B) K key
|
||||
const int GK_K = 0x4B;
|
||||
|
||||
// (4C) L key
|
||||
const int GK_L = 0x4C;
|
||||
|
||||
// (4D) M key
|
||||
const int GK_M = 0x4D;
|
||||
|
||||
// (4E) N key
|
||||
const int GK_N = 0x4E;
|
||||
|
||||
// (4F) O key
|
||||
const int GK_O = 0x4F;
|
||||
|
||||
// (50) P key
|
||||
const int GK_P = 0x50;
|
||||
|
||||
// (51) Q key
|
||||
const int GK_Q = 0x51;
|
||||
|
||||
// (52) R key
|
||||
const int GK_R = 0x52;
|
||||
|
||||
// (53) S key
|
||||
const int GK_S = 0x53;
|
||||
|
||||
// (54) T key
|
||||
const int GK_T = 0x54;
|
||||
|
||||
// (55) U key
|
||||
const int GK_U = 0x55;
|
||||
|
||||
// (56) V key
|
||||
const int GK_V = 0x56;
|
||||
|
||||
// (57) W key
|
||||
const int GK_W = 0x57;
|
||||
|
||||
// (58) X key
|
||||
const int GK_X = 0x58;
|
||||
|
||||
// (59) Y key
|
||||
const int GK_Y = 0x59;
|
||||
|
||||
// (5A) Z key
|
||||
const int GK_Z = 0x5A;
|
||||
|
||||
// GK_LWIN (5B) Left Windows key (Microsoft Natural keyboard)
|
||||
const int GK_LWIN = 0x5B;
|
||||
|
||||
// GK_RWIN (5C) Right Windows key (Natural keyboard)
|
||||
const int GK_RWIN = 0x5C;
|
||||
|
||||
// GK_APPS (5D) Applications key (Natural keyboard)
|
||||
const int GK_APPS = 0x5D;
|
||||
|
||||
// GK_SLEEP (5F) Computer Sleep key
|
||||
const int GK_SLEEP = 0x5F;
|
||||
|
||||
// GK_NUMPAD0 (60) Numeric keypad 0 key
|
||||
const int GK_NUMPAD0 = 0x60;
|
||||
|
||||
// GK_NUMPAD1 (61) Numeric keypad 1 key
|
||||
const int GK_NUMPAD1 = 0x61;
|
||||
|
||||
// GK_NUMPAD2 (62) Numeric keypad 2 key
|
||||
const int GK_NUMPAD2 = 0x62;
|
||||
|
||||
// GK_NUMPAD3 (63) Numeric keypad 3 key
|
||||
const int GK_NUMPAD3 = 0x63;
|
||||
|
||||
// GK_NUMPAD4 (64) Numeric keypad 4 key
|
||||
const int GK_NUMPAD4 = 0x64;
|
||||
|
||||
// GK_NUMPAD5 (65) Numeric keypad 5 key
|
||||
const int GK_NUMPAD5 = 0x65;
|
||||
|
||||
// GK_NUMPAD6 (66) Numeric keypad 6 key
|
||||
const int GK_NUMPAD6 = 0x66;
|
||||
|
||||
// GK_NUMPAD7 (67) Numeric keypad 7 key
|
||||
const int GK_NUMPAD7 = 0x67;
|
||||
|
||||
// GK_NUMPAD8 (68) Numeric keypad 8 key
|
||||
const int GK_NUMPAD8 = 0x68;
|
||||
|
||||
// GK_NUMPAD9 (69) Numeric keypad 9 key
|
||||
const int GK_NUMPAD9 = 0x69;
|
||||
|
||||
// GK_MULTIPLY (6A) Multiply key
|
||||
const int GK_MULTIPLY = 0x6A;
|
||||
|
||||
// GK_ADD (6B) Add key
|
||||
const int GK_ADD = 0x6B;
|
||||
|
||||
// GK_SEPARATOR (6C) Separator key
|
||||
const int GK_SEPARATOR = 0x6C;
|
||||
|
||||
// GK_SUBTRACT (6D) Subtract key
|
||||
const int GK_SUBTRACT = 0x6D;
|
||||
|
||||
// GK_DECIMAL (6E) Decimal key
|
||||
const int GK_DECIMAL = 0x6E;
|
||||
|
||||
// GK_DIVIDE (6F) Divide key
|
||||
const int GK_DIVIDE = 0x6F;
|
||||
|
||||
// GK_F1 (70) F1 key
|
||||
const int GK_F1 = 0x70;
|
||||
|
||||
// GK_F2 (71) F2 key
|
||||
const int GK_F2 = 0x71;
|
||||
|
||||
// GK_F3 (72) F3 key
|
||||
const int GK_F3 = 0x72;
|
||||
|
||||
// GK_F4 (73) F4 key
|
||||
const int GK_F4 = 0x73;
|
||||
|
||||
// GK_F5 (74) F5 key
|
||||
const int GK_F5 = 0x74;
|
||||
|
||||
// GK_F6 (75) F6 key
|
||||
const int GK_F6 = 0x75;
|
||||
|
||||
// GK_F7 (76) F7 key
|
||||
const int GK_F7 = 0x76;
|
||||
|
||||
// GK_F8 (77) F8 key
|
||||
const int GK_F8 = 0x77;
|
||||
|
||||
// GK_F9 (78) F9 key
|
||||
const int GK_F9 = 0x78;
|
||||
|
||||
// GK_F10 (79) F10 key
|
||||
const int GK_F10 = 0x79;
|
||||
|
||||
// GK_F11 (7A) F11 key
|
||||
const int GK_F11 = 0x7A;
|
||||
|
||||
// GK_F12 (7B) F12 key
|
||||
const int GK_F12 = 0x7B;
|
||||
|
||||
// GK_F13 (7C) F13 key
|
||||
const int GK_F13 = 0x7C;
|
||||
|
||||
// GK_F14 (7D) F14 key
|
||||
const int GK_F14 = 0x7D;
|
||||
|
||||
// GK_F15 (7E) F15 key
|
||||
const int GK_F15 = 0x7E;
|
||||
|
||||
// GK_F16 (7F) F16 key
|
||||
const int GK_F16 = 0x7F;
|
||||
|
||||
// GK_F17 (80H) F17 key
|
||||
const int GK_F17 = 0x80;
|
||||
|
||||
// GK_F18 (81H) F18 key
|
||||
const int GK_F18 = 0x81;
|
||||
|
||||
// GK_F19 (82H) F19 key
|
||||
const int GK_F19 = 0x82;
|
||||
|
||||
// GK_F20 (83H) F20 key
|
||||
const int GK_F20 = 0x83;
|
||||
|
||||
// GK_F21 (84H) F21 key
|
||||
const int GK_F21 = 0x84;
|
||||
|
||||
// GK_F22 (85H) F22 key
|
||||
const int GK_F22 = 0x85;
|
||||
|
||||
// GK_F23 (86H) F23 key
|
||||
const int GK_F23 = 0x86;
|
||||
|
||||
// GK_F24 (87H) F24 key
|
||||
const int GK_F24 = 0x87;
|
||||
|
||||
// GK_NUMLOCK (90) NUM LOCK key
|
||||
const int GK_NUMLOCK = 0x90;
|
||||
|
||||
// GK_SCROLL (91) SCROLL LOCK key
|
||||
const int GK_SCROLL = 0x91;
|
||||
|
||||
// GK_LSHIFT (A0) Left SHIFT key
|
||||
const int GK_LSHIFT = 0xA0;
|
||||
|
||||
// GK_RSHIFT (A1) Right SHIFT key
|
||||
const int GK_RSHIFT = 0xA1;
|
||||
|
||||
// GK_LCONTROL (A2) Left CONTROL key
|
||||
const int GK_LCONTROL = 0xA2;
|
||||
|
||||
// GK_RCONTROL (A3) Right CONTROL key
|
||||
const int GK_RCONTROL = 0xA3;
|
||||
|
||||
// GK_LMENU (A4) Left MENU key
|
||||
const int GK_LMENU = 0xA4;
|
||||
|
||||
// GK_RMENU (A5) Right MENU key
|
||||
const int GK_RMENU = 0xA5;
|
||||
|
||||
// GK_BROWSER_BACK (A6) Windows 2000/XP: Browser Back key
|
||||
const int GK_BROWSER_BACK = 0xA6;
|
||||
|
||||
// GK_BROWSER_FORWARD (A7) Windows 2000/XP: Browser Forward key
|
||||
const int GK_BROWSER_FORWARD = 0xA7;
|
||||
|
||||
// GK_BROWSER_REFRESH (A8) Windows 2000/XP: Browser Refresh key
|
||||
const int GK_BROWSER_REFRESH = 0xA8;
|
||||
|
||||
// GK_BROWSER_STOP (A9) Windows 2000/XP: Browser Stop key
|
||||
const int GK_BROWSER_STOP = 0xA9;
|
||||
|
||||
// GK_BROWSER_SEARCH (AA) Windows 2000/XP: Browser Search key
|
||||
const int GK_BROWSER_SEARCH = 0xAA;
|
||||
|
||||
// GK_BROWSER_FAVORITES (AB) Windows 2000/XP: Browser Favorites key
|
||||
const int GK_BROWSER_FAVORITES = 0xAB;
|
||||
|
||||
// GK_BROWSER_HOME (AC) Windows 2000/XP: Browser Start and Home key
|
||||
const int GK_BROWSER_HOME = 0xAC;
|
||||
|
||||
// GK_VOLUME_MUTE (AD) Windows 2000/XP: Volume Mute key
|
||||
const int GK_VOLUME_MUTE = 0xAD;
|
||||
|
||||
// GK_VOLUME_DOWN (AE) Windows 2000/XP: Volume Down key
|
||||
const int GK_VOLUME_DOWN = 0xAE;
|
||||
|
||||
// GK_VOLUME_UP (AF) Windows 2000/XP: Volume Up key
|
||||
const int GK_VOLUME_UP = 0xAF;
|
||||
|
||||
// GK_MEDIA_NEXT_TRACK (B0) Windows 2000/XP: Next Track key
|
||||
const int GK_MEDIA_NEXT_TRACK = 0xB0;
|
||||
|
||||
// GK_MEDIA_PREV_TRACK (B1) Windows 2000/XP: Previous Track key
|
||||
const int GK_MEDIA_PREV_TRACK = 0xB1;
|
||||
|
||||
// GK_MEDIA_STOP (B2) Windows 2000/XP: Stop Media key
|
||||
const int GK_MEDIA_STOP = 0xB2;
|
||||
|
||||
// GK_MEDIA_PLAY_PAUSE (B3) Windows 2000/XP: Play/Pause Media key
|
||||
const int GK_MEDIA_PLAY_PAUSE = 0xB3;
|
||||
|
||||
// GK_LAUNCH_MAIL (B4) Windows 2000/XP: Start Mail key
|
||||
const int GK_MEDIA_LAUNCH_MAIL = 0xB4;
|
||||
|
||||
// GK_LAUNCH_MEDIA_SELECT (B5) Windows 2000/XP: Select Media key
|
||||
const int GK_MEDIA_LAUNCH_MEDIA_SELECT = 0xB5;
|
||||
|
||||
// GK_LAUNCH_APP1 (B6) Windows 2000/XP: Start Application 1 key
|
||||
const int GK_MEDIA_LAUNCH_APP1 = 0xB6;
|
||||
|
||||
// GK_LAUNCH_APP2 (B7) Windows 2000/XP: Start Application 2 key
|
||||
const int GK_MEDIA_LAUNCH_APP2 = 0xB7;
|
||||
|
||||
// GK_OEM_1 (BA) ';:' for US
|
||||
const int GK_OEM_1 = 0xBA;
|
||||
|
||||
// GK_OEM_PLUS (BB) '=+' any country
|
||||
const int GK_OEM_PLUS = 0xBB;
|
||||
|
||||
// GK_OEM_COMMA (BC) ',<' any country
|
||||
const int GK_OEM_COMMA = 0xBC;
|
||||
|
||||
// GK_OEM_MINUS (BD) '-_' any country
|
||||
const int GK_OEM_MINUS = 0xBD;
|
||||
|
||||
// GK_OEM_PERIOD (BE) '.>' any country
|
||||
const int GK_OEM_PERIOD = 0xBE;
|
||||
|
||||
// GK_OEM_2 (BF) '/?' for US
|
||||
const int GK_OEM_2 = 0xBF;
|
||||
|
||||
// GK_OEM_3 (C0) '`~' for US
|
||||
const int GK_OEM_3 = 0xC0;
|
||||
|
||||
// GK_OEM_4 (DB) '[{' for US
|
||||
const int GK_OEM_4 = 0xDB;
|
||||
|
||||
// GK_OEM_5 (DC) '\|' for US
|
||||
const int GK_OEM_5 = 0xDC;
|
||||
|
||||
// GK_OEM_6 (DD) ']}' for US
|
||||
const int GK_OEM_6 = 0xDD;
|
||||
|
||||
// GK_OEM_7 (DE) ''"' for US
|
||||
const int GK_OEM_7 = 0xDE;
|
||||
|
||||
// GK_OEM_8 (DF) Used for miscellaneous characters; it can vary by keyboard.
|
||||
const int GK_OEM_8 = 0xDF;
|
||||
|
||||
// GK_OEM_102 (E2) Windows 2000/XP: Either the angle bracket key or the backslash key on the RT
|
||||
// 102-key keyboard
|
||||
const int GK_OEM_102 = 0xE2;
|
||||
|
||||
// GK_PROCESSKEY (E5) Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key
|
||||
const int GK_PROCESSKEY = 0xE5;
|
||||
|
||||
// GK_PACKET (E7) Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The
|
||||
// GK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods.
|
||||
// For more information, see Remark in KEYBDINPUT,SendInput, WM_KEYDOWN, and WM_KEYUP
|
||||
const int GK_PACKET = 0xE7;
|
||||
|
||||
const int GK_OEM_ATTN = 0xF0;
|
||||
|
||||
// GK_ATTN (F6) Attn key
|
||||
const int GK_ATTN = 0xF6;
|
||||
|
||||
// GK_CRSEL (F7) CrSel key
|
||||
const int GK_CRSEL = 0xF7;
|
||||
|
||||
// GK_EXSEL (F8) ExSel key
|
||||
const int GK_EXSEL = 0xF8;
|
||||
|
||||
// GK_EREOF (F9) Erase EOF key
|
||||
const int GK_EREOF = 0xF9;
|
||||
|
||||
// GK_PLAY (FA) Play key
|
||||
const int GK_PLAY = 0xFA;
|
||||
|
||||
// GK_ZOOM (FB) Zoom key
|
||||
const int GK_ZOOM = 0xFB;
|
||||
|
||||
// GK_NONAME (FC) Reserved for future use
|
||||
const int GK_NONAME = 0xFC;
|
||||
|
||||
// GK_PA1 (FD) PA1 key
|
||||
const int GK_PA1 = 0xFD;
|
||||
|
||||
// GK_OEM_CLEAR (FE) Clear key
|
||||
const int GK_OEM_CLEAR = 0xFE;
|
||||
|
||||
const int GK_UNKNOWN = 0;
|
||||
|
||||
} // namespace KeyCodes
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,180 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/KeyCodes.h>
|
||||
#include <Ultralight/String.h>
|
||||
#ifdef __OBJC__
|
||||
#import <AppKit/NSEvent.h>
|
||||
#endif
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Keyboard event representing a change in keyboard state.
|
||||
///
|
||||
/// @see View::FireKeyEvent
|
||||
///
|
||||
class UExport KeyEvent {
|
||||
public:
|
||||
///
|
||||
/// The various KeyEvent types.
|
||||
///
|
||||
enum Type {
|
||||
///
|
||||
/// Key-Down event type. This type does **not** trigger accelerator commands in WebCore (eg,
|
||||
/// Ctrl+C for copy is an accelerator command).
|
||||
///
|
||||
/// @warning You should probably use kType_RawKeyDown instead. This type is only here for
|
||||
/// historic compatibility with WebCore's key event types.
|
||||
///
|
||||
kType_KeyDown,
|
||||
|
||||
///
|
||||
/// Key-Up event type. Use this when a physical key is released.
|
||||
///
|
||||
kType_KeyUp,
|
||||
|
||||
///
|
||||
/// Raw Key-Down type. Use this when a physical key is pressed.
|
||||
///
|
||||
kType_RawKeyDown,
|
||||
|
||||
///
|
||||
/// Character input event type. Use this when the OS generates text from a physical key being
|
||||
/// pressed (for example, this maps to WM_CHAR on Windows).
|
||||
///
|
||||
kType_Char,
|
||||
};
|
||||
|
||||
///
|
||||
/// Creates an empty KeyEvent, you will need to initialize its members
|
||||
/// yourself. This is useful for synthesizing your own keyboard events.
|
||||
///
|
||||
KeyEvent();
|
||||
|
||||
#ifdef _WIN32
|
||||
///
|
||||
/// Create a KeyEvent directly from a Windows keyboard event.
|
||||
///
|
||||
KeyEvent(Type type, uintptr_t wparam, intptr_t lparam, bool is_system_key);
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
///
|
||||
/// Create a KeyEvent directly from a macOS NSEvent.
|
||||
///
|
||||
KeyEvent(NSEvent* evt);
|
||||
#endif
|
||||
|
||||
///
|
||||
/// An enumeration of the different keyboard modifiers.
|
||||
///
|
||||
enum Modifiers : uint8_t {
|
||||
/// Whether or not an ALT key is down
|
||||
kMod_AltKey = 1 << 0,
|
||||
|
||||
/// Whether or not a Control key is down
|
||||
kMod_CtrlKey = 1 << 1,
|
||||
|
||||
/// Whether or not a meta key (Command-key on Mac, Windows-key on Win) is down
|
||||
kMod_MetaKey = 1 << 2,
|
||||
|
||||
/// Whether or not a Shift key is down
|
||||
kMod_ShiftKey = 1 << 3,
|
||||
};
|
||||
|
||||
///
|
||||
/// The type of this KeyEvent.
|
||||
///
|
||||
Type type;
|
||||
|
||||
///
|
||||
/// The current state of the keyboard. Modifiers may be OR'd together to represent multiple
|
||||
/// values.
|
||||
///
|
||||
unsigned modifiers;
|
||||
|
||||
///
|
||||
/// The virtual key-code associated with this keyboard event. This is either directly from the
|
||||
/// event (ie, WPARAM on Windows) or via a mapping function. You can see a full list of the
|
||||
/// possible virtual key-codes in KeyCodes.h
|
||||
///
|
||||
int virtual_key_code;
|
||||
|
||||
///
|
||||
/// The actual key-code generated by the platform. The DOM spec primarily uses Windows-equivalent
|
||||
/// codes (hence virtualKeyCode above) but it helps to also specify the platform-specific
|
||||
/// key-code as well.
|
||||
///
|
||||
int native_key_code;
|
||||
|
||||
///
|
||||
/// This is a string identifying the key that was pressed. This can be generated from the
|
||||
/// virtual_key_code via the GetKeyIdentifierFromVirtualKeyCode() utility function. You can find
|
||||
/// the full list of key identifiers at:
|
||||
/// <https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/keyset.html>
|
||||
///
|
||||
String key_identifier;
|
||||
|
||||
///
|
||||
/// The actual text generated by this keyboard event. This is usually only a single character.
|
||||
///
|
||||
String text;
|
||||
|
||||
///
|
||||
/// The text generated by this keyboard event before all modifiers except shift are applied. This
|
||||
/// is used internally for working out shortcut keys. This is usually only a single character.
|
||||
///
|
||||
String unmodified_text;
|
||||
|
||||
///
|
||||
/// Whether or not this is a keypad event.
|
||||
///
|
||||
bool is_keypad;
|
||||
|
||||
///
|
||||
/// Whether or not this was generated as the result of an auto-repeat (eg, holding down a key).
|
||||
///
|
||||
bool is_auto_repeat;
|
||||
|
||||
///
|
||||
/// Whether or not the pressed key is a "system key". This is a Windows-only concept and should
|
||||
/// be "false" for all non-Windows platforms. For more information, see the following link:
|
||||
/// <http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx>
|
||||
///
|
||||
bool is_system_key;
|
||||
};
|
||||
|
||||
///
|
||||
/// Utility function for generating a key identifier string from a virtual
|
||||
/// key-code.
|
||||
///
|
||||
/// @param virtual_key_code The virtual key-code to generate the key identifier from.
|
||||
///
|
||||
/// @param key_identifier_result The string to store the result in.
|
||||
///
|
||||
void UExport GetKeyIdentifierFromVirtualKeyCode(int virtual_key_code,
|
||||
String& key_identifier_result);
|
||||
|
||||
///
|
||||
/// Utility function for generating a key string from a virtual key-code.
|
||||
///
|
||||
/// @param virtual_key_code The virtual key-code to generate the key string from.
|
||||
///
|
||||
/// @param shift Whether or not the shift key is currently pressed.
|
||||
///
|
||||
/// @param key_result The string to store the result in.
|
||||
///
|
||||
/// @note This function assumes US keyboard layout.
|
||||
///
|
||||
/// @see <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values>
|
||||
///
|
||||
void UExport GetKeyFromVirtualKeyCode(int virtual_key_code, bool shift, String& key_result);
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,350 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2025 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/String.h>
|
||||
#include <Ultralight/RefPtr.h>
|
||||
#include <Ultralight/Geometry.h>
|
||||
#include <Ultralight/Buffer.h>
|
||||
#include <Ultralight/ConsoleMessage.h>
|
||||
#include <Ultralight/NetworkRequest.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
class View;
|
||||
|
||||
|
||||
///
|
||||
/// Cursor types, @see ViewListener::OnChangeCursor
|
||||
///
|
||||
enum Cursor {
|
||||
kCursor_Pointer = 0,
|
||||
kCursor_Cross,
|
||||
kCursor_Hand,
|
||||
kCursor_IBeam,
|
||||
kCursor_Wait,
|
||||
kCursor_Help,
|
||||
kCursor_EastResize,
|
||||
kCursor_NorthResize,
|
||||
kCursor_NorthEastResize,
|
||||
kCursor_NorthWestResize,
|
||||
kCursor_SouthResize,
|
||||
kCursor_SouthEastResize,
|
||||
kCursor_SouthWestResize,
|
||||
kCursor_WestResize,
|
||||
kCursor_NorthSouthResize,
|
||||
kCursor_EastWestResize,
|
||||
kCursor_NorthEastSouthWestResize,
|
||||
kCursor_NorthWestSouthEastResize,
|
||||
kCursor_ColumnResize,
|
||||
kCursor_RowResize,
|
||||
kCursor_MiddlePanning,
|
||||
kCursor_EastPanning,
|
||||
kCursor_NorthPanning,
|
||||
kCursor_NorthEastPanning,
|
||||
kCursor_NorthWestPanning,
|
||||
kCursor_SouthPanning,
|
||||
kCursor_SouthEastPanning,
|
||||
kCursor_SouthWestPanning,
|
||||
kCursor_WestPanning,
|
||||
kCursor_Move,
|
||||
kCursor_VerticalText,
|
||||
kCursor_Cell,
|
||||
kCursor_ContextMenu,
|
||||
kCursor_Alias,
|
||||
kCursor_Progress,
|
||||
kCursor_NoDrop,
|
||||
kCursor_Copy,
|
||||
kCursor_None,
|
||||
kCursor_NotAllowed,
|
||||
kCursor_ZoomIn,
|
||||
kCursor_ZoomOut,
|
||||
kCursor_Grab,
|
||||
kCursor_Grabbing,
|
||||
kCursor_Custom
|
||||
};
|
||||
|
||||
///
|
||||
/// User-defined interface to handle general events for a View.
|
||||
///
|
||||
/// @see View::set_view_listener
|
||||
///
|
||||
class UExport ViewListener {
|
||||
public:
|
||||
virtual ~ViewListener() { }
|
||||
|
||||
///
|
||||
/// Called when the page title changes
|
||||
///
|
||||
virtual void OnChangeTitle(ultralight::View* caller, const String& title) { }
|
||||
|
||||
///
|
||||
/// Called when the page URL changes
|
||||
///
|
||||
virtual void OnChangeURL(ultralight::View* caller, const String& url) { }
|
||||
|
||||
///
|
||||
/// Called when the tooltip changes (usually as result of a mouse hover)
|
||||
///
|
||||
virtual void OnChangeTooltip(ultralight::View* caller, const String& tooltip) { }
|
||||
|
||||
///
|
||||
/// Called when the mouse cursor changes
|
||||
///
|
||||
virtual void OnChangeCursor(ultralight::View* caller, Cursor cursor) { }
|
||||
|
||||
///
|
||||
/// Called when a message is added to the console (useful for errors / debug)
|
||||
///
|
||||
virtual void OnAddConsoleMessage(ultralight::View* caller,
|
||||
const ultralight::ConsoleMessage& message) { }
|
||||
|
||||
///
|
||||
/// Called when the page wants to create a new child View.
|
||||
///
|
||||
/// This is usually the result of a user clicking a link with target="_blank"
|
||||
/// or by JavaScript calling window.open(url).
|
||||
///
|
||||
/// To allow creation of these new Views, you should create a new View in this callback (eg,
|
||||
/// Renderer::CreateView()), resize it to your container, and return it. You are responsible for
|
||||
/// displaying the returned View.
|
||||
///
|
||||
/// @param caller The View that called this event.
|
||||
///
|
||||
/// @param opener_url The URL of the page that initiated this request.
|
||||
///
|
||||
/// @param target_url The URL that the new View will navigate to.
|
||||
///
|
||||
/// @param is_popup Whether or not this was triggered by window.open().
|
||||
///
|
||||
/// @param popup_rect Popups can optionally request certain dimensions and coordinates via
|
||||
/// window.open(). You can choose to respect these or not by resizing/moving
|
||||
/// the View to this rect.
|
||||
///
|
||||
/// @return Returns a RefPtr to a created View to use to satisfy the the request (or return
|
||||
/// nullptr if you want to block the action).
|
||||
///
|
||||
virtual RefPtr<View> OnCreateChildView(ultralight::View* caller, const String& opener_url,
|
||||
const String& target_url, bool is_popup,
|
||||
const IntRect& popup_rect);
|
||||
|
||||
///
|
||||
/// Called when the page wants to create a new View to display the local inspector in.
|
||||
///
|
||||
/// You should create a new View in this callback (eg, Renderer::CreateView()), resize it to your
|
||||
/// container, and return it. You are responsible for displaying the returned View.
|
||||
///
|
||||
/// @return Returns a RefPtr to a created View to use to satisfy the the request (or return
|
||||
/// nullptr if you want to block the action).
|
||||
///
|
||||
virtual RefPtr<View> OnCreateInspectorView(ultralight::View* caller, bool is_local,
|
||||
const String& inspected_url);
|
||||
|
||||
///
|
||||
/// Called when the page requests to be closed.
|
||||
///
|
||||
virtual void OnRequestClose(ultralight::View* caller) { }
|
||||
|
||||
};
|
||||
|
||||
///
|
||||
/// User-defined interface to handle load-related events for a View.
|
||||
///
|
||||
/// @see View::set_load_listener
|
||||
///
|
||||
class UExport LoadListener {
|
||||
public:
|
||||
virtual ~LoadListener() { }
|
||||
|
||||
///
|
||||
/// Called when the page begins loading a new URL into a frame.
|
||||
///
|
||||
/// @param frame_id A unique ID for the frame.
|
||||
///
|
||||
/// @param is_main_frame Whether or not this is the main frame.
|
||||
///
|
||||
/// @param url The URL for the load.
|
||||
///
|
||||
/// @note This will be called for each frame on the page. You can filter for the main frame load
|
||||
/// by checking if `is_main_frame` is `true`.
|
||||
///
|
||||
virtual void OnBeginLoading(ultralight::View* caller, uint64_t frame_id, bool is_main_frame,
|
||||
const String& url) { }
|
||||
|
||||
///
|
||||
/// Called when the page finishes loading a URL into a frame.
|
||||
///
|
||||
/// @param frame_id A unique ID for the frame.
|
||||
///
|
||||
/// @param is_main_frame Whether or not this is the main frame.
|
||||
///
|
||||
/// @param url The URL for the load.
|
||||
///
|
||||
/// @note This will be called for each frame on the page. You can filter for the main frame load
|
||||
/// by checking if `is_main_frame` is `true`.
|
||||
///
|
||||
virtual void OnFinishLoading(ultralight::View* caller, uint64_t frame_id, bool is_main_frame,
|
||||
const String& url) { }
|
||||
|
||||
///
|
||||
/// Called when an error occurs while loading a URL into a frame.
|
||||
///
|
||||
/// @param frame_id A unique ID for the frame.
|
||||
///
|
||||
/// @param is_main_frame Whether or not this is the main frame.
|
||||
///
|
||||
/// @param url The URL for the load.
|
||||
///
|
||||
/// @param description A human-readable description of the error.
|
||||
///
|
||||
/// @param error_domain The name of the module that triggered the error.
|
||||
///
|
||||
/// @param error_code Internal error code generated by the module.
|
||||
///
|
||||
/// @note This will be called for each frame on the page. You can filter for the main frame load
|
||||
/// by checking if `is_main_frame` is `true`.
|
||||
///
|
||||
virtual void OnFailLoading(ultralight::View* caller, uint64_t frame_id, bool is_main_frame,
|
||||
const String& url, const String& description,
|
||||
const String& error_domain, int error_code) { }
|
||||
|
||||
///
|
||||
/// Called when the JavaScript window object is reset for a new page load.
|
||||
///
|
||||
/// This is called before any scripts are executed on the page and is the earliest time to setup
|
||||
/// any initial JavaScript state or bindings.
|
||||
///
|
||||
/// The document is not guaranteed to be loaded/parsed at this point. If you need to make any
|
||||
/// JavaScript calls that are dependent on DOM elements or scripts on the page, use OnDOMReady
|
||||
/// instead.
|
||||
///
|
||||
/// The window object is lazily initialized (this will not be called on pages with no scripts).
|
||||
///
|
||||
/// @param frame_id A unique ID for the frame.
|
||||
///
|
||||
/// @param is_main_frame Whether or not this is the main frame.
|
||||
///
|
||||
/// @param url The URL for the load.
|
||||
///
|
||||
/// @note This will be called for each frame on the page. You can filter for the main frame load
|
||||
/// by checking if `is_main_frame` is `true`.
|
||||
///
|
||||
virtual void OnWindowObjectReady(ultralight::View* caller, uint64_t frame_id, bool is_main_frame,
|
||||
const String& url) { }
|
||||
|
||||
///
|
||||
/// Called when all JavaScript has been parsed and the document is ready.
|
||||
///
|
||||
/// This is the best time to make any JavaScript calls that are dependent on DOM elements or
|
||||
/// scripts on the page.
|
||||
///
|
||||
/// @param frame_id A unique ID for the frame.
|
||||
///
|
||||
/// @param is_main_frame Whether or not this is the main frame.
|
||||
///
|
||||
/// @param url The URL for the load.
|
||||
///
|
||||
/// @note This will be called for each frame on the page. You can filter for the main frame load
|
||||
/// by checking if `is_main_frame` is `true`.
|
||||
///
|
||||
virtual void OnDOMReady(ultralight::View* caller, uint64_t frame_id, bool is_main_frame,
|
||||
const String& url) { }
|
||||
|
||||
///
|
||||
/// Called when the session history (back/forward state) is modified.
|
||||
///
|
||||
virtual void OnUpdateHistory(ultralight::View* caller) { }
|
||||
};
|
||||
|
||||
///
|
||||
/// A unique identifier representing an active download.
|
||||
///
|
||||
typedef uint32_t DownloadId;
|
||||
|
||||
///
|
||||
/// User-defined interface to handle download-related events for a View.
|
||||
///
|
||||
/// You must implement this interface to handle downloads initiated by a View.
|
||||
///
|
||||
/// @see View::set_download_listener
|
||||
///
|
||||
class UExport DownloadListener {
|
||||
public:
|
||||
virtual ~DownloadListener() {}
|
||||
|
||||
///
|
||||
/// Called when the View wants to generate a unique download id.
|
||||
///
|
||||
/// You should generally return an integer (starting at 0) that is incremented with each call
|
||||
/// to this callback.
|
||||
///
|
||||
virtual DownloadId NextDownloadId(ultralight::View* caller) = 0;
|
||||
|
||||
///
|
||||
/// Called when the View wants to start downloading a resource from the network.
|
||||
///
|
||||
/// You should return true to allow the download, or false to block the download.
|
||||
///
|
||||
virtual bool OnRequestDownload(ultralight::View* caller, DownloadId id, const String& url) = 0;
|
||||
|
||||
///
|
||||
/// Called when the View begins downloading a resource from the network.
|
||||
///
|
||||
/// The View will not actually write any data to disk, you should open a file for writing
|
||||
/// yourself and handle the OnReceiveDataForDownload callback below.
|
||||
///
|
||||
virtual void OnBeginDownload(ultralight::View* caller, DownloadId id, const String& url,
|
||||
const String& filename, int64_t expected_content_length) = 0;
|
||||
|
||||
///
|
||||
/// Called when the View receives data for a certain download from the network.
|
||||
///
|
||||
/// This may be called multiple times for each active download as data is streamed in.
|
||||
///
|
||||
/// You should write the data to the associated file in this callback.
|
||||
///
|
||||
virtual void OnReceiveDataForDownload(ultralight::View* caller, DownloadId id,
|
||||
RefPtr<Buffer> data) = 0;
|
||||
|
||||
///
|
||||
/// Called when the View finishes downloading a resource from the network.
|
||||
///
|
||||
/// You should close the associated file in this callback.
|
||||
///
|
||||
virtual void OnFinishDownload(ultralight::View* caller, DownloadId id) = 0;
|
||||
|
||||
///
|
||||
/// Called when the View fails downloading a resource from the network.
|
||||
///
|
||||
/// You should close the associated file and delete it from disk in this callback.
|
||||
///
|
||||
virtual void OnFailDownload(ultralight::View* caller, DownloadId id) = 0;
|
||||
};
|
||||
|
||||
///
|
||||
/// User-defined interface to handle network-related events for a View.
|
||||
///
|
||||
/// @see View::set_network_listener
|
||||
///
|
||||
class UExport NetworkListener {
|
||||
public:
|
||||
virtual ~NetworkListener() { }
|
||||
|
||||
///
|
||||
/// Called when the View is about to begin a network request.
|
||||
///
|
||||
/// You can use this to block or modify network requests before they are sent.
|
||||
///
|
||||
/// Return true to allow the request, return false to block it.
|
||||
///
|
||||
/// @pre This feature is only available in Ultralight Pro edition and above.
|
||||
///
|
||||
virtual bool OnNetworkRequest(ultralight::View* caller, NetworkRequest& request) = 0;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,53 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <atomic>
|
||||
#include <mutex> // for std::lock_guard<>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Tiny, efficient spinlock that is optimized for short locking periods but will still
|
||||
/// intelligently yield the current thread and save CPU if the lock is held longer.
|
||||
///
|
||||
/// Can be used in place of std::mutex since it implements the STL's Lockable interface.
|
||||
///
|
||||
class Lock {
|
||||
public:
|
||||
constexpr Lock() = default;
|
||||
|
||||
UL_ALWAYS_INLINE void lock() noexcept {
|
||||
// Optimistically assume the lock is free on the first try
|
||||
if (!lock_.exchange(true, std::memory_order_acquire))
|
||||
return;
|
||||
|
||||
contended_lock();
|
||||
}
|
||||
|
||||
UL_ALWAYS_INLINE bool try_lock() noexcept {
|
||||
// First do a relaxed load to check if lock is free in order to prevent
|
||||
// unnecessary cache misses if someone does while(!try_lock())
|
||||
return !lock_.load(std::memory_order_relaxed)
|
||||
&& !lock_.exchange(true, std::memory_order_acquire);
|
||||
}
|
||||
|
||||
UL_ALWAYS_INLINE void unlock() noexcept { lock_.store(false, std::memory_order_release); }
|
||||
|
||||
protected:
|
||||
Lock(const Lock&) = delete;
|
||||
Lock& operator=(const Lock&) = delete;
|
||||
|
||||
void contended_lock() noexcept;
|
||||
|
||||
std::atomic<bool> lock_ = { 0 };
|
||||
};
|
||||
|
||||
using LockHolder = std::lock_guard<Lock>;
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,179 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2025 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/RefPtr.h>
|
||||
#include <Ultralight/Geometry.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// 4x4 Matrix Helper
|
||||
///
|
||||
struct UExport Matrix4x4 {
|
||||
///
|
||||
/// Raw 4x4 matrix as an array in column-major order.
|
||||
///
|
||||
float data[16];
|
||||
|
||||
///
|
||||
/// Set to identity matrix.
|
||||
///
|
||||
void SetIdentity();
|
||||
};
|
||||
|
||||
///
|
||||
/// Transformation Matrix helper
|
||||
///
|
||||
struct UExport UL_ALIGN(16) Matrix {
|
||||
typedef double Aligned4x4[4][4];
|
||||
|
||||
///
|
||||
/// Raw matrix data in column-major order (eg, `data[column][row]`)
|
||||
///
|
||||
Aligned4x4 data;
|
||||
|
||||
///
|
||||
/// Set to identity matrix.
|
||||
///
|
||||
void SetIdentity();
|
||||
|
||||
///
|
||||
/// Set to an orthographic projection matrix suitable for use with our
|
||||
/// vertex shaders. Optionally flip the y-coordinate space (eg, for OpenGL).
|
||||
///
|
||||
void SetOrthographicProjection(double screen_width, double screen_height,
|
||||
bool flip_y);
|
||||
|
||||
///
|
||||
/// Set to another matrix.
|
||||
///
|
||||
void Set(const Matrix& other);
|
||||
|
||||
///
|
||||
/// Set to another matrix.
|
||||
///
|
||||
void Set(const Matrix4x4& other);
|
||||
|
||||
///
|
||||
/// Set from raw affine members.
|
||||
///
|
||||
void Set(double a, double b, double c, double d, double e, double f);
|
||||
|
||||
///
|
||||
/// Set from raw 4x4 components.
|
||||
///
|
||||
void Set(double m11, double m12, double m13, double m14,
|
||||
double m21, double m22, double m23, double m24,
|
||||
double m31, double m32, double m33, double m34,
|
||||
double m41, double m42, double m43, double m44);
|
||||
|
||||
inline double m11() const { return data[0][0]; }
|
||||
inline double m12() const { return data[0][1]; }
|
||||
inline double m13() const { return data[0][2]; }
|
||||
inline double m14() const { return data[0][3]; }
|
||||
inline double m21() const { return data[1][0]; }
|
||||
inline double m22() const { return data[1][1]; }
|
||||
inline double m23() const { return data[1][2]; }
|
||||
inline double m24() const { return data[1][3]; }
|
||||
inline double m31() const { return data[2][0]; }
|
||||
inline double m32() const { return data[2][1]; }
|
||||
inline double m33() const { return data[2][2]; }
|
||||
inline double m34() const { return data[2][3]; }
|
||||
inline double m41() const { return data[3][0]; }
|
||||
inline double m42() const { return data[3][1]; }
|
||||
inline double m43() const { return data[3][2]; }
|
||||
inline double m44() const { return data[3][3]; }
|
||||
|
||||
inline double a() const { return data[0][0]; }
|
||||
inline double b() const { return data[0][1]; }
|
||||
inline double c() const { return data[1][0]; }
|
||||
inline double d() const { return data[1][1]; }
|
||||
inline double e() const { return data[3][0]; }
|
||||
inline double f() const { return data[3][1]; }
|
||||
|
||||
///
|
||||
/// Whether or not this is an identity matrix.
|
||||
///
|
||||
bool IsIdentity() const;
|
||||
|
||||
///
|
||||
/// Whether or not this is an identity matrix or translation.
|
||||
///
|
||||
bool IsIdentityOrTranslation() const;
|
||||
|
||||
///
|
||||
/// Whether or not this matrix uses only affine transformations.
|
||||
///
|
||||
bool IsAffine() const;
|
||||
|
||||
///
|
||||
/// Whether or not this is an identity, translation, or non-negative
|
||||
/// uniform scale.
|
||||
///
|
||||
bool IsSimple() const;
|
||||
|
||||
///
|
||||
/// Translate by x and y.
|
||||
///
|
||||
void Translate(double x, double y);
|
||||
|
||||
///
|
||||
/// Scale by x and y.
|
||||
///
|
||||
void Scale(double x, double y);
|
||||
|
||||
///
|
||||
/// Rotate matrix by theta (in degrees)
|
||||
///
|
||||
void Rotate(double theta);
|
||||
|
||||
///
|
||||
/// Rotate matrix by x and y
|
||||
///
|
||||
void Rotate(double x, double y);
|
||||
|
||||
///
|
||||
/// Transform (multiply) by another Matrix
|
||||
///
|
||||
void Transform(const Matrix& other);
|
||||
|
||||
///
|
||||
/// Get the inverse of this matrix. May return false if not invertible.
|
||||
///
|
||||
bool GetInverse(Matrix& result) const;
|
||||
|
||||
///
|
||||
/// Transform point by this matrix and get the result.
|
||||
///
|
||||
Point Apply(const Point& p) const;
|
||||
|
||||
///
|
||||
/// Transform rect by this matrix and get the result as an axis-aligned rect.
|
||||
///
|
||||
Rect Apply(const Rect& r) const;
|
||||
|
||||
///
|
||||
/// Get an integer hash of this matrix's members.
|
||||
///
|
||||
uint32_t Hash() const;
|
||||
|
||||
///
|
||||
/// Get this matrix as unaligned 4x4 float components (for use passing to
|
||||
/// GPU driver APIs).
|
||||
///
|
||||
Matrix4x4 GetMatrix4x4() const;
|
||||
};
|
||||
|
||||
bool UExport operator==(const Matrix& a, const Matrix& b);
|
||||
bool UExport operator!=(const Matrix& a, const Matrix& b);
|
||||
|
||||
bool UExport operator==(const Matrix4x4& a, const Matrix4x4& b);
|
||||
bool UExport operator!=(const Matrix4x4& a, const Matrix4x4& b);
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,71 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Mouse event representing a change in mouse state.
|
||||
///
|
||||
/// @see View::FireMouseEvent
|
||||
///
|
||||
class MouseEvent {
|
||||
public:
|
||||
///
|
||||
/// The various MouseEvent types.
|
||||
///
|
||||
enum Type {
|
||||
///
|
||||
/// Mouse moved type
|
||||
///
|
||||
kType_MouseMoved,
|
||||
|
||||
///
|
||||
/// Mouse button pressed type
|
||||
///
|
||||
kType_MouseDown,
|
||||
|
||||
///
|
||||
/// Mouse button released type
|
||||
///
|
||||
kType_MouseUp,
|
||||
};
|
||||
|
||||
///
|
||||
/// The various mouse button types.
|
||||
///
|
||||
enum Button {
|
||||
kButton_None = 0,
|
||||
kButton_Left,
|
||||
kButton_Middle,
|
||||
kButton_Right,
|
||||
};
|
||||
|
||||
///
|
||||
/// The type of this MouseEvent
|
||||
///
|
||||
Type type;
|
||||
|
||||
///
|
||||
/// The current x-position of the mouse, relative to the View
|
||||
///
|
||||
int x;
|
||||
|
||||
///
|
||||
/// The current y-position of the mouse, relative to the View
|
||||
///
|
||||
int y;
|
||||
|
||||
///
|
||||
/// The mouse button that was pressed/released, if any.
|
||||
///
|
||||
Button button;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,63 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// @brief Interface for Network requests.
|
||||
///
|
||||
class UExport NetworkRequest {
|
||||
public:
|
||||
virtual ~NetworkRequest() { }
|
||||
|
||||
///
|
||||
/// URL of the request.
|
||||
///
|
||||
virtual String url() const = 0;
|
||||
|
||||
///
|
||||
/// The host portion of the URL.
|
||||
///
|
||||
virtual String urlHost() const = 0;
|
||||
|
||||
///
|
||||
/// The protocol of the URL (eg, "http")
|
||||
///
|
||||
virtual String urlProtocol() const = 0;
|
||||
|
||||
///
|
||||
/// The HTTP method (eg, "POST" or "GET")
|
||||
///
|
||||
virtual String httpMethod() const = 0;
|
||||
|
||||
///
|
||||
/// The origin of the request.
|
||||
///
|
||||
virtual String httpOrigin() const = 0;
|
||||
|
||||
///
|
||||
/// The user-agent of the request.
|
||||
///
|
||||
virtual String httpUserAgent() const = 0;
|
||||
|
||||
///
|
||||
/// Enforce additional TLS/SSL certificate validation by verifying the
|
||||
/// server's pinned public key.
|
||||
///
|
||||
/// The public key string can be any number of base64 encoded sha256 hashes
|
||||
/// preceded by "sha256//" and separated by ";".
|
||||
///
|
||||
/// For more info see the cURL docs:
|
||||
/// <https://curl.se/libcurl/c/CURLOPT_PINNEDPUBLICKEY.html>
|
||||
///
|
||||
virtual void EnforcePinnedPublicKey(const String& public_key) = 0;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,325 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
/*
|
||||
* Portions of the below code are derived from 'RefPtr.h' from Apple's WTF,
|
||||
* with the following license header:
|
||||
*
|
||||
* Copyright (C) 2013-2014 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <assert.h>
|
||||
#include <utility>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// @brief Interface for all ref-counted objects that will be managed using
|
||||
/// the RefPtr<> smart pointer.
|
||||
///
|
||||
class UExport RefCounted {
|
||||
public:
|
||||
virtual void AddRef() const = 0;
|
||||
virtual void Release() const = 0;
|
||||
virtual int ref_count() const = 0;
|
||||
protected:
|
||||
virtual ~RefCounted();
|
||||
};
|
||||
|
||||
template<typename T> class RefPtr;
|
||||
|
||||
///
|
||||
/// @brief Helper for wrapping new objects with the RefPtr smart pointer.
|
||||
///
|
||||
/// All ref-counted object are created with an initial ref-count of '1'.
|
||||
/// The AdoptRef() helper returns a RefPtr<T> without calling AddRef().
|
||||
/// This is used for creating new objects, like so:
|
||||
///
|
||||
/// RefPtr<Object> ref = AdoptRef(*new ObjectImpl());
|
||||
///
|
||||
template<typename T>
|
||||
RefPtr<T> AdoptRef(T& reference)
|
||||
{
|
||||
return RefPtr<T>(reference, RefPtr<T>::Adopt);
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief A nullable smart pointer.
|
||||
///
|
||||
/// This smart pointer automatically manages the lifetime of a RefCounted
|
||||
/// object. The managed instance may be NULL.
|
||||
///
|
||||
template<typename T> class RefPtr {
|
||||
public:
|
||||
///
|
||||
/// Construct a NULL ref-pointer.
|
||||
///
|
||||
constexpr RefPtr()
|
||||
: instance_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Construct a NULL ref-pointer.
|
||||
///
|
||||
inline RefPtr(std::nullptr_t)
|
||||
: instance_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Construct from a pointer. (Will increment ref-count by one)
|
||||
///
|
||||
inline RefPtr(T* other)
|
||||
: instance_(other)
|
||||
{
|
||||
if (instance_)
|
||||
instance_->AddRef();
|
||||
}
|
||||
|
||||
///
|
||||
/// Copy constructor.
|
||||
///
|
||||
inline RefPtr(const RefPtr& other)
|
||||
: instance_(other.instance_)
|
||||
{
|
||||
if (instance_)
|
||||
instance_->AddRef();
|
||||
}
|
||||
|
||||
///
|
||||
/// Copy constructor with internal type conversion.
|
||||
///
|
||||
template<typename U>
|
||||
RefPtr(const RefPtr<U>& other)
|
||||
: instance_(other.instance_)
|
||||
{
|
||||
if (instance_)
|
||||
instance_->AddRef();
|
||||
}
|
||||
|
||||
///
|
||||
/// Move constructor.
|
||||
///
|
||||
inline RefPtr(RefPtr&& other)
|
||||
: instance_(other.LeakRef())
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Move constructor.
|
||||
///
|
||||
template<typename U>
|
||||
RefPtr(RefPtr<U>&& other)
|
||||
: instance_(other.LeakRef())
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Destroy RefPtr (wll decrement ref-count by one)
|
||||
///
|
||||
inline ~RefPtr()
|
||||
{
|
||||
T* old_value = std::move(instance_);
|
||||
instance_ = std::forward<T*>(nullptr);
|
||||
if (old_value)
|
||||
old_value->Release();
|
||||
}
|
||||
|
||||
///
|
||||
/// Get a pointer to wrapped object.
|
||||
///
|
||||
inline T* get() const { return instance_; }
|
||||
|
||||
T* LeakRef() {
|
||||
T* result = std::move(instance_);
|
||||
instance_ = std::forward<T*>(nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
T& operator*() const { assert(instance_); return *instance_; }
|
||||
inline T* operator->() const { return instance_; }
|
||||
|
||||
bool operator!() const { return !instance_; }
|
||||
|
||||
// This conversion operator allows implicit conversion to bool but not to other integer types.
|
||||
typedef T* (RefPtr::*UnspecifiedBoolType);
|
||||
operator UnspecifiedBoolType() const { return instance_ ? &RefPtr::instance_ : nullptr; }
|
||||
|
||||
RefPtr& operator=(const RefPtr&);
|
||||
RefPtr& operator=(T*);
|
||||
RefPtr& operator=(std::nullptr_t);
|
||||
template<typename U> RefPtr& operator=(const RefPtr<U>&);
|
||||
RefPtr& operator=(RefPtr&&);
|
||||
template<typename U> RefPtr& operator=(RefPtr<U>&&);
|
||||
|
||||
friend inline bool operator==(const RefPtr& a, const RefPtr& b) {
|
||||
return a.instance_ == b.instance_;
|
||||
}
|
||||
|
||||
friend inline bool operator!=(const RefPtr& a, const RefPtr& b) {
|
||||
return a.instance_ != b.instance_;
|
||||
}
|
||||
|
||||
friend inline bool operator<(const RefPtr& a, const RefPtr& b) {
|
||||
return a.instance_ < b.instance_;
|
||||
}
|
||||
|
||||
///
|
||||
/// Releases the ownership of the managed object, if any
|
||||
///
|
||||
void reset();
|
||||
|
||||
///
|
||||
/// Replaces the managed object with another.
|
||||
///
|
||||
void reset(T* obj);
|
||||
|
||||
///
|
||||
/// Exchanges the stored pointer values and the ownerships of *this and ptr.
|
||||
/// Reference counts, if any, are not adjusted.
|
||||
///
|
||||
void swap(RefPtr& ptr);
|
||||
|
||||
protected:
|
||||
friend RefPtr AdoptRef<T>(T&);
|
||||
|
||||
enum AdoptTag { Adopt };
|
||||
RefPtr(T& object, AdoptTag) : instance_(&object) { }
|
||||
|
||||
private:
|
||||
T* instance_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
RefPtr<T>& RefPtr<T>::operator=(const RefPtr& other)
|
||||
{
|
||||
RefPtr ptr = other;
|
||||
swap(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& other)
|
||||
{
|
||||
RefPtr ptr = other;
|
||||
swap(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
RefPtr<T>& RefPtr<T>::operator=(T* object)
|
||||
{
|
||||
RefPtr ptr = object;
|
||||
swap(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
RefPtr<T>& RefPtr<T>::operator=(std::nullptr_t)
|
||||
{
|
||||
T* old_instance = std::move(instance_);
|
||||
instance_ = std::forward<T*>(nullptr);
|
||||
if (old_instance)
|
||||
old_instance->Release();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
RefPtr<T>& RefPtr<T>::operator=(RefPtr&& other)
|
||||
{
|
||||
RefPtr ptr = std::move(other);
|
||||
swap(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
RefPtr<T>& RefPtr<T>::operator=(RefPtr<U>&& other)
|
||||
{
|
||||
RefPtr ptr = std::move(other);
|
||||
swap(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T> void RefPtr<T>::reset() { *this = nullptr; }
|
||||
|
||||
template <typename T> void RefPtr<T>::reset(T* obj) { *this = obj; }
|
||||
|
||||
template<typename T>
|
||||
void RefPtr<T>::swap(RefPtr& other)
|
||||
{
|
||||
std::swap(instance_, other.instance_);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void swap(RefPtr<T>& a, RefPtr<T>& b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator==(const RefPtr<T>& a, const RefPtr<U>& b)
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator==(const RefPtr<T>& a, const U* b)
|
||||
{
|
||||
return a.get() == b;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator==(const T* a, const RefPtr<U>& b)
|
||||
{
|
||||
return a == b.get();
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b)
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator!=(const RefPtr<T>& a, const U* b)
|
||||
{
|
||||
return a.get() != b;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator!=(const T* a, const RefPtr<U>& b)
|
||||
{
|
||||
return a != b.get();
|
||||
}
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,86 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/Bitmap.h>
|
||||
#include <Ultralight/Geometry.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
///
|
||||
/// Offscreen render target, used when rendering Views via the GPU renderer.
|
||||
///
|
||||
/// When a View is rendered via the GPU renderer (see View::is_accelerated), it will be rendered to
|
||||
/// an offscreen render target (View::render_target) that you can display in your application.
|
||||
///
|
||||
/// This is intended to be used with a custom GPUDriver implementation in a game or similar
|
||||
/// application.
|
||||
///
|
||||
/// ## Displaying the Render Target
|
||||
///
|
||||
/// To display the View's render target, you should:
|
||||
///
|
||||
/// 1. Retrieve the underlying texture via RenderTarget::texture_id().
|
||||
/// 2. Bind the texture using your custom GPUDriver implementation.
|
||||
/// 3. Draw a textured quad with the provided UV coordinates (RenderTarget::uv_coords()).
|
||||
///
|
||||
struct UExport RenderTarget {
|
||||
///
|
||||
/// Whether this target is empty (null texture)
|
||||
///
|
||||
bool is_empty;
|
||||
|
||||
///
|
||||
/// The viewport width (in device coordinates).
|
||||
///
|
||||
uint32_t width;
|
||||
|
||||
///
|
||||
/// The viewport height (in device coordinates).
|
||||
///
|
||||
uint32_t height;
|
||||
|
||||
///
|
||||
/// The GPUDriver-specific texture ID (you should bind the texture using your custom GPUDriver
|
||||
/// implementation before drawing a quad).
|
||||
///
|
||||
uint32_t texture_id;
|
||||
|
||||
///
|
||||
/// The texture width (in pixels). This may be padded.
|
||||
///
|
||||
uint32_t texture_width;
|
||||
|
||||
///
|
||||
/// The texture height (in pixels). This may be padded.
|
||||
///
|
||||
uint32_t texture_height;
|
||||
|
||||
///
|
||||
/// The pixel format of the texture.
|
||||
///
|
||||
BitmapFormat texture_format;
|
||||
|
||||
///
|
||||
/// UV coordinates of the texture (this is needed because the texture may be padded).
|
||||
///
|
||||
Rect uv_coords;
|
||||
|
||||
///
|
||||
/// The GPUDriver-specific render buffer ID.
|
||||
///
|
||||
uint32_t render_buffer_id;
|
||||
|
||||
RenderTarget();
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,307 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/RefPtr.h>
|
||||
#include <Ultralight/Session.h>
|
||||
#include <Ultralight/View.h>
|
||||
#include <Ultralight/GamepadEvent.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Core renderer singleton for the library, coordinates all library functions.
|
||||
///
|
||||
/// The Renderer class is responsible for creating and painting View%s, managing Session%s, as well
|
||||
/// as coordinating network requests, events, JavaScript execution, and more.
|
||||
///
|
||||
/// ## Creating the Renderer
|
||||
///
|
||||
/// @note A Renderer will be created for you automatically when you call App::Create() (access it
|
||||
/// via App::renderer).
|
||||
///
|
||||
/// @note App::Create() is part of the AppCore API and automatically manages window creation, run
|
||||
/// loop, input, painting, and most platform-specific functionality. (Available on desktop
|
||||
/// platforms only)
|
||||
/// \endparblock
|
||||
///
|
||||
/// ### Defining Platform Handlers
|
||||
///
|
||||
/// Before creating the Renderer, you should define your platform handlers via the Platform
|
||||
/// singleton. This can be used to customize file loading, font loading, clipboard access, and other
|
||||
/// functionality typically provided by the OS.
|
||||
///
|
||||
/// Default implementations for most platform handlers are available in the
|
||||
/// [AppCore repo](https://github.com/ultralight-ux/AppCore/tree/master/src). You can use these
|
||||
/// stock implementations by copying the code into your project, or you can write your own.
|
||||
///
|
||||
/// At a minimum, you should provide a FileSystem and FontLoader otherwise Renderer creation will
|
||||
/// fail.
|
||||
///
|
||||
/// ### Setting Up the Config
|
||||
///
|
||||
/// You can configure various library options by creating a Config object and passing it to
|
||||
/// `Platform::instance().set_config()`.
|
||||
///
|
||||
/// ### Creating the Renderer
|
||||
///
|
||||
/// Once you've set up the Platform handlers and Config, you can create the Renderer by calling
|
||||
/// `Renderer::Create()`. You should store the result in a RefPtr to keep it alive.
|
||||
///
|
||||
/// @par Example creation code
|
||||
/// ```
|
||||
/// // Get the Platform singleton (maintains global library state)
|
||||
/// auto& platform = Platform::instance();
|
||||
///
|
||||
/// // Setup config
|
||||
/// Config my_config;
|
||||
/// platform.set_config(my_config);
|
||||
///
|
||||
/// // Create platform handlers (these are the minimum required)
|
||||
/// // (This is pseudo-code, you will need to define your own)
|
||||
/// MyFileSystem* file_system = new MyFileSystem();
|
||||
/// MyFontLoader* font_loader = new MyFontLoader();
|
||||
///
|
||||
/// // Setup platform handlers
|
||||
/// platform.set_file_system(file_system);
|
||||
/// platform.set_font_loader(font_loader);
|
||||
///
|
||||
/// // Create the Renderer
|
||||
/// RefPtr<Renderer> renderer = Renderer::Create();
|
||||
///
|
||||
/// // Create Views here
|
||||
/// ```
|
||||
///
|
||||
/// ## Updating Renderer Logic
|
||||
///
|
||||
/// You should call Renderer::Update() from your main update loop as often as possible to give the
|
||||
/// library an opportunity to dispatch events and timers:
|
||||
///
|
||||
/// @par Example update code
|
||||
/// ```
|
||||
/// void mainLoop()
|
||||
/// {
|
||||
/// while(true)
|
||||
/// {
|
||||
/// // Update program logic here
|
||||
/// renderer.Update();
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ## Rendering Each Frame
|
||||
///
|
||||
/// When your program is ready to display a new frame (usually in synchrony with the monitor
|
||||
/// refresh rate), you should call `Renderer::RefreshDisplay()` and `Renderer::Render()` so the
|
||||
/// library can render all active View%s as needed.
|
||||
///
|
||||
/// @par Example per-frame render code
|
||||
/// ```
|
||||
/// void displayFrame()
|
||||
/// {
|
||||
/// // Notify the renderer that the main display has refreshed. This will update animations,
|
||||
/// // smooth scroll, and window.requestAnimationFrame() for all Views matching the display id.
|
||||
/// renderer.RefreshDisplay(0);
|
||||
///
|
||||
/// // Render all Views as needed
|
||||
/// renderer.Render();
|
||||
///
|
||||
/// // Each View will render to a
|
||||
/// // - Pixel-Buffer Surface (View::surface())
|
||||
/// // or
|
||||
/// // - GPU texture (View::render_target())
|
||||
/// // based on whether CPU or GPU rendering is used.
|
||||
/// //
|
||||
/// // You will need to display the image data here as needed.
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
class UExport Renderer : public RefCounted {
|
||||
public:
|
||||
///
|
||||
/// Create the core renderer singleton for the library.
|
||||
///
|
||||
/// You should set up the Platform singleton before calling this function.
|
||||
///
|
||||
/// @note You do not need to the call this if you're using the App class from AppCore.
|
||||
///
|
||||
/// \parblock
|
||||
/// @warning You'll need to define a FontLoader and FileSystem within the Platform singleton
|
||||
/// or else this call will fail.
|
||||
/// \endparblock
|
||||
///
|
||||
/// \parblock
|
||||
/// @warning You should only create one Renderer during the lifetime of your program.
|
||||
/// \endparblock
|
||||
///
|
||||
/// @return Renderer is ref-counted. This method returns a ref-pointer to a new instance, you
|
||||
/// should store it in a RefPtr to keep the instance alive.
|
||||
///
|
||||
static RefPtr<Renderer> Create();
|
||||
|
||||
///
|
||||
/// Create a unique, named Session to store browsing data in (cookies, local storage,
|
||||
/// application cache, indexed db, etc).
|
||||
///
|
||||
/// @note A default, persistent Session is already created for you. You only need to call this
|
||||
/// if you want to create private, in-memory session or use a separate session for each
|
||||
/// View.
|
||||
///
|
||||
/// @param is_persistent Whether or not to store the session on disk. Persistent sessions will
|
||||
/// be written to the path set in Config::cache_path
|
||||
///
|
||||
/// @param name A unique name for this session, this will be used to generate a unique disk
|
||||
/// path for persistent sessions.
|
||||
///
|
||||
virtual RefPtr<Session> CreateSession(bool is_persistent, const String& name) = 0;
|
||||
|
||||
///
|
||||
/// Get the default Session. This session is persistent (backed to disk) and has the name
|
||||
/// "default".
|
||||
///
|
||||
virtual RefPtr<Session> default_session() = 0;
|
||||
|
||||
///
|
||||
/// Create a new View to load and display web pages in.
|
||||
///
|
||||
/// Views are similar to a tab in a browser. They have certain dimensions but are rendered to an
|
||||
/// offscreen surface and must be forwarded all input events.
|
||||
///
|
||||
/// @param width The initial width, in pixels.
|
||||
///
|
||||
/// @param height The initial height, in pixels.
|
||||
///
|
||||
/// @param config Configuration details for the View.
|
||||
///
|
||||
/// @param session The session to store local data in. Pass a nullptr to use the default
|
||||
/// session.
|
||||
///
|
||||
/// @return Returns a ref-pointer to a new View instance.
|
||||
///
|
||||
virtual RefPtr<View> CreateView(uint32_t width, uint32_t height, const ViewConfig& config,
|
||||
RefPtr<Session> session)
|
||||
= 0;
|
||||
|
||||
///
|
||||
/// Update timers and dispatch callbacks.
|
||||
///
|
||||
/// You should call this as often as you can from your application's run loop.
|
||||
///
|
||||
virtual void Update() = 0;
|
||||
|
||||
///
|
||||
/// Notify the renderer that a display has refreshed (you should call this after vsync).
|
||||
///
|
||||
/// This updates animations, smooth scroll, and window.requestAnimationFrame() for all Views
|
||||
/// matching the display id.
|
||||
///
|
||||
virtual void RefreshDisplay(uint32_t display_id) = 0;
|
||||
|
||||
///
|
||||
/// Render all active views to their respective render-targets/surfaces.
|
||||
///
|
||||
/// @note Views are only repainted if they actually need painting.
|
||||
///
|
||||
virtual void Render() = 0;
|
||||
|
||||
///
|
||||
/// Render a subset of views to their respective surfaces and render targets.
|
||||
///
|
||||
/// @param view_array A C-array containing a list of View pointers.
|
||||
///
|
||||
/// @param view_array_len The length of the C-array.
|
||||
///
|
||||
virtual void RenderOnly(View** view_array, size_t view_array_len) = 0;
|
||||
|
||||
///
|
||||
/// Attempt to release as much memory as possible.
|
||||
///
|
||||
/// @warning Don't call this from any callbacks or driver code.
|
||||
///
|
||||
virtual void PurgeMemory() = 0;
|
||||
|
||||
///
|
||||
/// Print detailed memory usage statistics to the log.
|
||||
///
|
||||
/// @see Platform::set_logger
|
||||
///
|
||||
virtual void LogMemoryUsage() = 0;
|
||||
|
||||
///
|
||||
/// Start the remote inspector server.
|
||||
///
|
||||
/// @pre This feature is only available in Ultralight Pro edition and above.
|
||||
///
|
||||
/// While the remote inspector is active, Views that are loaded into this renderer
|
||||
/// will be able to be remotely inspected from another Ultralight instance either locally
|
||||
/// (another app on same machine) or remotely (over the network) by navigating a View to:
|
||||
///
|
||||
/// \code
|
||||
/// inspector://<ADDRESS>:<PORT>
|
||||
/// \endcode
|
||||
///
|
||||
/// @param address The address for the server to listen on (eg, "127.0.0.1")
|
||||
///
|
||||
/// @param port The port for the server to listen on (eg, 9222)
|
||||
///
|
||||
/// @return Returns whether the server started successfully or not.
|
||||
///
|
||||
virtual bool StartRemoteInspectorServer(const char* address, uint16_t port) = 0;
|
||||
|
||||
///
|
||||
/// Describe the details of a gamepad, to be used with FireGamepadEvent and related
|
||||
/// events below. This can be called multiple times with the same index if the details change.
|
||||
///
|
||||
/// @param index The unique index (or "connection slot") of the gamepad. For example,
|
||||
/// controller #1 would be "1", controller #2 would be "2" and so on.
|
||||
///
|
||||
/// @param id A string ID representing the device, this will be made available
|
||||
/// in JavaScript as gamepad.id
|
||||
///
|
||||
/// @param axis_count The number of axes on the device.
|
||||
///
|
||||
/// @param button_count The number of buttons on the device.
|
||||
///
|
||||
virtual void SetGamepadDetails(uint32_t index, const String& id, uint32_t axis_count,
|
||||
uint32_t button_count)
|
||||
= 0;
|
||||
|
||||
///
|
||||
/// Fire a gamepad event (connection / disconnection).
|
||||
///
|
||||
/// @note The gamepad should first be described via SetGamepadDetails before calling this
|
||||
/// function.
|
||||
///
|
||||
/// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad>
|
||||
///
|
||||
virtual void FireGamepadEvent(const GamepadEvent& evt) = 0;
|
||||
|
||||
///
|
||||
/// Fire a gamepad axis event (to be called when an axis value is changed).
|
||||
///
|
||||
/// @note The gamepad should be connected via a previous call to FireGamepadEvent.
|
||||
///
|
||||
/// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad/axes>
|
||||
///
|
||||
virtual void FireGamepadAxisEvent(const GamepadAxisEvent& evt) = 0;
|
||||
|
||||
///
|
||||
/// Fire a gamepad button event (to be called when a button value is changed).
|
||||
///
|
||||
/// @note The gamepad should be connected via a previous call to FireGamepadEvent.
|
||||
///
|
||||
/// @see <https://developer.mozilla.org/en-US/docs/Web/API/Gamepad/buttons>
|
||||
///
|
||||
virtual void FireGamepadButtonEvent(const GamepadButtonEvent& evt) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Renderer();
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,44 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Scroll event representing a change in scroll state.
|
||||
///
|
||||
/// @see View::FireScrollEvent
|
||||
///
|
||||
class ScrollEvent {
|
||||
public:
|
||||
///
|
||||
/// The scroll event granularity type
|
||||
///
|
||||
enum Type {
|
||||
kType_ScrollByPixel, ///< The delta value will be interpreted as number of pixels to scroll.
|
||||
kType_ScrollByPage, ///< The delta value will be interpreted as number of pages to scroll.
|
||||
};
|
||||
|
||||
///
|
||||
/// Scroll granularity type
|
||||
///
|
||||
Type type;
|
||||
|
||||
///
|
||||
/// Horizontal scroll amount
|
||||
///
|
||||
int delta_x;
|
||||
|
||||
///
|
||||
/// Vertical scroll amount
|
||||
///
|
||||
int delta_y;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,59 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/RefPtr.h>
|
||||
#include <Ultralight/String.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Storage for a browsing session (cookies, local storage, etc.).
|
||||
///
|
||||
/// This class stores data for a unique browsing session (cookies, local storage, application cache,
|
||||
/// indexed db. etc.). You can create multiple sessions to isolate data between different browsing
|
||||
/// contexts.
|
||||
///
|
||||
/// ## Default Session
|
||||
///
|
||||
/// The Renderer has a default session named "default" that is used if no session is specified when
|
||||
/// when creating a View.
|
||||
///
|
||||
/// ## Session Lifetime
|
||||
///
|
||||
/// Sessions can be either temporary (in-memory only) or persistent (backed to disk).
|
||||
///
|
||||
/// @see Renderer::CreateSession
|
||||
///
|
||||
class UExport Session : public RefCounted {
|
||||
public:
|
||||
///
|
||||
/// Whether or not this session is written to disk.
|
||||
///
|
||||
virtual bool is_persistent() const = 0;
|
||||
|
||||
///
|
||||
/// A unique name identifying this session.
|
||||
///
|
||||
virtual String name() const = 0;
|
||||
|
||||
///
|
||||
/// A unique numeric ID identifying this session.
|
||||
///
|
||||
virtual uint64_t id() const = 0;
|
||||
|
||||
///
|
||||
/// The disk path of this session (only valid for persistent sessions).
|
||||
///
|
||||
virtual String disk_path() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Session();
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,158 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/String8.h>
|
||||
#include <Ultralight/String16.h>
|
||||
#include <Ultralight/String32.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Unicode string container with conversions for UTF-8, UTF-16, and UTF-32.
|
||||
///
|
||||
/// This class is used to represent strings in Ultralight. It can be created from a variety of
|
||||
/// string types and converted to a number of unicode string types.
|
||||
///
|
||||
/// ## Accessing string data
|
||||
///
|
||||
/// Strings are natively stored in a null-terminated UTF-8 format. You can access the UTF-8 bytes
|
||||
/// using the `utf8()` method:
|
||||
///
|
||||
/// ```
|
||||
/// String str("Hello, world!");
|
||||
///
|
||||
/// // Print the UTF-8 data (guaranteed to be null-terminated)
|
||||
/// printf("%s\n", str.utf8().data());
|
||||
/// ```
|
||||
///
|
||||
class UExport String {
|
||||
public:
|
||||
///
|
||||
/// Create empty string
|
||||
///
|
||||
String();
|
||||
|
||||
///
|
||||
/// Create from null-terminated, ASCII C-string
|
||||
///
|
||||
String(const char* str);
|
||||
|
||||
///
|
||||
/// Create from raw, UTF-8 string with certain length
|
||||
///
|
||||
String(const char* str, size_t len);
|
||||
|
||||
///
|
||||
/// Create from existing String8 (UTF-8).
|
||||
///
|
||||
String(const String8& str);
|
||||
|
||||
///
|
||||
/// Create from raw UTF-16 string with certain length
|
||||
///
|
||||
String(const Char16* str, size_t len);
|
||||
|
||||
///
|
||||
/// Create from existing String16 (UTF-16)
|
||||
///
|
||||
String(const String16& str);
|
||||
|
||||
///
|
||||
/// Create from existing String32 (UTF-32)
|
||||
///
|
||||
String(const String32& str);
|
||||
|
||||
///
|
||||
/// Copy constructor
|
||||
///
|
||||
String(const String& other);
|
||||
|
||||
///
|
||||
/// Move constructor
|
||||
///
|
||||
String(String&& other);
|
||||
|
||||
///
|
||||
/// Destructor
|
||||
///
|
||||
~String();
|
||||
|
||||
///
|
||||
/// Assign string from another, copy is made
|
||||
///
|
||||
String& operator=(const String& other);
|
||||
|
||||
///
|
||||
/// Move assignment operator
|
||||
///
|
||||
String& operator=(String&& other);
|
||||
|
||||
///
|
||||
/// Append string with another
|
||||
///
|
||||
String& operator+=(const String& other);
|
||||
|
||||
///
|
||||
/// Concatenation operator
|
||||
///
|
||||
inline friend String operator+(String lhs, const String& rhs) {
|
||||
lhs += rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
///
|
||||
/// Get native UTF-8 string
|
||||
///
|
||||
String8& utf8() { return str_; }
|
||||
|
||||
///
|
||||
/// Get native UTF-8 string
|
||||
///
|
||||
const String8& utf8() const { return str_; }
|
||||
|
||||
///
|
||||
/// Convert to UTF-16 string
|
||||
///
|
||||
String16 utf16() const;
|
||||
|
||||
///
|
||||
/// Convert to UTF-32 string
|
||||
///
|
||||
String32 utf32() const;
|
||||
|
||||
///
|
||||
/// Check if string is empty or not
|
||||
///
|
||||
bool empty() const { return str_.empty(); }
|
||||
|
||||
///
|
||||
/// Hash function
|
||||
///
|
||||
size_t Hash() const;
|
||||
|
||||
///
|
||||
/// Comparison operator
|
||||
///
|
||||
bool operator<(const String& other) const;
|
||||
|
||||
///
|
||||
/// Equality operator
|
||||
///
|
||||
bool operator==(const String& other) const;
|
||||
|
||||
///
|
||||
/// Inequality operator
|
||||
///
|
||||
bool operator!=(const String& other) const;
|
||||
|
||||
private:
|
||||
String8 str_;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,152 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/RefPtr.h>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
class String8;
|
||||
class String32;
|
||||
|
||||
namespace detail {
|
||||
template<int> struct selector;
|
||||
template<> struct selector<4> { typedef char16_t Char16; };
|
||||
template<> struct selector<2> { typedef wchar_t Char16; };
|
||||
}
|
||||
|
||||
#ifdef DISABLE_NATIVE_WCHAR_T
|
||||
// Force Char16 type to use char16_t, used on Windows when native wchar_t support is disabled.
|
||||
typedef char16_t Char16;
|
||||
#else
|
||||
// We use wchar_t if size == 2, otherwise use char16_t
|
||||
typedef detail::selector<sizeof(wchar_t)>::Char16 Char16;
|
||||
#endif
|
||||
|
||||
///
|
||||
/// A null-terminated UTF-16 string container.
|
||||
///
|
||||
class UExport String16 {
|
||||
public:
|
||||
// Native character type
|
||||
typedef Char16 CharType;
|
||||
|
||||
// Make an empty String16
|
||||
String16();
|
||||
|
||||
// Make a String16 from raw UTF-16 buffer with certain length
|
||||
String16(const Char16* str, size_t len);
|
||||
|
||||
// Make a String16 from raw unsigned short UTF-16 buffer with certain length. Useful on Windows
|
||||
// when native support for wchar_t is disabled (eg, /Zc:wchar_t-).
|
||||
String16(const unsigned short* str, size_t len);
|
||||
|
||||
// Make a deep copy of String16
|
||||
String16(const String16& other);
|
||||
|
||||
// Move constructor
|
||||
String16(String16&& other);
|
||||
|
||||
// Destructor
|
||||
~String16();
|
||||
|
||||
// Assign a String16 to this one, deep copy is made
|
||||
String16& operator=(const String16& other);
|
||||
|
||||
// Move assignment operator
|
||||
String16& operator=(String16&& other);
|
||||
|
||||
// Append a String16 to this one.
|
||||
String16& operator+=(const String16& other);
|
||||
|
||||
// Concatenation operator
|
||||
inline friend String16 operator+(String16 lhs, const String16& rhs) { lhs += rhs; return lhs; }
|
||||
|
||||
// Get raw UTF-16 data
|
||||
Char16* data() { return data_; }
|
||||
|
||||
// Get raw UTF-16 data (const)
|
||||
const Char16* data() const { return data_; }
|
||||
|
||||
// Get raw UTF-16 data as unsigned short. This is useful on Windows if you compile without native
|
||||
// support for wchar_t (eg, /Zc:wchar_t-)
|
||||
unsigned short* udata() { return reinterpret_cast<unsigned short*>(data_); }
|
||||
|
||||
// Get raw UTF-16 data as unsigned short (const).
|
||||
const unsigned short* udata() const { return reinterpret_cast<const unsigned short*>(data_); }
|
||||
|
||||
// Get length in characters.
|
||||
size_t length() const { return length_; }
|
||||
|
||||
// Get size in characters (synonym for length)
|
||||
size_t size() const { return length_; }
|
||||
|
||||
// Get size in bytes
|
||||
size_t sizeBytes() const { return length_ * sizeof(Char16); }
|
||||
|
||||
// Check if string is empty.
|
||||
bool empty() const { return !data_ || length_ == 0; }
|
||||
|
||||
// Get character at specific position
|
||||
Char16& operator[](size_t pos) { return data_[pos]; }
|
||||
|
||||
// Get character at specific position (const)
|
||||
const Char16& operator[](size_t pos) const { return data_[pos]; }
|
||||
|
||||
// Get a UTF-8 copy of this string
|
||||
String8 utf8() const;
|
||||
|
||||
// Get a UTF-32 copy of this string
|
||||
String32 utf32() const;
|
||||
|
||||
// Hash function
|
||||
size_t Hash() const;
|
||||
|
||||
// Comparison operator
|
||||
bool operator<(const String16& other) const;
|
||||
|
||||
// Equality operator
|
||||
bool operator==(const String16& other) const;
|
||||
|
||||
// Inequality operator
|
||||
bool operator!=(const String16& other) const;
|
||||
|
||||
private:
|
||||
Char16* data_;
|
||||
size_t length_;
|
||||
};
|
||||
|
||||
///
|
||||
/// @brief A UTF-16 string vector.
|
||||
///
|
||||
class UExport String16Vector : public RefCounted {
|
||||
public:
|
||||
// Create an empty string vector
|
||||
static RefPtr<String16Vector> Create();
|
||||
|
||||
// Create a string vector from an existing array (a deep copy is made)
|
||||
static RefPtr<String16Vector> Create(const String16* stringArray, size_t len);
|
||||
|
||||
// Add an element to the back of the string vector
|
||||
virtual void push_back(const String16& val) = 0;
|
||||
|
||||
// Get raw String16 vector array
|
||||
virtual String16* data() = 0;
|
||||
|
||||
// Get the number of elements in vector
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
protected:
|
||||
String16Vector();
|
||||
virtual ~String16Vector();
|
||||
String16Vector(const String16Vector&);
|
||||
void operator=(const String16Vector&);
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,99 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
class String8;
|
||||
class String16;
|
||||
|
||||
///
|
||||
/// A null-terminated UTF-32 string container.
|
||||
///
|
||||
class UExport String32 {
|
||||
public:
|
||||
// Native character type
|
||||
typedef char32_t CharType;
|
||||
|
||||
// Make an empty String32
|
||||
String32();
|
||||
|
||||
// Make a String32 from raw UTF-32 string with certain length
|
||||
String32(const char32_t* c_str, size_t len);
|
||||
|
||||
// Make a deep copy of String32
|
||||
String32(const String32& other);
|
||||
|
||||
// Move constructor
|
||||
String32(String32&& other);
|
||||
|
||||
// Destructor
|
||||
~String32();
|
||||
|
||||
// Assign a String32 to this one, deep copy is made
|
||||
String32& operator=(const String32& other);
|
||||
|
||||
// Move assignment operator
|
||||
String32& operator=(String32&& other);
|
||||
|
||||
// Append a String32 to this one.
|
||||
String32& operator+=(const String32& other);
|
||||
|
||||
// Concatenation operator
|
||||
inline friend String32 operator+(String32 lhs, const String32& rhs) { lhs += rhs; return lhs; }
|
||||
|
||||
// Get raw UTF-32 data
|
||||
char32_t* data() { return data_; }
|
||||
|
||||
// Get raw UTF-32 data (const)
|
||||
const char32_t* data() const { return data_; }
|
||||
|
||||
// Get length in characters.
|
||||
size_t length() const { return length_; }
|
||||
|
||||
// Get size in characters (synonym for length)
|
||||
size_t size() const { return length_; }
|
||||
|
||||
// Get size in bytes
|
||||
size_t sizeBytes() const { return length_ * sizeof(char32_t); }
|
||||
|
||||
// Check if string is empty.
|
||||
bool empty() const { return !data_ || length_ == 0; }
|
||||
|
||||
// Get character at specific position
|
||||
char32_t& operator[](size_t pos) { return data_[pos]; }
|
||||
|
||||
// Get character at specific position (const)
|
||||
const char32_t& operator[](size_t pos) const { return data_[pos]; }
|
||||
|
||||
// Get a UTF-8 copy of this string
|
||||
String8 utf8() const;
|
||||
|
||||
// Get a UTF-16 copy of this string
|
||||
String16 utf16() const;
|
||||
|
||||
// Hash function
|
||||
size_t Hash() const;
|
||||
|
||||
// Comparison operator
|
||||
bool operator<(const String32& other) const;
|
||||
|
||||
// Equality operator
|
||||
bool operator==(const String32& other) const;
|
||||
|
||||
// Inequality operator
|
||||
bool operator!=(const String32& other) const;
|
||||
|
||||
private:
|
||||
char32_t* data_;
|
||||
size_t length_;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,102 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
class String16;
|
||||
class String32;
|
||||
|
||||
///
|
||||
/// A null-terminated UTF-8 string container.
|
||||
//
|
||||
class UExport String8 {
|
||||
public:
|
||||
// Native character type
|
||||
typedef char CharType;
|
||||
|
||||
// Make an empty String8
|
||||
String8();
|
||||
|
||||
// Make a String8 from raw, null-terminated UTF-8 string
|
||||
String8(const char* c_str);
|
||||
|
||||
// Make a String8 from raw UTF-8 string with certain length
|
||||
String8(const char* c_str, size_t len);
|
||||
|
||||
// Make a deep copy of String8
|
||||
String8(const String8& other);
|
||||
|
||||
// Move constructor
|
||||
String8(String8&& other);
|
||||
|
||||
// Destructor
|
||||
~String8();
|
||||
|
||||
// Assign a String8 to this one, deep copy is made
|
||||
String8& operator=(const String8& other);
|
||||
|
||||
// Move assignment operator
|
||||
String8& operator=(String8&& other);
|
||||
|
||||
// Append a String8 to this one.
|
||||
String8& operator+=(const String8& other);
|
||||
|
||||
// Concatenation operator
|
||||
inline friend String8 operator+(String8 lhs, const String8& rhs) { lhs += rhs; return lhs; }
|
||||
|
||||
// Get raw UTF-8 data
|
||||
char* data() { return data_; }
|
||||
|
||||
// Get raw UTF-8 data (const)
|
||||
const char* data() const { return data_; }
|
||||
|
||||
// Get length in characters.
|
||||
size_t length() const { return length_; }
|
||||
|
||||
// Get size in characters (synonym for length)
|
||||
size_t size() const { return length_; }
|
||||
|
||||
// Get size in bytes
|
||||
size_t sizeBytes() const { return length_ * sizeof(char); }
|
||||
|
||||
// Check if string is empty.
|
||||
bool empty() const { return !data_ || length_ == 0; }
|
||||
|
||||
// Get character at specific position
|
||||
char& operator[](size_t pos) { return data_[pos]; }
|
||||
|
||||
// Get character at specific position (const)
|
||||
const char& operator[](size_t pos) const { return data_[pos]; }
|
||||
|
||||
// Get a UTF-16 copy of this string
|
||||
String16 utf16() const;
|
||||
|
||||
// Get a UTF-32 copy of this string
|
||||
String32 utf32() const;
|
||||
|
||||
// Hash function
|
||||
size_t Hash() const;
|
||||
|
||||
// Comparison operator
|
||||
bool operator<(const String8& other) const;
|
||||
|
||||
// Equality operator
|
||||
bool operator==(const String8& other) const;
|
||||
|
||||
// Inequality operator
|
||||
bool operator!=(const String8& other) const;
|
||||
|
||||
private:
|
||||
char* data_;
|
||||
size_t length_;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,199 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
///
|
||||
/// @file StringSTL.h
|
||||
///
|
||||
/// STL compatibility header for ultralight::String.
|
||||
///
|
||||
/// `#include <Ultralight/StringSTL.h>`
|
||||
///
|
||||
/// This optional header provides utility functions for converting between ultralight::String,
|
||||
/// std::string, and std::string_view. It also provides support for using ultralight::String
|
||||
/// with standard library containers and stream operators.
|
||||
///
|
||||
/// @pre This header requires C++17 or later.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```cpp
|
||||
/// #include <Ultralight/StringSTL.h>
|
||||
/// #include <string>
|
||||
/// #include <iostream>
|
||||
///
|
||||
/// ultralight::String myStr("Hello, world!");
|
||||
///
|
||||
/// // Convert ultralight::String to std::string
|
||||
/// std::string stdStr = ultralight::Convert(myStr);
|
||||
///
|
||||
/// // Convert std::string to ultralight::String
|
||||
/// ultralight::String backToUl = ultralight::Convert(stdStr);
|
||||
///
|
||||
/// // Print ultralight::String to std::cout
|
||||
/// std::cout << myStr << std::endl;
|
||||
/// ```
|
||||
///
|
||||
#pragma once
|
||||
#include <Ultralight/String.h>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Trait to check if a type is a supported string-like type.
|
||||
///
|
||||
template <typename T>
|
||||
struct is_string_type : std::false_type {};
|
||||
|
||||
template <> struct is_string_type<String> : std::true_type {};
|
||||
template <> struct is_string_type<std::string> : std::true_type {};
|
||||
template <> struct is_string_type<std::string_view> : std::true_type {};
|
||||
template <> struct is_string_type<const char*> : std::true_type {};
|
||||
|
||||
///
|
||||
/// Convert between string types.
|
||||
///
|
||||
/// This function provides efficient conversion between different string types.
|
||||
/// It supports ultralight::String, std::string, std::string_view, and const char*.
|
||||
///
|
||||
/// The following type conversions are automatically deduced (no template argument needed):
|
||||
/// - ultralight::String -> std::string
|
||||
/// - std::string -> ultralight::String
|
||||
/// - std::string_view -> ultralight::String
|
||||
/// - const char* -> ultralight::String
|
||||
///
|
||||
/// For explicit conversion to std::string_view, use Convert<std::string_view>().
|
||||
///
|
||||
/// @tparam To The target string type (optional, deduced in common cases)
|
||||
/// @tparam From The source string type (optional)
|
||||
///
|
||||
/// @param from The string to convert
|
||||
///
|
||||
/// @return The converted string in the target type
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```cpp
|
||||
/// ultralight::String myStr("Hello, world!");
|
||||
///
|
||||
/// // ultralight::String -> std::string
|
||||
/// std::string stdStr = ultralight::Convert(myStr);
|
||||
///
|
||||
/// // ultralight::String -> std::string_view
|
||||
/// std::string_view svStr = ultralight::Convert<std::string_view>(myStr);
|
||||
///
|
||||
/// // std::string -> ultralight::String
|
||||
/// ultralight::String backToUl = ultralight::Convert(stdStr);
|
||||
///
|
||||
/// // std::string_view -> ultralight::String
|
||||
/// ultralight::String fromView = ultralight::Convert(std::string_view("View"));
|
||||
/// ```
|
||||
///
|
||||
template <typename To = void, typename From>
|
||||
auto Convert(const From& from) {
|
||||
static_assert(is_string_type<std::remove_cv_t<std::remove_reference_t<From>>>::value,
|
||||
"Convert only supports String, std::string, std::string_view, and const char*");
|
||||
|
||||
if constexpr (std::is_same_v<To, void>) {
|
||||
// Automatic deduction
|
||||
if constexpr (std::is_same_v<From, String>) {
|
||||
return std::string(from.utf8().data(), from.utf8().length());
|
||||
} else if constexpr (std::is_same_v<From, std::string> ||
|
||||
std::is_same_v<From, std::string_view>) {
|
||||
return String(from.data(), from.length());
|
||||
} else if constexpr (std::is_same_v<From, const char*>) {
|
||||
return String(from); // String constructor handles null-termination
|
||||
} else {
|
||||
// This case should never be reached due to the static_assert
|
||||
return From{};
|
||||
}
|
||||
} else {
|
||||
// Explicit conversion
|
||||
static_assert(is_string_type<To>::value,
|
||||
"Convert only supports String, std::string, std::string_view, and const char*");
|
||||
|
||||
if constexpr (std::is_same_v<To, From>) {
|
||||
return from;
|
||||
} else if constexpr (std::is_same_v<To, String>) {
|
||||
if constexpr (std::is_same_v<From, const char*>) {
|
||||
return String(from); // String constructor handles null-termination
|
||||
} else {
|
||||
return String(from.data(), from.length());
|
||||
}
|
||||
} else if constexpr (std::is_same_v<To, std::string>) {
|
||||
if constexpr (std::is_same_v<From, String>) {
|
||||
return std::string(from.utf8().data(), from.utf8().length());
|
||||
} else if constexpr (std::is_same_v<From, const char*>) {
|
||||
return std::string(from); // std::string constructor handles null-termination
|
||||
} else {
|
||||
return std::string(from);
|
||||
}
|
||||
} else if constexpr (std::is_same_v<To, std::string_view>) {
|
||||
if constexpr (std::is_same_v<From, String>) {
|
||||
return std::string_view(from.utf8().data(), from.utf8().length());
|
||||
} else if constexpr (std::is_same_v<From, const char*>) {
|
||||
return std::string_view(from); // std::string_view constructor handles null-termination
|
||||
} else {
|
||||
return std::string_view(from);
|
||||
}
|
||||
} else if constexpr (std::is_same_v<To, const char*>) {
|
||||
static_assert(!std::is_same_v<To, const char*>,
|
||||
"Direct conversion to const char* is not supported due to ownership issues. "
|
||||
"Convert to String, std::string, or std::string_view instead.");
|
||||
} else {
|
||||
// This case should never be reached due to the static_assert
|
||||
return To{};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ultralight
|
||||
|
||||
namespace std {
|
||||
|
||||
///
|
||||
/// Hash specialization for ultralight::String
|
||||
///
|
||||
template<>
|
||||
struct hash<ultralight::String> {
|
||||
size_t operator()(const ultralight::String& str) const {
|
||||
return str.Hash();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
///
|
||||
/// Stream output operator for ultralight::String.
|
||||
///
|
||||
/// @param os The output stream.
|
||||
//
|
||||
/// @param str The string to output.
|
||||
///
|
||||
/// @return The output stream.
|
||||
///
|
||||
inline std::ostream& operator<<(std::ostream& os, const ultralight::String& str) {
|
||||
return os << ultralight::Convert<std::string_view>(str);
|
||||
}
|
||||
|
||||
///
|
||||
/// Stream input operator for ultralight::String.
|
||||
///
|
||||
/// @param is The input stream.
|
||||
///
|
||||
/// @param str The string to input into.
|
||||
///
|
||||
/// @return The input stream.
|
||||
///
|
||||
inline std::istream& operator>>(std::istream& is, ultralight::String& str) {
|
||||
std::string temp;
|
||||
is >> temp;
|
||||
str = ultralight::Convert<ultralight::String>(temp);
|
||||
return is;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/RefPtr.h>
|
||||
#include <Ultralight/String8.h>
|
||||
#include <Ultralight/String16.h>
|
||||
#include <Ultralight/String32.h>
|
||||
#include <Ultralight/String.h>
|
||||
#include <Ultralight/Bitmap.h>
|
||||
#include <Ultralight/Buffer.h>
|
||||
#include <Ultralight/View.h>
|
||||
#include <Ultralight/Session.h>
|
||||
#include <Ultralight/KeyCodes.h>
|
||||
#include <Ultralight/KeyEvent.h>
|
||||
#include <Ultralight/Listener.h>
|
||||
#include <Ultralight/Matrix.h>
|
||||
#include <Ultralight/MouseEvent.h>
|
||||
#include <Ultralight/NetworkRequest.h>
|
||||
#include <Ultralight/ConsoleMessage.h>
|
||||
#include <Ultralight/Renderer.h>
|
||||
#include <Ultralight/Geometry.h>
|
||||
#include <Ultralight/RenderTarget.h>
|
||||
#include <Ultralight/ImageSource.h>
|
||||
#include <Ultralight/ScrollEvent.h>
|
||||
#include <Ultralight/GamepadEvent.h>
|
||||
#include <Ultralight/platform/Platform.h>
|
||||
#include <Ultralight/platform/Config.h>
|
||||
#include <Ultralight/platform/GPUDriver.h>
|
||||
#include <Ultralight/platform/FileSystem.h>
|
||||
#include <Ultralight/platform/FontLoader.h>
|
||||
#include <Ultralight/platform/Surface.h>
|
||||
#include <Ultralight/platform/Clipboard.h>
|
||||
#include <Ultralight/platform/Logger.h>
|
||||
@@ -0,0 +1,526 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2025 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/RefPtr.h>
|
||||
#include <Ultralight/KeyEvent.h>
|
||||
#include <Ultralight/JavaScript.h>
|
||||
#include <Ultralight/MouseEvent.h>
|
||||
#include <Ultralight/ScrollEvent.h>
|
||||
#include <Ultralight/GamepadEvent.h>
|
||||
#include <Ultralight/RenderTarget.h>
|
||||
#include <Ultralight/Bitmap.h>
|
||||
#include <Ultralight/Listener.h>
|
||||
#include <Ultralight/platform/Surface.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// View-specific configuration settings.
|
||||
///
|
||||
/// @see Renderer::CreateView
|
||||
///
|
||||
struct UExport ViewConfig {
|
||||
|
||||
///
|
||||
/// A user-generated id for the display (monitor, TV, or screen) that this View will be shown on.
|
||||
///
|
||||
/// Animations are driven based on the physical refresh rate of the display. Multiple Views can
|
||||
/// share the same display.
|
||||
///
|
||||
/// @note This is automatically managed for you when App::Create() is used.
|
||||
///
|
||||
/// @see Renderer::RefreshDisplay.
|
||||
///
|
||||
uint32_t display_id = 0;
|
||||
|
||||
///
|
||||
/// Whether to render using the GPU renderer (accelerated) or the CPU renderer (unaccelerated).
|
||||
///
|
||||
/// When true, the View will be rendered to an offscreen GPU texture using the GPU driver set in
|
||||
/// Platform::set_gpu_driver. You can fetch details for the texture via View::render_target.
|
||||
///
|
||||
/// When false (the default), the View will be rendered to an offscreen pixel buffer using the
|
||||
/// multithreaded CPU renderer. This pixel buffer can optionally be provided by the user--
|
||||
/// for more info see Platform::set_surface_factory and View::surface.
|
||||
///
|
||||
/// @note This is automatically managed for you when App::Create() is used.
|
||||
///
|
||||
bool is_accelerated = false;
|
||||
|
||||
///
|
||||
/// The initial device scale, ie. the amount to scale page units to screen pixels. This should
|
||||
/// be set to the scaling factor of the device that the View is displayed on.
|
||||
///
|
||||
/// @note 1.0 is equal to 100% zoom (no scaling), 2.0 is equal to 200% zoom (2x scaling)
|
||||
///
|
||||
/// @note This is automatically managed for you when App::Create() is used.
|
||||
///
|
||||
double initial_device_scale = 1.0;
|
||||
|
||||
///
|
||||
/// Whether or not this View should support transparency.
|
||||
///
|
||||
/// @note Make sure to also set the following CSS on the page:
|
||||
///
|
||||
/// html, body { background: transparent; }
|
||||
///
|
||||
bool is_transparent = false;
|
||||
|
||||
///
|
||||
/// Whether or not the View should initially have input focus, @see View::Focus()
|
||||
///
|
||||
bool initial_focus = true;
|
||||
|
||||
///
|
||||
/// Whether or not images should be enabled.
|
||||
///
|
||||
bool enable_images = true;
|
||||
|
||||
///
|
||||
/// Whether or not JavaScript should be enabled.
|
||||
///
|
||||
bool enable_javascript = true;
|
||||
|
||||
///
|
||||
/// Whether or not compositing should be enabled.
|
||||
///
|
||||
bool enable_compositor = false;
|
||||
|
||||
///
|
||||
/// Default font-family to use.
|
||||
///
|
||||
String font_family_standard = "Times New Roman";
|
||||
|
||||
///
|
||||
/// Default font-family to use for fixed fonts. (pre/code)
|
||||
///
|
||||
String font_family_fixed = "Courier New";
|
||||
|
||||
///
|
||||
/// Default font-family to use for serif fonts.
|
||||
///
|
||||
String font_family_serif = "Times New Roman";
|
||||
|
||||
///
|
||||
/// Default font-family to use for sans-serif fonts.
|
||||
///
|
||||
String font_family_sans_serif = "Arial";
|
||||
|
||||
///
|
||||
/// Custom user-agent string. You can use this to override the default user-agent string.
|
||||
///
|
||||
/// @pre This feature is only available in Ultralight Pro edition and above.
|
||||
///
|
||||
String user_agent = ULTRALIGHT_USER_AGENT;
|
||||
};
|
||||
|
||||
///
|
||||
/// Web-page container rendered to an offscreen surface.
|
||||
///
|
||||
/// The View class is responsible for loading and rendering web-pages to an offscreen surface. It
|
||||
/// is completely isolated from the OS windowing system, you must forward all input events to it
|
||||
/// from your application.
|
||||
///
|
||||
/// ## Creating a View
|
||||
///
|
||||
/// You can create a View using Renderer::CreateView.
|
||||
///
|
||||
/// ```
|
||||
/// // Create a ViewConfig with the desired settings
|
||||
/// ViewConfig view_config;
|
||||
///
|
||||
/// // Create a View, 500 by 500 pixels in size, using the default Session
|
||||
/// RefPtr<View> view = renderer->CreateView(500, 500, view_config, nullptr);
|
||||
/// ```
|
||||
///
|
||||
/// @note When using App::Create, the library will automatically create a View for you when you
|
||||
/// call Overlay::Create.
|
||||
///
|
||||
/// ## Loading Content into a View
|
||||
///
|
||||
/// You can load content asynchronously into a View using View::LoadURL().
|
||||
///
|
||||
/// ```
|
||||
/// // Load a URL into the View
|
||||
/// view->LoadURL("https://en.wikipedia.org/wiki/Main_Page");
|
||||
/// ```
|
||||
///
|
||||
/// ### Local File URLs
|
||||
///
|
||||
/// Local file URLs (eg, `file:///page.html`) will be loaded via FileSystem. You can provide your
|
||||
/// own FileSystem implementation so these files can be loaded from your application's resources.
|
||||
///
|
||||
/// ### Displaying Views in Your Application
|
||||
///
|
||||
/// Views are rendered either to a pixel-buffer (View::surface) or a GPU texture
|
||||
/// (View::render_target) depending on whether CPU or GPU rendering is used (see
|
||||
/// ViewConfig::is_accelerated).
|
||||
///
|
||||
/// You can use the Surface or RenderTarget to display the View in your application.
|
||||
///
|
||||
/// ```
|
||||
/// // Get the Surface for the View (assuming CPU rendering)
|
||||
/// Surface* surface = view->surface();
|
||||
///
|
||||
/// // Check if the Surface is dirty (pixels have changed)
|
||||
/// if (!surface->dirty_bounds().IsEmpty()) {
|
||||
/// // Cast to the default Surface implementation (BitmapSurface) and get
|
||||
/// // the underlying Bitmap.
|
||||
/// RefPtr<Bitmap> bitmap = static_cast<BitmapSurface*>(surface)->bitmap();
|
||||
///
|
||||
/// // Use the bitmap pixels here...
|
||||
///
|
||||
/// // Clear the dirty bounds after you're done displaying the pixels
|
||||
/// surface->ClearDirtyBounds();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ## Input Events
|
||||
///
|
||||
/// You must forward all input events to the View from your application. This includes keyboard,
|
||||
/// mouse, and scroll events.
|
||||
///
|
||||
/// ```
|
||||
/// // Forward a mouse-move event to the View
|
||||
/// MouseEvent evt;
|
||||
/// evt.type = MouseEvent::kType_MouseMoved;
|
||||
/// evt.x = 100;
|
||||
/// evt.y = 100;
|
||||
/// evt.button = MouseEvent::kButton_None;
|
||||
/// view->FireMouseEvent(evt);
|
||||
/// ```
|
||||
///
|
||||
/// @note The View API is not thread-safe, all calls must be made on the same thread that the
|
||||
/// Renderer or App was created on.
|
||||
///
|
||||
class UExport View : public RefCounted {
|
||||
public:
|
||||
///
|
||||
/// Get the URL of the current page loaded into this View, if any.
|
||||
///
|
||||
virtual String url() = 0;
|
||||
|
||||
///
|
||||
/// Get the title of the current page loaded into this View, if any.
|
||||
///
|
||||
virtual String title() = 0;
|
||||
|
||||
///
|
||||
/// Get the width of the View, in pixels.
|
||||
///
|
||||
virtual uint32_t width() const = 0;
|
||||
|
||||
///
|
||||
/// Get the height of the View, in pixels.
|
||||
///
|
||||
virtual uint32_t height() const = 0;
|
||||
|
||||
///
|
||||
/// Get the display id of the View.
|
||||
///
|
||||
/// @see ViewConfig::display_id
|
||||
///
|
||||
virtual uint32_t display_id() const = 0;
|
||||
|
||||
///
|
||||
/// Set the display id of the View.
|
||||
///
|
||||
/// This should be called when the View is moved to another display.
|
||||
///
|
||||
virtual void set_display_id(uint32_t id) = 0;
|
||||
|
||||
///
|
||||
/// Get the device scale, ie. the amount to scale page units to screen pixels.
|
||||
///
|
||||
/// For example, a value of 1.0 is equivalent to 100% zoom. A value of 2.0 is 200% zoom.
|
||||
///
|
||||
virtual double device_scale() const = 0;
|
||||
|
||||
///
|
||||
/// Set the device scale.
|
||||
///
|
||||
virtual void set_device_scale(double scale) = 0;
|
||||
|
||||
///
|
||||
/// Whether or not the View is GPU-accelerated. If this is false, the page will be rendered
|
||||
/// via the CPU renderer.
|
||||
///
|
||||
virtual bool is_accelerated() const = 0;
|
||||
|
||||
///
|
||||
/// Whether or not the View supports transparent backgrounds.
|
||||
///
|
||||
virtual bool is_transparent() const = 0;
|
||||
|
||||
///
|
||||
/// Check if the main frame of the page is currently loading.
|
||||
///
|
||||
virtual bool is_loading() = 0;
|
||||
|
||||
///
|
||||
/// Get the RenderTarget for the View.
|
||||
///
|
||||
/// @pre Only valid if this View is using the GPU renderer (see ViewConfig::is_accelerated).
|
||||
///
|
||||
/// @note You can use this with your GPUDriver implementation to bind and display the
|
||||
/// corresponding texture in your application.
|
||||
///
|
||||
virtual RenderTarget render_target() = 0;
|
||||
|
||||
///
|
||||
/// Get the Surface for the View (native pixel buffer that the CPU renderer draws into).
|
||||
///
|
||||
/// @pre This operation is only valid if the View is using the CPU renderer, (eg, it is
|
||||
/// **not** GPU accelerated, see ViewConfig::is_accelerated). This function will return
|
||||
/// return nullptr if the View is using the GPU renderer.
|
||||
///
|
||||
/// @note The default Surface is BitmapSurface but you can provide your own Surface
|
||||
/// implementation via Platform::set_surface_factory().
|
||||
///
|
||||
virtual Surface* surface() = 0;
|
||||
|
||||
///
|
||||
/// Load a raw string of HTML, the View will navigate to it as a new page.
|
||||
///
|
||||
/// @param html The raw HTML string to load.
|
||||
///
|
||||
/// @param url An optional URL for this load (to make it appear as if we we loaded this HTML
|
||||
/// from a certain URL). Can be used for resolving relative URLs and cross-origin
|
||||
/// rules.
|
||||
///
|
||||
/// @param add_to_history Whether or not this load should be added to the session's history
|
||||
/// (eg, the back/forward list).
|
||||
///
|
||||
virtual void LoadHTML(const String& html, const String& url = "", bool add_to_history = false)
|
||||
= 0;
|
||||
|
||||
///
|
||||
/// Load a URL, the View will navigate to it as a new page.
|
||||
///
|
||||
/// @note You can use File URLs (eg, file:///page.html) but you must define your own FileSystem
|
||||
/// implementation if you are not using AppCore. @see Platform::set_file_system
|
||||
///
|
||||
virtual void LoadURL(const String& url) = 0;
|
||||
|
||||
///
|
||||
/// Resize View to a certain size.
|
||||
///
|
||||
/// @param width The initial width, in pixels.
|
||||
///
|
||||
/// @param height The initial height, in pixels.
|
||||
///
|
||||
///
|
||||
virtual void Resize(uint32_t width, uint32_t height) = 0;
|
||||
|
||||
///
|
||||
/// Acquire the page's JSContext for use with the JavaScriptCore API
|
||||
///
|
||||
/// @note You can use the underlying JSContextRef with the JavaScriptCore C API. This allows you
|
||||
/// to marshall C/C++ objects to/from JavaScript, bind callbacks, and call JS functions
|
||||
/// directly.
|
||||
///
|
||||
/// @note The JSContextRef gets reset after each page navigation. You should initialize your
|
||||
/// JavaScript state within the OnWindowObjectReady and OnDOMReady events,
|
||||
/// @see ViewListener.
|
||||
///
|
||||
/// @note This call locks the internal context for the current thread. It will be unlocked when
|
||||
/// the returned JSContext's ref-count goes to zero. The lock is recursive, you can call
|
||||
/// this multiple times.
|
||||
///
|
||||
virtual RefPtr<JSContext> LockJSContext() = 0;
|
||||
|
||||
///
|
||||
/// Get a handle to the internal JavaScriptCore VM.
|
||||
///
|
||||
virtual void* JavaScriptVM() = 0;
|
||||
|
||||
///
|
||||
/// Helper function to evaluate a raw string of JavaScript and return the result as a String.
|
||||
///
|
||||
/// @param script A string of JavaScript to evaluate in the main frame.
|
||||
///
|
||||
/// @param exception A string to store the exception in, if any. Pass a nullptr if you don't
|
||||
/// care about exceptions.
|
||||
///
|
||||
/// @return Returns the JavaScript result typecast to a String.
|
||||
///
|
||||
///
|
||||
/// @note You do not need to lock the JS context, it is done automatically.
|
||||
///
|
||||
/// @note If you need lower-level access to native JavaScript values, you should instead lock
|
||||
/// the JS context and call JSEvaluateScript() in the JavaScriptCore C API.
|
||||
/// @see <JavaScriptCore/JSBase.h>
|
||||
///
|
||||
virtual String EvaluateScript(const String& script, String* exception = nullptr) = 0;
|
||||
|
||||
///
|
||||
/// Whether or not we can navigate backwards in history
|
||||
///
|
||||
virtual bool CanGoBack() = 0;
|
||||
|
||||
///
|
||||
/// Whether or not we can navigate forwards in history
|
||||
///
|
||||
virtual bool CanGoForward() = 0;
|
||||
|
||||
///
|
||||
/// Navigate backwards in history
|
||||
///
|
||||
virtual void GoBack() = 0;
|
||||
|
||||
///
|
||||
/// Navigate forwards in history
|
||||
///
|
||||
virtual void GoForward() = 0;
|
||||
|
||||
///
|
||||
/// Navigate to an arbitrary offset in history
|
||||
///
|
||||
virtual void GoToHistoryOffset(int offset) = 0;
|
||||
|
||||
///
|
||||
/// Reload current page
|
||||
///
|
||||
virtual void Reload() = 0;
|
||||
|
||||
///
|
||||
/// Stop all page loads
|
||||
///
|
||||
virtual void Stop() = 0;
|
||||
|
||||
///
|
||||
/// Give focus to the View.
|
||||
///
|
||||
/// You should call this to give visual indication that the View has input focus (changes active
|
||||
/// text selection colors, for example).
|
||||
///
|
||||
virtual void Focus() = 0;
|
||||
|
||||
///
|
||||
/// Remove focus from the View and unfocus any focused input elements.
|
||||
///
|
||||
/// You should call this to give visual indication that the View has lost input focus.
|
||||
///
|
||||
virtual void Unfocus() = 0;
|
||||
|
||||
///
|
||||
/// Whether or not the View has focus.
|
||||
///
|
||||
virtual bool HasFocus() = 0;
|
||||
|
||||
///
|
||||
/// Whether or not the View has an input element with visible keyboard focus (indicated by a
|
||||
/// blinking caret).
|
||||
///
|
||||
/// You can use this to decide whether or not the View should consume keyboard input events
|
||||
/// (useful in games with mixed UI and key handling).
|
||||
///
|
||||
virtual bool HasInputFocus() = 0;
|
||||
|
||||
///
|
||||
/// Fire a keyboard event
|
||||
///
|
||||
/// @note Only 'Char' events actually generate text in input fields.
|
||||
///
|
||||
virtual void FireKeyEvent(const KeyEvent& evt) = 0;
|
||||
|
||||
///
|
||||
/// Fire a mouse event
|
||||
///
|
||||
virtual void FireMouseEvent(const MouseEvent& evt) = 0;
|
||||
|
||||
///
|
||||
/// Fire a scroll event
|
||||
///
|
||||
virtual void FireScrollEvent(const ScrollEvent& evt) = 0;
|
||||
|
||||
///
|
||||
/// Set a ViewListener to receive callbacks for View-related events.
|
||||
///
|
||||
/// @note Ownership remains with the caller.
|
||||
///
|
||||
virtual void set_view_listener(ViewListener* listener) = 0;
|
||||
|
||||
///
|
||||
/// Get the active ViewListener, if any
|
||||
///
|
||||
virtual ViewListener* view_listener() const = 0;
|
||||
|
||||
///
|
||||
/// Set a LoadListener to receive callbacks for Load-related events.
|
||||
///
|
||||
/// @note Ownership remains with the caller.
|
||||
///
|
||||
virtual void set_load_listener(LoadListener* listener) = 0;
|
||||
|
||||
///
|
||||
/// Get the active LoadListener, if any
|
||||
///
|
||||
virtual LoadListener* load_listener() const = 0;
|
||||
|
||||
///
|
||||
/// Set a DownloadListener to receive callbacks for download-related events.
|
||||
///
|
||||
/// @note Ownership remains with the caller.
|
||||
///
|
||||
virtual void set_download_listener(DownloadListener* listener) = 0;
|
||||
|
||||
///
|
||||
/// Get the active DownloadListener, if any
|
||||
///
|
||||
virtual DownloadListener* download_listener() const = 0;
|
||||
|
||||
///
|
||||
/// Cancel an active download.
|
||||
///
|
||||
virtual void CancelDownload(DownloadId id) = 0;
|
||||
|
||||
///
|
||||
/// Set a NetworkListener to receive callbacks for network-related events.
|
||||
///
|
||||
/// @note Ownership remains with the caller.
|
||||
///
|
||||
virtual void set_network_listener(NetworkListener* listener) = 0;
|
||||
|
||||
///
|
||||
/// Get the active NetworkListener, if any
|
||||
///
|
||||
virtual NetworkListener* network_listener() const = 0;
|
||||
|
||||
///
|
||||
/// Set whether or not this View should be repainted during the next call to Renderer::Render
|
||||
///
|
||||
/// @note This flag is automatically set whenever the page content changes but you can set it
|
||||
/// directly in case you need to force a repaint.
|
||||
///
|
||||
virtual void set_needs_paint(bool needs_paint) = 0;
|
||||
|
||||
///
|
||||
/// Whether or not this View should be repainted during the next call to
|
||||
/// Renderer::Render.
|
||||
///
|
||||
virtual bool needs_paint() const = 0;
|
||||
|
||||
///
|
||||
/// Create an Inspector View to inspect / debug this View locally.
|
||||
///
|
||||
/// This will only succeed if you have the inspector assets in your filesystem-- the inspector
|
||||
/// will look for file:///inspector/Main.html when it first loads.
|
||||
///
|
||||
/// You must handle ViewListener::OnCreateInspectorView so that the library has a View to display
|
||||
/// the inspector in. This function will call this event only if an inspector view is not
|
||||
/// currently active.
|
||||
///
|
||||
virtual void CreateLocalInspectorView() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~View();
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,106 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#ifndef ULTRALIGHT_ALLOCATOR_H
|
||||
#define ULTRALIGHT_ALLOCATOR_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <Ultralight/Exports.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
///
|
||||
/// User-defined allocator interface.
|
||||
///
|
||||
/// @pre This API is only available in the Pro edition when the UL_ENABLE_ALLOCATOR_OVERRIDE
|
||||
/// build option is enabled.
|
||||
///
|
||||
/// The library uses this to allocate memory. You can override the default allocator functions
|
||||
/// by setting the ulAllocator object with your own functions.
|
||||
///
|
||||
/// This should be done before calling any other library functions.
|
||||
///
|
||||
/// @see ulAllocator
|
||||
///
|
||||
typedef struct {
|
||||
//
|
||||
// Allocate a block of memory of at least |bytes| size.
|
||||
//
|
||||
void* (*malloc)(size_t bytes);
|
||||
|
||||
//
|
||||
// Reallocate a block of memory to at least |bytes| size.
|
||||
//
|
||||
void* (*realloc)(void* address, size_t bytes);
|
||||
|
||||
//
|
||||
// Free a block of memory allocated with malloc or realloc.
|
||||
//
|
||||
void (*free)(void* address);
|
||||
|
||||
//
|
||||
// Allocate a block of memory of at least |bytes| size, aligned to |alignment|.
|
||||
//
|
||||
void* (*aligned_malloc)(size_t bytes, size_t alignment);
|
||||
|
||||
//
|
||||
// Reallocate a block of memory to at least |bytes| size, aligned to |alignment|.
|
||||
//
|
||||
void* (*aligned_realloc)(void* address, size_t bytes, size_t alignment);
|
||||
|
||||
//
|
||||
// Free a block of memory allocated with aligned_malloc or aligned_realloc.
|
||||
//
|
||||
void (*aligned_free)(void* address);
|
||||
|
||||
//
|
||||
// Get the size of the memory block that backs the allocation at |address|. The memory
|
||||
// block size is always at least as large as the allocation it backs, and may be larger.
|
||||
// * Windows equivalent: _msize
|
||||
// * POSIX equivalent: malloc_size
|
||||
//
|
||||
size_t (*get_size_estimate)(void* address);
|
||||
|
||||
} ULAllocator;
|
||||
|
||||
///
|
||||
/// Get the allocator interface object for the library.
|
||||
///
|
||||
/// @pre This API is only available in the Pro edition when the UL_ENABLE_ALLOCATOR_OVERRIDE
|
||||
/// build option is enabled.
|
||||
///
|
||||
/// The C functions set in this object will be used for allocating memory inside the library
|
||||
/// when the `UL_ENABLE_ALLOCATOR_OVERRIDE` build option is enabled.
|
||||
///
|
||||
/// Default functions are already set for all of these but you can override them with your own.
|
||||
///
|
||||
/// Platform specific notes:
|
||||
/// * __Windows__: The default functions use `HeapAlloc` / `HeapReAlloc` / `HeapFree`.
|
||||
///
|
||||
extern UCExport ULAllocator ulAllocator;
|
||||
|
||||
#ifdef _WIN32
|
||||
///
|
||||
/// Get the handle to the private heap used by the library.
|
||||
///
|
||||
/// This is the handle returned by `HeapCreate()`, you should destroy it after unloading the library
|
||||
/// by calling `HeapDestroy()`.
|
||||
///
|
||||
/// This is only valid if the UL_ENABLE_ALLOCATOR_OVERRIDE build option is enabled and the default
|
||||
/// functions are set in the ulAllocator object.
|
||||
///
|
||||
UCExport void* ulGetHeapHandle();
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ULTRALIGHT_ALLOCATOR_H
|
||||
@@ -0,0 +1,49 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/String.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// User-defined clipboard interface.
|
||||
///
|
||||
/// The library uses this to read and write data to the system's clipboard.
|
||||
///
|
||||
/// AppCore automatically provides a platform-specific implementation of this that cuts, copies,
|
||||
/// and pastes to the OS clipboard when you call App::Create().
|
||||
///
|
||||
/// If you are using Renderer::Create() instead of App::Create(), you will need to provide your own
|
||||
/// implementation of this. @see Platform::set_clipboard().
|
||||
///
|
||||
class UExport Clipboard {
|
||||
public:
|
||||
virtual ~Clipboard();
|
||||
|
||||
///
|
||||
/// Clear the clipboard.
|
||||
///
|
||||
virtual void Clear() = 0;
|
||||
|
||||
///
|
||||
/// Read plain text from the clipboard
|
||||
///
|
||||
/// This is called when the library wants to read text from the OS clipboard.
|
||||
///
|
||||
virtual String ReadPlainText() = 0;
|
||||
|
||||
///
|
||||
/// Write plain text to the clipboard.
|
||||
///
|
||||
/// This is called when the library wants to write text to the OS clipboard.
|
||||
///
|
||||
virtual void WritePlainText(const String& text) = 0;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,274 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2025 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/String.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// The winding order for front-facing triangles. (Only used when the GPU renderer is used)
|
||||
///
|
||||
enum class FaceWinding : uint8_t {
|
||||
///
|
||||
/// Clockwise Winding (Direct3D, etc.)
|
||||
///
|
||||
Clockwise,
|
||||
|
||||
///
|
||||
/// Counter-Clockwise Winding (OpenGL, etc.)
|
||||
///
|
||||
CounterClockwise,
|
||||
};
|
||||
|
||||
enum class FontHinting : uint8_t {
|
||||
///
|
||||
/// Lighter hinting algorithm-- glyphs are slightly fuzzier but better resemble their original
|
||||
/// shape. This is achieved by snapping glyphs to the pixel grid only vertically which better
|
||||
/// preserves inter-glyph spacing.
|
||||
///
|
||||
Smooth,
|
||||
|
||||
///
|
||||
/// Default hinting algorithm-- offers a good balance between sharpness and shape at smaller font
|
||||
/// sizes.
|
||||
///
|
||||
Normal,
|
||||
|
||||
///
|
||||
/// Strongest hinting algorithm-- outputs only black/white glyphs. The result is usually
|
||||
/// unpleasant if the underlying TTF does not contain hints for this type of rendering.
|
||||
///
|
||||
Monochrome,
|
||||
|
||||
///
|
||||
/// No hinting is performed-- fonts may be blurry at smaller font sizes.
|
||||
///
|
||||
None,
|
||||
};
|
||||
|
||||
enum class EffectQuality : uint8_t {
|
||||
///
|
||||
/// Fastest effect quality-- uses the lowest quality effects (half-resolution, fewer passes, etc.)
|
||||
///
|
||||
Low,
|
||||
|
||||
///
|
||||
/// Default effect quality-- strikes a good balance between quality and performance.
|
||||
///
|
||||
Medium,
|
||||
|
||||
///
|
||||
/// Highest effect quality-- favors quality over performance.
|
||||
///
|
||||
High,
|
||||
};
|
||||
|
||||
///
|
||||
/// Core configuration for the renderer.
|
||||
///
|
||||
/// These are various configuration options that can be used to customize the behavior of the
|
||||
/// library. These options can only be set once before creating the Renderer.
|
||||
///
|
||||
/// ## Setting the Config
|
||||
///
|
||||
/// You should create an instance of the Config struct, set its members, and then call
|
||||
/// Platform::set_config() before creating the Renderer at the beginning of your
|
||||
/// application's lifetime.
|
||||
///
|
||||
/// @par Example usage
|
||||
/// ```
|
||||
/// Config config;
|
||||
/// config.user_stylesheet = "body { background: purple; }";
|
||||
///
|
||||
/// Platform::instance().set_config(config);
|
||||
/// // (Setup other Platform interfaces here.)
|
||||
///
|
||||
/// auto renderer = Renderer::Create();
|
||||
/// ```
|
||||
///
|
||||
struct UExport Config {
|
||||
///
|
||||
/// A writable OS file path to store persistent Session data in.
|
||||
///
|
||||
/// This data may include cookies, cached network resources, indexed DB, etc.
|
||||
///
|
||||
/// @note Files are only written to the path when using a persistent Session.
|
||||
///
|
||||
/// @see Renderer::CreateSession()
|
||||
///
|
||||
String cache_path;
|
||||
|
||||
///
|
||||
/// The relative path to the resources folder (loaded via the FileSystem API).
|
||||
///
|
||||
/// The library loads certain resources (SSL certs, ICU data, etc.) from the FileSystem API
|
||||
/// during runtime (eg, `file:///resources/cacert.pem`).
|
||||
///
|
||||
/// You can customize the relative file path to the resources folder by modifying this setting.
|
||||
///
|
||||
/// @see FileSystem
|
||||
///
|
||||
String resource_path_prefix = "resources/";
|
||||
|
||||
///
|
||||
/// The winding order for front-facing triangles.
|
||||
///
|
||||
/// @pre Only used when GPU rendering is enabled for the View.
|
||||
///
|
||||
/// @see FaceWinding
|
||||
///
|
||||
FaceWinding face_winding = FaceWinding::CounterClockwise;
|
||||
|
||||
///
|
||||
/// The hinting algorithm to use when rendering fonts.
|
||||
///
|
||||
/// @see FontHinting
|
||||
///
|
||||
FontHinting font_hinting = FontHinting::Normal;
|
||||
|
||||
///
|
||||
/// The gamma to use when compositing font glyphs.
|
||||
///
|
||||
/// You can change this value to adjust font contrast (Adobe and Apple prefer 1.8).
|
||||
///
|
||||
double font_gamma = 1.8;
|
||||
|
||||
///
|
||||
/// Global user-defined CSS string (included before any CSS on the page).
|
||||
///
|
||||
/// You can use this to override default styles for various elements on the page.
|
||||
///
|
||||
/// @note This is an actual string of CSS, not a file path.
|
||||
///
|
||||
String user_stylesheet;
|
||||
|
||||
///
|
||||
/// Whether or not to continuously repaint any Views, regardless if they are dirty.
|
||||
///
|
||||
/// This is mainly used to diagnose painting/shader issues and profile performance.
|
||||
///
|
||||
bool force_repaint = false;
|
||||
|
||||
///
|
||||
/// The delay (in seconds) between every tick of a CSS animation. (Default: 60 FPS)
|
||||
///
|
||||
double animation_timer_delay = 1.0 / 60.0;
|
||||
|
||||
///
|
||||
/// The delay (in seconds) between every tick of a smooth scroll animation. (Default: 60 FPS)
|
||||
///
|
||||
double scroll_timer_delay = 1.0 / 60.0;
|
||||
|
||||
///
|
||||
/// The delay (in seconds) between every call to the recycler.
|
||||
///
|
||||
/// The library attempts to reclaim excess memory during calls to the internal recycler. You can
|
||||
/// change how often this is run by modifying this value.
|
||||
///
|
||||
double recycle_delay = 4.0;
|
||||
|
||||
///
|
||||
/// The size of WebCore's memory cache in bytes.
|
||||
///
|
||||
/// @note You should increase this if you anticipate handling pages with large resources, Safari
|
||||
/// typically uses 128+ MiB for its cache.
|
||||
///
|
||||
uint32_t memory_cache_size = 64 * 1024 * 1024;
|
||||
|
||||
///
|
||||
/// The number of pages to keep in the cache. (Default: 0, none)
|
||||
///
|
||||
/// @note
|
||||
/// \parblock
|
||||
///
|
||||
/// Safari typically caches about 5 pages and maintains an on-disk cache to support typical
|
||||
/// web-browsing activities.
|
||||
///
|
||||
/// If you increase this, you should probably increase the memory cache size as well.
|
||||
///
|
||||
/// \endparblock
|
||||
///
|
||||
uint32_t page_cache_size = 0;
|
||||
|
||||
///
|
||||
/// The system's physical RAM size in bytes.
|
||||
///
|
||||
/// JavaScriptCore tries to detect the system's physical RAM size to set reasonable allocation
|
||||
/// limits. Set this to anything other than 0 to override the detected value. Size is in bytes.
|
||||
///
|
||||
/// This can be used to force JavaScriptCore to be more conservative with its allocation strategy
|
||||
/// (at the cost of some performance).
|
||||
///
|
||||
uint32_t override_ram_size = 0;
|
||||
|
||||
///
|
||||
/// The minimum size of large VM heaps in JavaScriptCore.
|
||||
///
|
||||
/// Set this to a lower value to make these heaps start with a smaller initial value.
|
||||
///
|
||||
uint32_t min_large_heap_size = 32 * 1024 * 1024;
|
||||
|
||||
///
|
||||
/// The minimum size of small VM heaps in JavaScriptCore.
|
||||
///
|
||||
/// Set this to a lower value to make these heaps start with a smaller initial value.
|
||||
///
|
||||
uint32_t min_small_heap_size = 1 * 1024 * 1024;
|
||||
|
||||
///
|
||||
/// The number of threads to use in the Renderer (for parallel painting on the CPU, etc.).
|
||||
///
|
||||
/// You can set this to a certain number to limit the number of threads to spawn.
|
||||
///
|
||||
/// @note
|
||||
/// \parblock
|
||||
///
|
||||
/// If this value is 0, the number of threads will be determined at runtime using the following
|
||||
/// formula:
|
||||
///
|
||||
/// ```
|
||||
/// max(PhysicalProcessorCount() - 1, 1)
|
||||
/// ```
|
||||
///
|
||||
/// \endparblock
|
||||
///
|
||||
uint32_t num_renderer_threads = 0;
|
||||
|
||||
///
|
||||
/// The max amount of time (in seconds) to allow repeating timers to run during each call to
|
||||
/// Renderer::Update.
|
||||
///
|
||||
/// The library will attempt to throttle timers if this time budget is exceeded.
|
||||
///
|
||||
double max_update_time = 1.0 / 200.0;
|
||||
|
||||
///
|
||||
/// The alignment (in bytes) of the BitmapSurface when using the CPU renderer.
|
||||
///
|
||||
/// The underlying bitmap associated with each BitmapSurface will have row_bytes padded to reach
|
||||
/// this alignment.
|
||||
///
|
||||
/// Aligning the bitmap helps improve performance when using the CPU renderer. Determining the
|
||||
/// proper value to use depends on the CPU architecture and max SIMD instruction set used.
|
||||
///
|
||||
/// We generally target the 128-bit SSE2 instruction set across most PC platforms so '16' is
|
||||
/// a safe value to use.
|
||||
///
|
||||
/// You can set this to '0' to perform no padding (row_bytes will always be width * 4) at a
|
||||
/// slight cost to performance.
|
||||
///
|
||||
uint32_t bitmap_alignment = 16;
|
||||
|
||||
///
|
||||
/// The quality of effects (blurs, CSS filters, SVG filters, etc.) to use when rendering.
|
||||
///
|
||||
EffectQuality effect_quality = EffectQuality::Medium;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,105 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/String.h>
|
||||
#include <Ultralight/Buffer.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// User-defined file system interface.
|
||||
///
|
||||
/// The library uses this to load file data (ie, raw file bytes) for a given file URL
|
||||
/// (eg, `file:///page.html`) .
|
||||
///
|
||||
/// You can provide the library with your own FileSystem implementation so that file data is
|
||||
/// provided directly by your application (eg, from memory, from a virtual file system, etc).
|
||||
///
|
||||
/// ## Default Implementation
|
||||
///
|
||||
/// A platform-specific implementation of FileSystem is provided for you when you call
|
||||
/// App::Create().
|
||||
///
|
||||
/// If you are using Renderer::Create(), you **must** provide your own. You can still use AppCore's
|
||||
/// implementation however-- see the helper functions defined in <AppCore/Platform.h>.
|
||||
///
|
||||
/// ## Setting the File System
|
||||
///
|
||||
/// To provide your own custom FileSystem implementation, you should inherit from this class,
|
||||
/// handle the virtual member functions, and then pass an instance of your class to
|
||||
/// Platform::set_file_system() before calling Renderer::Create() or App::Create().
|
||||
///
|
||||
class UExport FileSystem {
|
||||
public:
|
||||
virtual ~FileSystem();
|
||||
|
||||
///
|
||||
/// Check if a file exists within the file system.
|
||||
///
|
||||
/// @param file_path Relative file path (the string following the file:/// prefix)
|
||||
///
|
||||
/// @return Returns whether or not a file exists at the path specified.
|
||||
///
|
||||
virtual bool FileExists(const String& file_path) = 0;
|
||||
|
||||
///
|
||||
/// Get the mime-type of a file (eg "text/html").
|
||||
///
|
||||
/// This is usually determined by analyzing the file extension.
|
||||
///
|
||||
/// If a mime-type cannot be determined, this should return "application/unknown".
|
||||
///
|
||||
/// @param file_path Relative file path (the string following the file:/// prefix)
|
||||
///
|
||||
/// @return Returns whether or not a file exists at the path specified.
|
||||
///
|
||||
virtual String GetFileMimeType(const String& file_path) = 0;
|
||||
|
||||
///
|
||||
/// Get the charset / encoding of a file (eg "utf-8", "iso-8859-1").
|
||||
///
|
||||
/// @note This is only applicable for text-based files (eg, "text/html", "text/plain") and is
|
||||
/// usually determined by analyzing the contents of the file.
|
||||
///
|
||||
/// @param file_path Relative file path (the string following the file:/// prefix)
|
||||
///
|
||||
/// @return Returns the charset of the specified file. If a charset cannot be determined, a safe
|
||||
/// default to return is "utf-8".
|
||||
///
|
||||
virtual String GetFileCharset(const String& file_path) = 0;
|
||||
|
||||
///
|
||||
/// Open a file for reading and map it to a Buffer.
|
||||
///
|
||||
/// To minimize copies, you should map the requested file into memory and use Buffer::Create()
|
||||
/// to wrap the data pointer (unmapping should be performed in the destruction callback).
|
||||
///
|
||||
/// @note
|
||||
/// \parblock
|
||||
/// File data addresses returned from this function should generally be aligned to 16-byte
|
||||
/// boundaries (the default alignment on most operating systems-- if you're using C stdlib or
|
||||
/// C++ STL functions this is already handled for you).
|
||||
///
|
||||
/// This requirement is currently necessary when loading the ICU data file (eg, icudt67l.dat),
|
||||
/// and may be relaxed for other files (but you may still see a performance benefit due to cache
|
||||
/// line alignment).
|
||||
///
|
||||
/// If you can't guarantee alignment or are unsure, you can use Buffer::CreateFromCopy to copy
|
||||
/// the file data content to an aligned block (at the expense of data duplication).
|
||||
/// \endparblock
|
||||
///
|
||||
/// @param file_path Relative file path (the string following the file:/// prefix)
|
||||
///
|
||||
/// @return If the file was able to be opened, this returns a Buffer object representing the
|
||||
/// contents of the file. If the file was unable to be opened, you should return nullptr.
|
||||
///
|
||||
virtual RefPtr<Buffer> OpenFile(const String& file_path) = 0;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,129 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/String.h>
|
||||
#include <Ultralight/Buffer.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Represents a font file, either on-disk path or in-memory file contents.
|
||||
///
|
||||
class UExport FontFile : public RefCounted {
|
||||
public:
|
||||
///
|
||||
/// Create a font file from an on-disk file path.
|
||||
///
|
||||
/// @note The file path should already exist.
|
||||
///
|
||||
static RefPtr<FontFile> Create(const String& filepath);
|
||||
|
||||
///
|
||||
/// Create a font file from an in-memory buffer.
|
||||
///
|
||||
static RefPtr<FontFile> Create(RefPtr<Buffer> buffer);
|
||||
|
||||
///
|
||||
/// Whether or not this font file was created from an in-memory buffer.
|
||||
///
|
||||
virtual bool is_in_memory() const = 0;
|
||||
|
||||
///
|
||||
/// The file path (if any).
|
||||
///
|
||||
virtual String filepath() const = 0;
|
||||
|
||||
///
|
||||
/// The in-memory buffer (if any).
|
||||
///
|
||||
virtual RefPtr<Buffer> buffer() const = 0;
|
||||
|
||||
///
|
||||
/// Unique hash (if this is a filepath, only the path string is hashed).
|
||||
///
|
||||
virtual uint32_t hash() const = 0;
|
||||
|
||||
protected:
|
||||
FontFile();
|
||||
virtual ~FontFile();
|
||||
FontFile(const FontFile&);
|
||||
void operator=(const FontFile&);
|
||||
};
|
||||
|
||||
///
|
||||
/// User-defined font loader interface.
|
||||
///
|
||||
/// The library uses this to load a font file (eg, `Arial.ttf`) for a given font description (eg,
|
||||
/// `font-family: Arial;`).
|
||||
///
|
||||
/// Every OS has its own library of installed system fonts. The FontLoader interface is used to
|
||||
/// lookup these fonts and fetch the actual font data (raw TTF/OTF file data) for a given font
|
||||
/// description.
|
||||
///
|
||||
/// You can provide the library with your own font loader implementation so that you can bundle
|
||||
/// fonts with your application rather than relying on the system's installed fonts.
|
||||
///
|
||||
/// ## Default Implementation
|
||||
///
|
||||
/// A platform-specific implementation of FontLoader is provided for you when you call
|
||||
/// App::Create().
|
||||
///
|
||||
/// If you are using Renderer::Create(), you **must** provide your own. You can still use AppCore's
|
||||
/// implementation however-- see the helper functions defined in <AppCore/Platform.h>.
|
||||
///
|
||||
/// ## Setting the Font Loader
|
||||
///
|
||||
/// To provide your own custom FontLoader implementation, you should inherit from this class,
|
||||
/// handle the virtual member functions, and then pass an instance of your class to
|
||||
/// Platform::set_font_loader() before calling Renderer::Create() or App::Create().
|
||||
///
|
||||
class UExport FontLoader {
|
||||
public:
|
||||
virtual ~FontLoader();
|
||||
|
||||
///
|
||||
/// Fallback font family name. Will be used if all other fonts fail to load.
|
||||
///
|
||||
/// @note This font should be guaranteed to exist (eg, FontLoader::Load won't fail when passed
|
||||
/// this font family name).
|
||||
///
|
||||
virtual String fallback_font() const = 0;
|
||||
|
||||
///
|
||||
/// Fallback font family name that can render the specified characters. Mainly used to support
|
||||
/// CJK (Chinese, Japanese, Korean) text display.
|
||||
///
|
||||
/// @param characters One or more UTF-16 characters. This is almost always a single character.
|
||||
///
|
||||
/// @param weight Font weight.
|
||||
///
|
||||
/// @param italic Whether or not italic is requested.
|
||||
///
|
||||
/// @return Returns a font family name that can render the text.
|
||||
///
|
||||
virtual String fallback_font_for_characters(const String& characters, int weight,
|
||||
bool italic) const = 0;
|
||||
|
||||
///
|
||||
/// Get the actual font file data (TTF/OTF) for a given font description.
|
||||
///
|
||||
/// @param family Font family name.
|
||||
///
|
||||
/// @param weight Font weight.
|
||||
///
|
||||
/// @param italic Whether or not italic is requested.
|
||||
///
|
||||
/// @return A font file matching the given description (either an on-disk font filepath or an
|
||||
/// in-memory file contents). You can return NULL here and the loader will fallback to
|
||||
/// another font.
|
||||
///
|
||||
virtual RefPtr<FontFile> Load(const String& family, int weight, bool italic) = 0;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,436 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#pragma warning(disable : 4251)
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/Geometry.h>
|
||||
#include <Ultralight/Matrix.h>
|
||||
#include <Ultralight/Bitmap.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
/// \cond ignore
|
||||
/// This pragma pack(push, 1) command is important!
|
||||
/// GPU structs should not be padded with any bytes.
|
||||
/// \endcond
|
||||
#pragma pack(push, 1)
|
||||
|
||||
///
|
||||
/// Render buffer description.
|
||||
///
|
||||
/// This structure describes a render buffer that can be used as a target for drawing commands.
|
||||
///
|
||||
/// @see GPUDriver::CreateRenderBuffer.
|
||||
///
|
||||
struct UExport RenderBuffer {
|
||||
uint32_t texture_id; ///< The backing texture for this RenderBuffer
|
||||
uint32_t width; ///< The width of the RenderBuffer texture
|
||||
uint32_t height; ///< The height of the RenderBuffer texture
|
||||
bool has_stencil_buffer; ///< Currently unused, always false.
|
||||
bool has_depth_buffer; ///< Currently unsued, always false.
|
||||
};
|
||||
|
||||
///
|
||||
/// Vertex layout for path vertices.
|
||||
///
|
||||
/// This struct is the in-memory layout for each path vertex (useful for synthesizing or modifying
|
||||
/// your own vertex data).
|
||||
///
|
||||
struct Vertex_2f_4ub_2f {
|
||||
float pos[2];
|
||||
unsigned char color[4];
|
||||
float obj[2];
|
||||
};
|
||||
|
||||
///
|
||||
/// Vertex layout for quad vertices.
|
||||
///
|
||||
/// This struct is the in-memory layout for each quad vertex (useful for synthesizing or modifying
|
||||
/// your own vertex data).
|
||||
///
|
||||
struct Vertex_2f_4ub_2f_2f_28f {
|
||||
float pos[2];
|
||||
unsigned char color[4];
|
||||
float tex[2];
|
||||
float obj[2];
|
||||
float data0[4];
|
||||
float data1[4];
|
||||
float data2[4];
|
||||
float data3[4];
|
||||
float data4[4];
|
||||
float data5[4];
|
||||
float data6[4];
|
||||
};
|
||||
|
||||
///
|
||||
/// Vertex buffer formats.
|
||||
///
|
||||
/// This enumeration describes the format of a vertex buffer.
|
||||
///
|
||||
/// @note Identifiers start with an underscore due to C++ naming rules.
|
||||
///
|
||||
/// @see VertexBuffer
|
||||
///
|
||||
enum class VertexBufferFormat : uint8_t {
|
||||
_2f_4ub_2f, ///< Vertex_2f_4ub_2f (used for path rendering)
|
||||
_2f_4ub_2f_2f_28f, ///< Vertex_2f_4ub_2f_2f_28f (used for quad rendering)
|
||||
};
|
||||
|
||||
///
|
||||
/// Vertex buffer description.
|
||||
///
|
||||
/// @see GPUDriver::CreateGeometry
|
||||
///
|
||||
struct UExport VertexBuffer {
|
||||
VertexBufferFormat format; ///< The format of the vertex buffer.
|
||||
uint32_t size; ///< The size of the vertex buffer in bytes.
|
||||
uint8_t* data; ///< The raw vertex buffer data.
|
||||
};
|
||||
|
||||
///
|
||||
/// Vertex index type.
|
||||
///
|
||||
typedef uint32_t IndexType;
|
||||
|
||||
///
|
||||
/// Index buffer description.
|
||||
///
|
||||
/// This structure describes an index buffer that can be used to index into a vertex buffer.
|
||||
///
|
||||
/// @note The index buffer is a simple array of IndexType values.
|
||||
///
|
||||
/// @see GPUDriver::CreateGeometry
|
||||
///
|
||||
struct UExport IndexBuffer {
|
||||
uint32_t size; ///< The size of the index buffer in bytes.
|
||||
uint8_t* data; ///< The raw index buffer data.
|
||||
};
|
||||
|
||||
///
|
||||
/// Shader program types.
|
||||
///
|
||||
/// Each of these correspond to a vertex/pixel shader pair. You can find stock shader code for
|
||||
/// these in the `shaders` folder of the AppCore repo.
|
||||
///
|
||||
/// @see GPUState::shader_type
|
||||
///
|
||||
enum class ShaderType : uint8_t {
|
||||
Fill, ///< Shader program for filling quad geometry.
|
||||
FillPath, ///< Shader program for filling tesselated path geometry.
|
||||
};
|
||||
|
||||
///
|
||||
/// The state of the GPU for a given draw command.
|
||||
///
|
||||
/// This structure describes the current state of the GPU for a given draw command.
|
||||
///
|
||||
/// @see Command::gpu_state
|
||||
///
|
||||
struct UExport GPUState {
|
||||
/// Viewport width in pixels
|
||||
uint32_t viewport_width;
|
||||
|
||||
/// Viewport height in pixels
|
||||
uint32_t viewport_height;
|
||||
|
||||
/// Transform matrix-- you should multiply this with the screen-space orthographic projection
|
||||
/// matrix then pass to the vertex shader.
|
||||
Matrix4x4 transform;
|
||||
|
||||
/// Whether or not we should enable texturing for the current draw command.
|
||||
bool enable_texturing;
|
||||
|
||||
/// Whether or not we should enable blending for the current draw command. If blending is
|
||||
/// disabled, any drawn pixels should overwrite existing. This is mainly used so we can modify
|
||||
/// alpha values of the RenderBuffer during scissored clears.
|
||||
bool enable_blend;
|
||||
|
||||
/// The vertex/pixel shader program pair to use for the current draw command.
|
||||
ShaderType shader_type;
|
||||
|
||||
/// The render buffer to use for the current draw command.
|
||||
uint32_t render_buffer_id;
|
||||
|
||||
/// The texture id to bind to slot #1. (Will be 0 if none)
|
||||
uint32_t texture_1_id;
|
||||
|
||||
/// The texture id to bind to slot #2. (Will be 0 if none)
|
||||
uint32_t texture_2_id;
|
||||
|
||||
/// The texture id to bind to slot #3. (Will be 0 if none)
|
||||
uint32_t texture_3_id;
|
||||
|
||||
/// The uniform scalars (passed to the pixel shader via uniforms).
|
||||
float uniform_scalar[8];
|
||||
|
||||
/// The uniform vectors (passed to the pixel shader via uniforms).
|
||||
vec4 uniform_vector[8];
|
||||
|
||||
/// The clip size (passed to the pixel shader via uniforms).
|
||||
uint8_t clip_size;
|
||||
|
||||
/// The clip stack (passed to the pixel shader via uniforms).
|
||||
Matrix4x4 clip[8];
|
||||
|
||||
/// Whether or not scissor testing should be used for the current draw command.
|
||||
bool enable_scissor;
|
||||
|
||||
/// The scissor rect to use for scissor testing (units in pixels)
|
||||
IntRect scissor_rect;
|
||||
};
|
||||
|
||||
///
|
||||
/// The types of commands.
|
||||
///
|
||||
/// This enumeration describes the type of command to execute on the GPU.
|
||||
///
|
||||
/// @see Command
|
||||
///
|
||||
enum class CommandType : uint8_t {
|
||||
ClearRenderBuffer, ///< Clear the specified render buffer.
|
||||
DrawGeometry, ///< Draw the specified geometry to the specified render buffer.
|
||||
};
|
||||
|
||||
///
|
||||
/// A command to execute on the GPU.
|
||||
///
|
||||
/// This structure describes a command to be executed on the GPU.
|
||||
///
|
||||
/// Commands are dispatched to the GPU driver asynchronously via GPUDriver::UpdateCommandList(),
|
||||
/// the GPU driver should consume these commands and execute them at an appropriate time.
|
||||
///
|
||||
/// @see CommandList
|
||||
///
|
||||
struct UExport Command {
|
||||
CommandType command_type; ///< The type of command to dispatch.
|
||||
GPUState gpu_state; ///< The current GPU state.
|
||||
uint32_t geometry_id; ///< The geometry ID to bind. (used with CommandType::DrawGeometry)
|
||||
uint32_t indices_count; ///< The number of indices. (used with CommandType::DrawGeometry)
|
||||
uint32_t indices_offset; ///< The index to start from. (used with CommandType::DrawGeometry)
|
||||
};
|
||||
|
||||
///
|
||||
/// List of commands to execute on the GPU.
|
||||
///
|
||||
/// @see GPUDriver::UpdateCommandList
|
||||
///
|
||||
struct UExport CommandList {
|
||||
uint32_t size; ///< The number of commands in the list.
|
||||
Command* commands; ///< The raw command list data.
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
///
|
||||
/// User-defined GPU driver interface.
|
||||
///
|
||||
/// The library uses this to optionally render Views on the GPU (see ViewConfig::is_accelerated).
|
||||
///
|
||||
/// You can provide the library with your own GPU driver implementation so that all rendering is
|
||||
/// performed using an existing GPU context (useful for game engines).
|
||||
///
|
||||
/// When a View is rendered on the GPU, you can retrieve the backing texture ID via
|
||||
/// View::render_target().
|
||||
///
|
||||
/// ## Default Implementation
|
||||
///
|
||||
/// A platform-specific implementation of GPUDriver is provided for you when you call App::Create(),
|
||||
/// (currently D3D11, Metal, and OpenGL). We recommend using these classes as a starting point for
|
||||
/// your own implementation (available open-source in the AppCore repository on GitHub).
|
||||
///
|
||||
/// ## Setting the GPU Driver
|
||||
///
|
||||
/// When using Renderer::Create(), you can provide your own implementation of this
|
||||
/// class via Platform::set_gpu_driver().
|
||||
///
|
||||
/// ## State Synchronization
|
||||
///
|
||||
/// During each call to Renderer::Render(), the library will update the state of the GPU driver
|
||||
/// (textures, render buffers, geometry, command lists, etc.) to match the current state of the
|
||||
/// library.
|
||||
///
|
||||
/// ### Detecting State Changes
|
||||
///
|
||||
/// The library will call BeginSynchronize() before any state is updated and EndSynchronize() after
|
||||
/// all state is updated. All `Create` / `Update` / `Destroy` calls will be made between these two
|
||||
/// calls.
|
||||
///
|
||||
/// This allows the GPU driver implementation to prepare the GPU for any state changes.
|
||||
///
|
||||
/// ## Drawing
|
||||
///
|
||||
/// All drawing is done via command lists (UpdateCommandList()) to allow asynchronous execution
|
||||
/// of commands on the GPU.
|
||||
///
|
||||
/// The library will dispatch a list of commands to the GPU driver during state synchronization. The
|
||||
/// GPU driver implementation should periodically consume the command list and execute the commands
|
||||
/// at an appropriate time.
|
||||
///
|
||||
/// @see Platform::set_gpu_driver()
|
||||
///
|
||||
class UExport GPUDriver {
|
||||
public:
|
||||
virtual ~GPUDriver();
|
||||
|
||||
///
|
||||
/// Called before any state (eg, CreateTexture(), UpdateTexture(), DestroyTexture(), etc.) is
|
||||
/// updated during a call to Renderer::Render().
|
||||
///
|
||||
/// This is a good time to prepare the GPU for any state updates.
|
||||
///
|
||||
virtual void BeginSynchronize() = 0;
|
||||
|
||||
///
|
||||
/// Called after all state has been updated during a call to Renderer::Render().
|
||||
///
|
||||
virtual void EndSynchronize() = 0;
|
||||
|
||||
///
|
||||
/// Get the next available texture ID.
|
||||
///
|
||||
/// This is used to generate a unique texture ID for each texture created by the library. The
|
||||
/// GPU driver implementation is responsible for mapping these IDs to a native ID.
|
||||
///
|
||||
/// @note Numbering should start at 1, 0 is reserved for "no texture".
|
||||
///
|
||||
/// @return Returns the next available texture ID.
|
||||
///
|
||||
virtual uint32_t NextTextureId() = 0;
|
||||
|
||||
///
|
||||
/// Create a texture with a certain ID and optional bitmap.
|
||||
///
|
||||
/// @param texture_id The texture ID to use for the new texture.
|
||||
///
|
||||
/// @param bitmap The bitmap to initialize the texture with (can be empty).
|
||||
///
|
||||
/// @note If the Bitmap is empty (Bitmap::IsEmpty), then a RTT Texture should be created instead.
|
||||
/// This will be used as a backing texture for a new RenderBuffer.
|
||||
///
|
||||
/// @warning A deep copy of the bitmap data should be made if you are uploading it to the GPU
|
||||
/// asynchronously, it will not persist beyond this call.
|
||||
///
|
||||
virtual void CreateTexture(uint32_t texture_id, RefPtr<Bitmap> bitmap) = 0;
|
||||
|
||||
///
|
||||
/// Update an existing non-RTT texture with new bitmap data.
|
||||
///
|
||||
/// @param texture_id The texture to update.
|
||||
///
|
||||
/// @param bitmap The new bitmap data.
|
||||
///
|
||||
/// @warning A deep copy of the bitmap data should be made if you are uploading it to the GPU
|
||||
/// asynchronously, it will not persist beyond this call.
|
||||
///
|
||||
virtual void UpdateTexture(uint32_t texture_id, RefPtr<Bitmap> bitmap) = 0;
|
||||
|
||||
///
|
||||
/// Destroy a texture.
|
||||
///
|
||||
/// @param texture_id The texture to destroy.
|
||||
///
|
||||
virtual void DestroyTexture(uint32_t texture_id) = 0;
|
||||
|
||||
///
|
||||
/// Get the next available render buffer ID.
|
||||
///
|
||||
/// This is used to generate a unique render buffer ID for each render buffer created by the
|
||||
/// library. The GPU driver implementation is responsible for mapping these IDs to a native ID.
|
||||
///
|
||||
/// @note Numbering should start at 1, 0 is reserved for "no render buffer".
|
||||
///
|
||||
/// @return Returns the next available render buffer ID.
|
||||
///
|
||||
virtual uint32_t NextRenderBufferId() = 0;
|
||||
|
||||
///
|
||||
/// Create a render buffer with certain ID and buffer description.
|
||||
///
|
||||
/// @param render_buffer_id The render buffer ID to use for the new render buffer.
|
||||
///
|
||||
/// @param buffer The render buffer description.
|
||||
///
|
||||
virtual void CreateRenderBuffer(uint32_t render_buffer_id, const RenderBuffer& buffer) = 0;
|
||||
|
||||
///
|
||||
/// Destroy a render buffer.
|
||||
///
|
||||
/// @param render_buffer_id The render buffer to destroy.
|
||||
///
|
||||
virtual void DestroyRenderBuffer(uint32_t render_buffer_id) = 0;
|
||||
|
||||
///
|
||||
/// Get the next available geometry ID.
|
||||
///
|
||||
/// This is used to generate a unique geometry ID for each geometry created by the library. The
|
||||
/// GPU driver implementation is responsible for mapping these IDs to a native ID.
|
||||
///
|
||||
/// @note Numbering should start at 1, 0 is reserved for "no geometry".
|
||||
///
|
||||
/// @return Returns the next available geometry ID.
|
||||
///
|
||||
virtual uint32_t NextGeometryId() = 0;
|
||||
|
||||
///
|
||||
/// Create geometry with certain ID and vertex/index data.
|
||||
///
|
||||
/// @param geometry_id The geometry ID to use for the new geometry.
|
||||
///
|
||||
/// @param vertices The vertex buffer data.
|
||||
///
|
||||
/// @param indices The index buffer data.
|
||||
///
|
||||
/// @warning A deep copy of the vertex/index data should be made if you are uploading it to the
|
||||
/// GPU asynchronously, it will not persist beyond this call.
|
||||
///
|
||||
virtual void CreateGeometry(uint32_t geometry_id, const VertexBuffer& vertices,
|
||||
const IndexBuffer& indices)
|
||||
= 0;
|
||||
|
||||
///
|
||||
/// Update existing geometry with new vertex/index data.
|
||||
///
|
||||
/// @param geometry_id The geometry to update.
|
||||
///
|
||||
/// @param vertices The new vertex buffer data.
|
||||
///
|
||||
/// @param indices The new index buffer data.
|
||||
///
|
||||
/// @warning A deep copy of the vertex/index data should be made if you are uploading it to the
|
||||
/// GPU asynchronously, it will not persist beyond this call.
|
||||
///
|
||||
virtual void UpdateGeometry(uint32_t geometry_id, const VertexBuffer& vertices,
|
||||
const IndexBuffer& indices)
|
||||
= 0;
|
||||
|
||||
///
|
||||
/// Destroy geometry.
|
||||
///
|
||||
/// @param geometry_id The geometry to destroy.
|
||||
///
|
||||
virtual void DestroyGeometry(uint32_t geometry_id) = 0;
|
||||
|
||||
///
|
||||
/// Update the pending command list with commands to execute on the GPU.
|
||||
///
|
||||
/// Commands are dispatched to the GPU driver asynchronously via this method. The GPU driver
|
||||
/// implementation should consume these commands and execute them at an appropriate time.
|
||||
///
|
||||
/// @param list The list of commands to execute.
|
||||
///
|
||||
/// @warning Implementations should make a deep copy of the command list, it will not persist
|
||||
/// beyond this call.
|
||||
///
|
||||
virtual void UpdateCommandList(const CommandList& list) = 0;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
|
||||
// clang-format on
|
||||
@@ -0,0 +1,42 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/String.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Log levels, used with Logger::LogMessage
|
||||
///
|
||||
enum class LogLevel : uint8_t {
|
||||
Error,
|
||||
Warning,
|
||||
Info
|
||||
};
|
||||
|
||||
///
|
||||
/// User-defined logging interface.
|
||||
///
|
||||
/// The library uses this to display log messages for debugging during development.
|
||||
///
|
||||
/// This is intended to be implemented by users and defined before creating the Renderer.
|
||||
///
|
||||
/// @see Platform::set_logger()
|
||||
///
|
||||
class UExport Logger {
|
||||
public:
|
||||
virtual ~Logger();
|
||||
|
||||
///
|
||||
/// Called when the library wants to display a log message.
|
||||
///
|
||||
virtual void LogMessage(LogLevel log_level, const String& message) = 0;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,182 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
struct Config;
|
||||
class Logger;
|
||||
class GPUDriver;
|
||||
class FontLoader;
|
||||
class FileSystem;
|
||||
class Clipboard;
|
||||
class SurfaceFactory;
|
||||
class ThreadFactory;
|
||||
|
||||
///
|
||||
/// Global platform singleton, manages user-defined platform handlers and global config.
|
||||
///
|
||||
/// The library uses the Platform API for most platform-specific operations (eg, file access,
|
||||
/// clipboard, font loading, GPU access, pixel buffer transport, etc.).
|
||||
///
|
||||
/// ## Motivation
|
||||
///
|
||||
/// Ultralight is designed to work in as many platforms and environments as possible. To achieve
|
||||
/// this, we've factored out most platform-specific code into a set of interfaces that you can
|
||||
/// implement and set on the Platform singleton.
|
||||
///
|
||||
/// ## Default Implementations
|
||||
///
|
||||
/// We provide a number of default implementations for desktop platforms (eg, Windows, macOS, Linux)
|
||||
/// for you when you call App::Create(). These implementations are defined in the
|
||||
/// [AppCore repository](https://github.com/ultralight-ux/AppCore/tree/master/src), we recommend
|
||||
/// using their source code as a starting point for your own implementations.
|
||||
///
|
||||
/// ## Required Handlers
|
||||
///
|
||||
/// When using Renderer::Create() directly, you'll need to provide your own implementations for
|
||||
/// FileSystem and FontLoader at a minimum.
|
||||
///
|
||||
/// @par Overview of which platform handlers are required / optional / provided:
|
||||
///
|
||||
/// | | Renderer::Create() | App::Create() |
|
||||
/// |----------------|--------------------|---------------|
|
||||
/// | FileSystem | **Required** | *Provided* |
|
||||
/// | FontLoader | **Required** | *Provided* |
|
||||
/// | Clipboard | *Optional* | *Provided* |
|
||||
/// | GPUDriver | *Optional* | *Provided* |
|
||||
/// | Logger | *Optional* | *Provided* |
|
||||
/// | SurfaceFactory | *Provided* | *Provided* |
|
||||
/// | ThreadFactory | *Optional* | *Optional* |
|
||||
///
|
||||
/// @note This singleton should be set up before creating the Renderer or App.
|
||||
///
|
||||
class UExport Platform {
|
||||
public:
|
||||
///
|
||||
/// Get the Platform singleton
|
||||
///
|
||||
static Platform& instance();
|
||||
|
||||
virtual ~Platform();
|
||||
|
||||
///
|
||||
/// Set the Config
|
||||
///
|
||||
virtual void set_config(const Config& config) = 0;
|
||||
|
||||
///
|
||||
/// Get the Config
|
||||
///
|
||||
virtual const Config& config() const = 0;
|
||||
|
||||
///
|
||||
/// Set the Logger (to handle error messages and debug output).
|
||||
///
|
||||
/// @param logger A user-defined Logger implementation, ownership remains with the caller.
|
||||
///
|
||||
virtual void set_logger(Logger* logger) = 0;
|
||||
|
||||
///
|
||||
/// Get the Logger
|
||||
///
|
||||
virtual Logger* logger() const = 0;
|
||||
|
||||
///
|
||||
/// Set the GPU Driver (will handle all rendering)
|
||||
///
|
||||
/// @param gpu_driver A user-defined GPUDriver implementation, ownership remains with the
|
||||
/// caller.
|
||||
///
|
||||
virtual void set_gpu_driver(GPUDriver* gpu_driver) = 0;
|
||||
|
||||
///
|
||||
/// Get the GPU Driver
|
||||
///
|
||||
virtual GPUDriver* gpu_driver() const = 0;
|
||||
|
||||
///
|
||||
/// Set the Font Loader (will be used to map font families to actual fonts)
|
||||
///
|
||||
/// @param font_loader A user-defined FontLoader implementation, ownership remains with the
|
||||
/// caller.
|
||||
///
|
||||
virtual void set_font_loader(FontLoader* font_loader) = 0;
|
||||
|
||||
///
|
||||
/// Get the Font Loader
|
||||
///
|
||||
virtual FontLoader* font_loader() const = 0;
|
||||
|
||||
///
|
||||
/// Set the File System (will be used for all file system operations)
|
||||
///
|
||||
/// @param file_system A user-defined FileSystem implementation, ownership remains with the
|
||||
/// caller.
|
||||
///
|
||||
virtual void set_file_system(FileSystem* file_system) = 0;
|
||||
|
||||
///
|
||||
/// Get the File System
|
||||
///
|
||||
virtual FileSystem* file_system() const = 0;
|
||||
|
||||
///
|
||||
/// Set the Clipboard (will be used for all clipboard operations)
|
||||
///
|
||||
/// @param clipboard A user-defined Clipboard implementation, ownership remains with the
|
||||
/// caller.
|
||||
///
|
||||
virtual void set_clipboard(Clipboard* clipboard) = 0;
|
||||
|
||||
///
|
||||
/// Get the Clipboard
|
||||
///
|
||||
virtual Clipboard* clipboard() const = 0;
|
||||
|
||||
///
|
||||
/// Set the SurfaceFactory
|
||||
///
|
||||
/// This can be used to provide a platform-specific bitmap surface for View to paint into when
|
||||
/// the CPU renderer is enabled. See View::surface().
|
||||
///
|
||||
/// @param surface_factory A user-defined SurfaceFactory implementation, ownership remains with
|
||||
/// the caller.
|
||||
///
|
||||
/// @note A default BitmapSurfaceFactory is defined if you never call this, View::surface() can
|
||||
/// be safely cast to BitmapSurface.
|
||||
///
|
||||
virtual void set_surface_factory(SurfaceFactory* surface_factory) = 0;
|
||||
|
||||
///
|
||||
/// Get the SurfaceFactory
|
||||
///
|
||||
/// @note A default BitmapSurfaceFactory is set by default, View::surface() can be safely cast
|
||||
/// to BitmapSurface if you don't define your own.
|
||||
///
|
||||
virtual SurfaceFactory* surface_factory() const = 0;
|
||||
|
||||
///
|
||||
/// Set the ThreadFactory
|
||||
///
|
||||
/// This can be used to provide a platform-specific ThreadFactory implementation for the library
|
||||
/// to use when creating threads.
|
||||
///
|
||||
/// @param thread_factory A user-defined ThreadFactory implementation, ownership remains with the
|
||||
/// caller.
|
||||
///
|
||||
virtual void set_thread_factory(ThreadFactory* thread_factory) = 0;
|
||||
|
||||
///
|
||||
/// Get the ThreadFactory
|
||||
///
|
||||
virtual ThreadFactory* thread_factory() const = 0;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,204 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
#include <Ultralight/RefPtr.h>
|
||||
#include <Ultralight/Bitmap.h>
|
||||
#include <Ultralight/Geometry.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// User-defined pixel buffer surface.
|
||||
///
|
||||
/// The library uses this to store pixel data when rendering Views on the CPU (see
|
||||
/// ViewConfig::is_accelerated).
|
||||
///
|
||||
/// You can provide the library with your own Surface implementation to reduce the latency of
|
||||
/// displaying pixels in your application (Views will be drawn directly to a block of memory
|
||||
/// controlled by you).
|
||||
///
|
||||
/// When a View is rendered on the CPU, you can retrieve the backing Surface via View::surface().
|
||||
///
|
||||
/// @pre This is automatically managed for you when using App::Create(), if you want to override
|
||||
/// Surface or SurfaceFactory, you'll need to use Renderer::Create() instead.
|
||||
///
|
||||
/// ## Default Implementation
|
||||
///
|
||||
/// A default Surface implementation, BitmapSurface, is automatically provided by the library when
|
||||
/// you call Renderer::Create() without defining a custom SurfaceFactory.
|
||||
///
|
||||
/// You should cast the Surface to a BitmapSurface to access the underlying Bitmap.
|
||||
///
|
||||
/// ## Setting the Surface Implementation
|
||||
///
|
||||
/// To define your own implementation, you should inherit from this class, handle the virtual
|
||||
/// member functions, and then define a custom SurfaceFactory that creates/destroys an
|
||||
/// instance of your class.
|
||||
///
|
||||
/// After that, you should pass an instance of your custom SurfaceFactory class to
|
||||
/// Platform::set_surface_factory() before calling Renderer::Create().
|
||||
///
|
||||
class UExport Surface {
|
||||
public:
|
||||
virtual ~Surface();
|
||||
|
||||
///
|
||||
/// Width (in pixels).
|
||||
///
|
||||
virtual uint32_t width() const = 0;
|
||||
|
||||
///
|
||||
/// Height (in pixels).
|
||||
///
|
||||
virtual uint32_t height() const = 0;
|
||||
|
||||
///
|
||||
/// Number of bytes between rows (usually width * 4)
|
||||
///
|
||||
virtual uint32_t row_bytes() const = 0;
|
||||
|
||||
///
|
||||
/// Size in bytes.
|
||||
///
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
///
|
||||
/// Lock the pixel buffer and get a pointer to the beginning of the data for reading/writing.
|
||||
///
|
||||
/// @note Native pixel format is premultiplied BGRA 32-bit (8 bits per channel).
|
||||
///
|
||||
virtual void* LockPixels() = 0;
|
||||
|
||||
///
|
||||
/// Unlock the pixel buffer.
|
||||
///
|
||||
virtual void UnlockPixels() = 0;
|
||||
|
||||
///
|
||||
/// Resize the pixel buffer to a certain width and height (both in pixels).
|
||||
///
|
||||
/// This should never be called while pixels are locked.
|
||||
///
|
||||
virtual void Resize(uint32_t width, uint32_t height) = 0;
|
||||
|
||||
///
|
||||
/// Set the dirty bounds to a certain value.
|
||||
///
|
||||
/// This is called after the Renderer paints to an area of the pixel buffer. (The new value will
|
||||
/// be joined with the existing dirty_bounds())
|
||||
///
|
||||
virtual void set_dirty_bounds(const IntRect& bounds);
|
||||
|
||||
///
|
||||
/// Get the dirty bounds.
|
||||
///
|
||||
/// This value can be used to determine which portion of the pixel buffer has been updated since
|
||||
/// the last call to ClearDirtyBounds().
|
||||
///
|
||||
/// The general algorithm to determine if a Surface needs display is:
|
||||
/// <pre>
|
||||
/// if (!surface.dirty_bounds().IsEmpty()) {
|
||||
/// // Surface pixels are dirty and needs display.
|
||||
/// // Cast Surface to native Surface and use it here (pseudo code)
|
||||
/// DisplaySurface(surface);
|
||||
///
|
||||
/// // Once you're done, clear the dirty bounds:
|
||||
/// surface.ClearDirtyBounds();
|
||||
/// }
|
||||
/// </pre>
|
||||
///
|
||||
virtual IntRect dirty_bounds() const;
|
||||
|
||||
///
|
||||
/// Clear the dirty bounds.
|
||||
///
|
||||
/// You should call this after you're done displaying the Surface.
|
||||
///
|
||||
virtual void ClearDirtyBounds();
|
||||
|
||||
protected:
|
||||
Surface();
|
||||
|
||||
IntRect dirty_bounds_;
|
||||
};
|
||||
|
||||
///
|
||||
/// User-defined factory to provide your own surface implementation.
|
||||
///
|
||||
/// The library uses this to create/destroy Surface instances when rendering Views on the CPU.
|
||||
///
|
||||
/// @pre This is automatically managed for you when using App::Create(), if you want to override
|
||||
/// Surface or SurfaceFactory, you'll need to use Renderer::Create() instead.
|
||||
///
|
||||
/// ## Setting the Surface Factory
|
||||
///
|
||||
/// The default factory creates/destroys a BitmapSurface but you can override this by providing your
|
||||
/// own factory to Platform::set_surface_factory().
|
||||
///
|
||||
class UExport SurfaceFactory {
|
||||
public:
|
||||
virtual ~SurfaceFactory();
|
||||
|
||||
///
|
||||
/// Create a native Surface with a certain width and height (in pixels).
|
||||
///
|
||||
virtual Surface* CreateSurface(uint32_t width, uint32_t height) = 0;
|
||||
|
||||
///
|
||||
/// Destroy a native Surface previously created by CreateSurface().
|
||||
///
|
||||
virtual void DestroySurface(Surface* surface) = 0;
|
||||
};
|
||||
|
||||
///
|
||||
/// The default surface implementation, backed by a bitmap.
|
||||
///
|
||||
/// This is automatically provided by the library when you call Renderer::Create() without defining
|
||||
/// a custom SurfaceFactory.
|
||||
///
|
||||
/// This implementation uses a Bitmap to store pixel data (retrieve it via BitmapSurface::bitmap()).
|
||||
///
|
||||
class UExport BitmapSurface : public Surface {
|
||||
public:
|
||||
virtual uint32_t width() const override;
|
||||
|
||||
virtual uint32_t height() const override;
|
||||
|
||||
virtual uint32_t row_bytes() const override;
|
||||
|
||||
virtual size_t size() const override;
|
||||
|
||||
virtual void* LockPixels() override;
|
||||
|
||||
virtual void UnlockPixels() override;
|
||||
|
||||
virtual void Resize(uint32_t width, uint32_t height) override;
|
||||
|
||||
///
|
||||
/// Get the underlying Bitmap.
|
||||
///
|
||||
RefPtr<Bitmap> bitmap();
|
||||
|
||||
protected:
|
||||
BitmapSurface(uint32_t width, uint32_t height);
|
||||
virtual ~BitmapSurface();
|
||||
BitmapSurface(const BitmapSurface&) = delete;
|
||||
void operator=(const BitmapSurface&) = delete;
|
||||
friend class BitmapSurfaceFactory;
|
||||
|
||||
void* impl_;
|
||||
};
|
||||
|
||||
///
|
||||
/// Get the default Bitmap Surface Factory singleton. (Do not destroy this, this singleton is owned
|
||||
/// by the library).
|
||||
///
|
||||
UExport SurfaceFactory* GetBitmapSurfaceFactory();
|
||||
|
||||
} // namespace ultralight
|
||||
@@ -0,0 +1,93 @@
|
||||
/**************************************************************************************************
|
||||
* This file is a part of Ultralight. *
|
||||
* *
|
||||
* See <https://ultralig.ht> for licensing and more. *
|
||||
* *
|
||||
* (C) 2024 Ultralight, Inc. *
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
#include <Ultralight/Defines.h>
|
||||
|
||||
namespace ultralight {
|
||||
|
||||
///
|
||||
/// Unique id of the thread, used for referencing the created thread later.
|
||||
/// * on Windows this should match the thread identifier returned by either _beginthreadex()
|
||||
/// or GetCurrentThreadId()
|
||||
/// * on POSIX this can be whatever unique id you want
|
||||
///
|
||||
typedef uint32_t ThreadId;
|
||||
|
||||
///
|
||||
/// Platform-specific handle
|
||||
/// * on Windows this is HANDLE
|
||||
/// * on POSIX this is pthread_t
|
||||
///
|
||||
typedef uint64_t ThreadHandle;
|
||||
|
||||
///
|
||||
/// Entry point for the thread, this function should be called by the thread once it is active
|
||||
/// and should be passed entry_point_data as the argument.
|
||||
///
|
||||
typedef void (*ThreadEntryPoint)(void*);
|
||||
|
||||
///
|
||||
/// The type of thread, you can choose to optionally handle these for better performance.
|
||||
///
|
||||
enum class ThreadType : uint8_t {
|
||||
Unknown = 0,
|
||||
JavaScript,
|
||||
Compiler,
|
||||
GarbageCollection,
|
||||
Network,
|
||||
Graphics,
|
||||
Audio,
|
||||
};
|
||||
|
||||
///
|
||||
/// Result of creating a new thread.
|
||||
///
|
||||
/// This struct is used to return the id and handle of the created thread.
|
||||
///
|
||||
struct UExport CreateThreadResult {
|
||||
ThreadId id; ///< The unique id of the thread. @see ThreadId
|
||||
ThreadHandle handle; ///< The platform-specific handle of the thread. @see ThreadHandle
|
||||
};
|
||||
|
||||
///
|
||||
/// User-defined factory for creating new threads.
|
||||
///
|
||||
/// You can implement this interface so that the library will use your own implementation for
|
||||
/// creating threads (useful for tracking thread creation, setting thread names, etc).
|
||||
///
|
||||
/// ## Default Implementation
|
||||
///
|
||||
/// When no factory is defined, the library will create threads using the default platform-specific
|
||||
/// thread creation functions (eg, `_beginthreadex()` on Windows, `pthread_create()` on POSIX).
|
||||
///
|
||||
/// ## Setting the Thread Factory
|
||||
///
|
||||
/// To provide your own custom ThreadFactory implementation, you should inherit from this class,
|
||||
/// handle the virtual member functions, and then pass an instance to
|
||||
/// Platform::set_thread_factory().
|
||||
///
|
||||
class UExport ThreadFactory {
|
||||
public:
|
||||
virtual ~ThreadFactory() = default;
|
||||
|
||||
///
|
||||
/// Create a new thread.
|
||||
///
|
||||
/// @param name The name of the thread (can be nullptr).
|
||||
/// @param type The type of thread.
|
||||
/// @param entry_point The entry point for the thread.
|
||||
/// @param entry_point_data The data to pass to the entry point.
|
||||
/// @param result The resulting id and handle of the thread creation.
|
||||
///
|
||||
/// @return Returns whether or not the thread was created successfully.
|
||||
///
|
||||
virtual bool CreateThread(const char* name, ThreadType type, ThreadEntryPoint entry_point,
|
||||
void* entry_point_data, CreateThreadResult& result) = 0;
|
||||
};
|
||||
|
||||
} // namespace ultralight
|
||||
Reference in New Issue
Block a user