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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 0 additions & 109 deletions .github/.copilot-instructions.md

This file was deleted.

5 changes: 5 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
<!--
SPDX-FileCopyrightText: 2026 Kushview, LLC
SPDX-License-Identifier: ISC
-->

# Copilot Instructions for LUI Project

## General Guidelines
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ jobs:
- os: macos-latest
arch: arm64
cmake_arch: arm64
# - os: ubuntu-latest
# arch: x64
- os: ubuntu-latest
arch: x64
# - os: windows-latest
# arch: x64

Expand All @@ -41,9 +41,10 @@ jobs:
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y libx11-dev libgl1-mesa-dev ninja-build cmake \
sudo apt-get install -y libx11-dev libxcursor-dev libxext-dev libxrandr-dev \
libgl1-mesa-dev libepoxy-dev libcairo2-dev ninja-build cmake \
doxygen graphviz python3-sphinx python3-sphinx-rtd-theme

- name: Configure CMake (macOS)
if: runner.os == 'macOS'
run: |
Expand Down
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ include(GNUInstallDirs)

include(cmake/SetupCairo.cmake)

# Find libepoxy for GL backend (Linux/cross-platform)
if(UNIX AND NOT APPLE)
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(LIBEPOXY epoxy)
endif()
# Find X11 and related libraries for Pugl
find_package(X11 REQUIRED)
endif()

# Python 3 for scripts
find_package(Python3 REQUIRED COMPONENTS Interpreter)

Expand Down
8 changes: 4 additions & 4 deletions include/lui/path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class Path {

/** Copy a path */
Path (const Path& o) { operator= (o); }
constexpr Path& operator= (const Path& o) {
Path& operator= (const Path& o) {
std::copy (o._data.begin(), o._data.end(), _data.begin());
return *this;
}
Expand All @@ -69,7 +69,7 @@ class Path {
}

/** Clear the path */
constexpr void clear() noexcept { _data.clear(); }
void clear() noexcept { _data.clear(); }

void begin_path() {
clear();
Expand Down Expand Up @@ -177,9 +177,9 @@ class Path {
/** End iter */
auto end() const noexcept { return iterator (_data.cend()); }
/** Raw data vector */
constexpr const auto& data() const noexcept { return _data; }
const auto& data() const noexcept { return _data; }
/** Reserve amount of bytes */
constexpr void reserve (std::size_t n) { _data.reserve (_data.size() + n); }
void reserve (std::size_t n) { _data.reserve (_data.size() + n); }

void add_ellipse (float x, float y, float width, float height) noexcept {
auto hw = width * 0.5f;
Expand Down
28 changes: 28 additions & 0 deletions include/lui/string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
#include <cctype>
#include <cstdint>
#include <cstring>

#if __has_include(<format>)
#include <format>
#endif

#include <string>

namespace lui {
Expand Down Expand Up @@ -132,22 +136,42 @@ class String final {

/** Append an int */
String& append (int i) {
#if __has_include(<format>)
return append_formatted ("{}", i);
#else
_str.append (std::to_string (i));
return *this;
#endif
}

/** Append an int64 */
String& append (int64_t i) {
#if __has_include(<format>)
return append_formatted ("{}", i);
#else
_str.append (std::to_string (i));
return *this;
#endif
}

/** Append a float */
String& append (float i) {
#if __has_include(<format>)
return append_formatted ("{}", i);
#else
_str.append (std::to_string (i));
return *this;
#endif
}

/** Append a double */
String& append (double i) {
#if __has_include(<format>)
return append_formatted ("{}", i);
#else
_str.append (std::to_string (i));
return *this;
#endif
}

/** Append formatted output using C++20 std::format.
Expand All @@ -157,11 +181,13 @@ class String final {

Example: str.append_formatted("Value: {}", 42);
*/
#if __has_include(<format>)
template <typename... Args>
String& append_formatted (std::format_string<Args...> fmt, Args&&... args) {
_str.append (std::format (fmt, std::forward<Args> (args)...));
return *this;
}
#endif

/** Create a new formatted String using C++20 std::format.
@param fmt Format string (e.g., "{} items: {:.2f}")
Expand All @@ -170,10 +196,12 @@ class String final {

Example: auto msg = String::formatted("{} + {} = {}", 1, 2, 3);
*/
#if __has_include(<format>)
template <typename... Args>
static String formatted (std::format_string<Args...> fmt, Args&&... args) {
return String (std::format (fmt, std::forward<Args> (args)...));
}
#endif

/** Return substring by byte position and length.
Warning: Does not validate UTF-8 boundaries. Use with caution.
Expand Down
48 changes: 41 additions & 7 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ if(APPLE)
COMPILE_FLAGS "-Wno-deprecated")
elseif(UNIX AND NOT APPLE)
list(APPEND LIBLUI_SOURCES
embed_x11.cpp)
embed_x11.cpp
pugl/src/x11.c)
elseif(WIN32)
list(APPEND LIBLUI_SOURCES
embed_win32.cpp)
Expand Down Expand Up @@ -92,6 +93,21 @@ target_link_directories(lui-${LUI_ABI_VERSION} PRIVATE)
target_link_libraries(lui-${LUI_ABI_VERSION}
PRIVATE Threads::Threads)

# X11 support for Linux
if(UNIX AND NOT APPLE)
target_compile_options(lui-${LUI_ABI_VERSION} PRIVATE -fPIC)
target_link_libraries(lui-${LUI_ABI_VERSION}
PRIVATE
X11::X11
X11::Xcursor
X11::Xext
X11::Xrandr)
# Xsync is optional, may not be available on all systems
if(TARGET X11::Xsync)
target_link_libraries(lui-${LUI_ABI_VERSION} PRIVATE X11::Xsync)
endif()
endif()

# Apple frameworks
if(APPLE)
target_link_libraries(lui-${LUI_ABI_VERSION}
Expand Down Expand Up @@ -145,6 +161,10 @@ function(lui_add_backend tgt)

target_link_libraries(${tgt} PUBLIC lui-${LUI_ABI_VERSION})

if(UNIX AND NOT APPLE)
target_compile_options(${tgt} PRIVATE -fPIC)
endif()

install(TARGETS ${tgt}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
Expand All @@ -165,14 +185,27 @@ if(APPLE)
pugl/src/mac_gl.m)
target_link_libraries(lui-gl-${LUI_ABI_VERSION}
PRIVATE "-framework OpenGL")
target_compile_definitions(lui-gl-${LUI_ABI_VERSION} PRIVATE NANOVG_GL2)
elseif(UNIX AND NOT APPLE)
# Linux: use libepoxy for OpenGL function loading
target_sources(lui-gl-${LUI_ABI_VERSION} PRIVATE
pugl/src/x11_gl.c)
if(LIBEPOXY_FOUND)
target_link_libraries(lui-gl-${LUI_ABI_VERSION}
PRIVATE ${LIBEPOXY_LIBRARIES} GL X11)
target_include_directories(lui-gl-${LUI_ABI_VERSION}
PRIVATE ${LIBEPOXY_INCLUDE_DIRS})
target_compile_definitions(lui-gl-${LUI_ABI_VERSION} PRIVATE NANOVG_GL3)
else()
message(FATAL_ERROR "libepoxy not found - required for OpenGL backend on Linux")
endif()
endif()

lui_add_backend(lui-gl-${LUI_ABI_VERSION})
target_include_directories(lui-gl-${LUI_ABI_VERSION}
PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/nanovg)
target_compile_definitions(lui-gl-${LUI_ABI_VERSION} PRIVATE NANOVG_GL2)

# Generate and install pkg-config file for OpenGL backend
configure_file(
Expand All @@ -187,8 +220,7 @@ install(FILES ${CMAKE_BINARY_DIR}/lui-gl-${LUI_ABI_VERSION}.pc
# Cairo Backend
if(CAIRO_FOUND)
add_library(lui-cairo-${LUI_ABI_VERSION}
cairo.cpp
pugl/src/mac_cairo.m)
cairo.cpp)

lui_add_backend(lui-cairo-${LUI_ABI_VERSION})

Expand All @@ -203,13 +235,15 @@ if(CAIRO_FOUND)

# Platform-specific Cairo libraries
if(APPLE)
target_sources(lui-cairo-${LUI_ABI_VERSION} PRIVATE pugl/src/mac_cairo.m)
target_link_libraries(lui-cairo-${LUI_ABI_VERSION} PRIVATE
"-framework CoreGraphics"
)
elseif(UNIX AND NOT APPLE)
target_sources(lui-cairo-${LUI_ABI_VERSION} PRIVATE pugl/src/x11_cairo.c)
elseif(WIN32)
target_link_libraries(lui-cairo-${LUI_ABI_VERSION} PRIVATE
gdi32
)
target_sources(lui-cairo-${LUI_ABI_VERSION} PRIVATE pugl/src/win_cairo.c)
target_link_libraries(lui-cairo-${LUI_ABI_VERSION} PRIVATE gdi32)
endif()

message(STATUS "Cairo backend enabled - building lui-cairo-${LUI_ABI_VERSION}")
Expand Down
1 change: 1 addition & 0 deletions src/cairo.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2024 Michael Fisher <mfisher@lvtk.org>
// SPDX-License-Identifier: ISC

#include <cassert>
#include <iostream>

#if _MSC_VER
Expand Down
2 changes: 2 additions & 0 deletions src/gl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# undef NOMINMAX
# endif
# define NOMINMAX
#elif __linux__
# include <epoxy/gl.h>
#endif

#define PUGL_DISABLE_DEPRECATED
Expand Down
2 changes: 1 addition & 1 deletion src/nanovg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ void Context::draw_image (Image i, Transform matrix) {
handle = nvgCreateImageRGBA (ctx->ctx,
i.width(),
i.height(),
NVG_IMAGE_PREMULTIPLIED | NVG_IMAGE_NODELETE,
(int) NVG_IMAGE_PREMULTIPLIED | (int) NVG_IMAGE_NODELETE,
i.data());

if (handle <= 0) {
Expand Down
Loading
Loading