Added SDK

This commit is contained in:
Andrew Zambazos
2026-06-11 14:01:22 +12:00
commit c0395a49bd
2155 changed files with 451005 additions and 0 deletions
@@ -0,0 +1,189 @@
#include <Ultralight/CAPI.h>
#include <AppCore/CAPI.h>
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#define sleep_ms(x) Sleep(x)
#else
#include <unistd.h>
#define sleep_ms(x) usleep((x)*1000)
#endif
///
/// Welcome to Sample 1 (for the C API)!
///
/// In this sample we'll load a local HTML file and render it to a PNG.
///
/// Quick overview of the steps we'll cover:
///
/// 1. Define our Platform handlers.
/// 2. Create the Renderer.
/// 3. Create our View.
/// 4. Load a local file into the View.
/// 5. Wait for it to load using our own main loop.
/// 6. Render the View.
/// 7. Get the rendered Bitmap and save it to a PNG.
///
bool done = false;
// Forward declaration of our load callback
void OnFinishLoading(void* user_data, ULView caller, unsigned long long frame_id,
bool is_main_frame, ULString url);
int main() {
///
/// Setup our config.
///
/// @note:
/// We don't set any config options in this sample but you could set your own options here.
///
ULConfig config = ulCreateConfig();
///
/// We must provide our own Platform API handlers since we're not using ulCreateApp().
///
/// The Platform API handlers we can set are:
///
/// | | ulCreateRenderer() | ulCreateApp() |
/// |-------------------|--------------------|---------------|
/// | FileSystem | **Required** | *Provided* |
/// | FontLoader | **Required** | *Provided* |
/// | Clipboard | *Optional* | *Provided* |
/// | GPUDriver | *Optional* | *Provided* |
/// | Logger | *Optional* | *Provided* |
/// | SurfaceDefinition | *Provided* | *Provided* |
///
/// The only Platform API handlers we are required to provide are file system and font loader.
///
/// In this sample we will use AppCore's font loader and file system via
/// ulEnablePlatformFontLoader() and ulEnablePlatformFileSystem() respectively.
///
/// You can replace these with your own implementations later.
///
ulEnablePlatformFontLoader();
///
/// Use AppCore's file system singleton to load file:/// URLs from the OS.
///
ULString base_dir = ulCreateString("./assets/");
ulEnablePlatformFileSystem(base_dir);
ulDestroyString(base_dir);
///
/// Use AppCore's defaut logger to write the log file to disk.
///
ULString log_path = ulCreateString("./ultralight.log");
ulEnableDefaultLogger(log_path);
ulDestroyString(log_path);
///
/// Create our renderer using the Config we just set up.
///
/// The Renderer singleton maintains the lifetime of the library and is required before creating
/// any Views. It should outlive any Views.
///
/// You should set up any platform handlers before creating this.
///
ULRenderer renderer = ulCreateRenderer(config);
ulDestroyConfig(config);
///
/// Create our View.
///
/// Views are sized containers for loading and displaying web content.
///
/// Let's set a 2x DPI scale and disable GPU acceleration so we can render to a bitmap.
///
ULViewConfig view_config = ulCreateViewConfig();
ulViewConfigSetInitialDeviceScale(view_config, 2.0);
ulViewConfigSetIsAccelerated(view_config, false);
ULView view = ulCreateView(renderer, 1600, 800, view_config, 0);
ulDestroyViewConfig(view_config);
///
/// Register OnFinishLoading() callback with our View.
///
ulViewSetFinishLoadingCallback(view, &OnFinishLoading, 0);
///
/// Load a local HTML file into the View (uses the file system defined above).
///
/// @note:
/// This operation may not complete immediately-- we will call ulUpdate() continuously
/// and wait for the OnFinishLoading event before rendering our View.
///
/// Views can also load remote URLs, try replacing the code below with:
///
/// ULString url_string = ulCreateString("https://en.wikipedia.org");
/// ulViewLoadURL(view, url_string);
/// ulDestroyString(url_string);
///
ULString url_string = ulCreateString("file:///page.html");
ulViewLoadURL(view, url_string);
ulDestroyString(url_string);
printf("Starting Run(), waiting for page to load...\n");
///
/// Continuously update until OnFinishLoading() is called below (which sets done = true).
///
/// @note:
/// Calling ulUpdate() handles any pending network requests, resource loads, and
/// JavaScript timers.
///
do {
ulUpdate(renderer);
sleep_ms(10);
} while (!done);
///
/// Render our View.
///
/// @note:
/// Calling ulRender will render any dirty Views to their respective Surfaces.
///
ulRender(renderer);
///
/// Get our View's rendering surface.
///
ULSurface surface = ulViewGetSurface(view);
///
/// Get the underlying bitmap.
///
/// @note We're using the default surface definition which is BitmapSurface, you can override
/// the surface implementation via ulPlatformSetSurfaceDefinition()
///
ULBitmap bitmap = ulBitmapSurfaceGetBitmap(surface);
///
/// Write our bitmap to a PNG in the current working directory.
///
ulBitmapWritePNG(bitmap, "result.png");
printf("Saved a render of our page to result.png.\n");
}
///
/// This is called when a View finishes loading a page into a frame.
///
void OnFinishLoading(void* user_data, ULView caller, unsigned long long frame_id,
bool is_main_frame, ULString url) {
///
/// Our page is done when the main frame is finished loading.
///
if (is_main_frame) {
printf("Our page has loaded!\n");
///
/// Set our done flag to true to exit the Run loop.
///
done = true;
}
}
@@ -0,0 +1 @@
add_console_app(Sample1 main.cpp)
@@ -0,0 +1,38 @@
<html>
<head>
<style type="text/css">
body {
margin: 0;
padding: 0;
overflow: hidden;
color: white;
font-family: -apple-system, 'Segoe UI', 'Roboto', 'Arial', sans-serif;
background: linear-gradient(45deg, #4e95ff, #6032e4, #c478ff);
}
div {
width: 350px;
text-align: center;
border-radius: 5px;
background: linear-gradient(45deg, #61a0ff, #6737e9, #cb86ff);
}
body, div {
display: flex;
justify-content: center;
align-items: center;
}
h1 {
padding: 1em;
font-size: 24px;
font-weight: normal;
}
</style>
</head>
<body>
<div>
<h1>Hello Ultralight!</h1>
</div>
</body>
</html>
+209
View File
@@ -0,0 +1,209 @@
#include <Ultralight/Ultralight.h>
#include <AppCore/AppCore.h>
#include <iostream>
#include <string>
#include <memory>
#include <thread>
#include <chrono>
using namespace ultralight;
///
/// Welcome to Sample 1!
///
/// In this sample we'll load a local HTML file and render it to a PNG.
///
/// Quick overview of the steps we'll cover:
///
/// 1. Define our Platform handlers.
/// 2. Create the Renderer.
/// 3. Create our View.
/// 4. Load a local file into the View.
/// 5. Wait for it to load using our own main loop.
/// 6. Render the View.
/// 7. Get the rendered Bitmap and save it to a PNG.
///
class MyApp : public LoadListener,
public Logger {
RefPtr<Renderer> renderer_;
RefPtr<View> view_;
bool done_ = false;
public:
MyApp() {
///
/// Setup our config.
///
/// @note:
/// We don't set any config options in this sample but you could set your own options here.
///
Config config;
///
/// Pass our configuration to the Platform singleton so that the library can use it.
///
/// The Platform singleton can be used to define various platform-specific properties and
/// handlers such as file system access, font loaders, and the gpu driver.
///
Platform::instance().set_config(config);
///
/// We must provide our own Platform API handlers since we're not using App::Create().
///
/// The Platform API handlers we can set are:
///
/// - Platform::set_logger (empty, optional)
/// - Platform::set_gpu_driver (empty, optional)
/// - Platform::set_font_loader (empty, **required**)
/// - Platform::set_file_system (empty, **required**)
/// - Platform::set_clipboard (empty, optional)
/// - Platform::set_surface_factory (defaults to BitmapSurfaceFactory, **required**)
///
/// The only Platform API handlers we are required to provide are file system and font loader.
///
/// In this sample we will use AppCore's font loader and file system via
/// GetPlatformFontLoader() and GetPlatformFileSystem() respectively.
///
/// You can replace these with your own implementations later.
///
Platform::instance().set_font_loader(GetPlatformFontLoader());
///
/// Use AppCore's file system singleton to load file:/// URLs from the OS.
///
/// You could replace this with your own to provide your own file loader (useful if you need to
/// bundle encrypted / compressed HTML assets).
///
Platform::instance().set_file_system(GetPlatformFileSystem("./assets/"));
///
/// Register our MyApp instance as a logger so we can handle the library's LogMessage() event
/// below in case we encounter an error.
///
Platform::instance().set_logger(this);
///
/// Create our Renderer (you should only create this once per application).
///
/// The Renderer singleton maintains the lifetime of the library and is required before
/// creating any Views. It should outlive any Views.
///
/// You should set up the Platform singleton before creating this.
///
renderer_ = Renderer::Create();
///
/// Create our View.
///
/// Views are sized containers for loading and displaying web content.
///
/// Let's set a 2x DPI scale and disable GPU acceleration so we can render to a bitmap.
///
ViewConfig view_config;
view_config.initial_device_scale = 2.0;
view_config.is_accelerated = false;
view_ = renderer_->CreateView(1600, 800, view_config, nullptr);
///
/// Register our MyApp instance as a LoadListener so we can handle the View's OnFinishLoading
/// event below.
///
view_->set_load_listener(this);
///
/// Load a local HTML file into the View (uses the file system defined above).
///
/// @note:
/// This operation may not complete immediately-- we will call Renderer::Update continuously
/// and wait for the OnFinishLoading event before rendering our View.
///
/// Views can also load remote URLs, try replacing the code below with:
///
/// view_->LoadURL("https://en.wikipedia.org");
///
view_->LoadURL("file:///page.html");
}
virtual ~MyApp() {
view_ = nullptr;
renderer_ = nullptr;
}
void Run() {
LogMessage(LogLevel::Info, "Starting Run(), waiting for page to load...");
///
/// Continuously update until OnFinishLoading() is called below (which sets done = true).
///
/// @note:
/// Calling Renderer::Update handles any pending network requests, resource loads, and
/// JavaScript timers.
///
do {
renderer_->Update();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
} while (!done_);
///
/// Render our View.
///
/// @note:
/// Calling Renderer::Render will render any dirty Views to their respective Surfaces.
///
renderer_->RefreshDisplay(0);
renderer_->Render();
///
/// Get our View's rendering surface and cast it to BitmapSurface.
///
/// BitmapSurface is the default Surface implementation, you can provide your own via
/// Platform::set_surface_factory.
///
BitmapSurface* bitmap_surface = (BitmapSurface*)view_->surface();
///
/// Get the underlying bitmap.
///
RefPtr<Bitmap> bitmap = bitmap_surface->bitmap();
///
/// Write our bitmap to a PNG in the current working directory.
///
bitmap->WritePNG("result.png");
LogMessage(LogLevel::Info, "Saved a render of our page to result.png.");
}
///
/// Inherited from LoadListener, this is called when a View finishes loading a page into a frame.
///
virtual void OnFinishLoading(ultralight::View* caller, uint64_t frame_id, bool is_main_frame,
const String& url) override {
///
/// Our page is done when the main frame finishes loading.
///
if (is_main_frame) {
LogMessage(LogLevel::Info, "Our page has loaded!");
///
/// Set our done flag to true to exit the Run loop.
///
done_ = true;
}
}
///
/// Inherited from Logger, this is called when the library wants to print a message to the log.
///
virtual void LogMessage(LogLevel log_level, const String& message) override {
std::cout << "> " << message.utf8().data() << std::endl << std::endl;
}
};
int main() {
MyApp app;
app.Run();
return 0;
}