diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a1aa3b..3a29308 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,9 +19,10 @@ add_subdirectory(external/raylib-cpp-4.5.1) add_subdirectory(external/utfcpp-3.2.5) -add_executable(browser src/main.cpp src/fetch.cpp +add_executable(browser src/main.cpp + src/fetch.cpp src/html_parse.cpp - src/utf8.hpp) + src/html_render.cpp) target_include_directories(browser PRIVATE external/raygui-4.0/src) diff --git a/data/tests/html.html b/data/tests/html.html new file mode 100644 index 0000000..91d040a --- /dev/null +++ b/data/tests/html.html @@ -0,0 +1,7 @@ + + + + + Hello World! + + \ No newline at end of file diff --git a/src/html_render.cpp b/src/html_render.cpp new file mode 100644 index 0000000..da8eca7 --- /dev/null +++ b/src/html_render.cpp @@ -0,0 +1,31 @@ +#include "html_render.hpp" +#include + +namespace html { + +void render_doc(const NodeDoc& doc, Bounds bounds, const raylib::Font& font) +{ + for (const std::variant& child : doc.children) { + if (const NodeElem* elem = std::get_if(&child)) { + render_elem(*elem, bounds, font); + } + } +} + +void render_elem(const NodeElem& elem, Bounds bounds, const raylib::Font& font) +{ + if (const NodeElemReg* reg = std::get_if(&elem.var)) { + Utf8String inner_str; + for (const std::variant& inner : reg->inner) { + if (const Utf8String* str = std::get_if(&inner)) { + inner_str += *str; + } + else if (const NodeElem* inner_elem = std::get_if(&inner)) { + render_elem(*inner_elem, bounds, font); + } + } + DrawTextEx(font, inner_str.str(), { (float)bounds.left, (float)bounds.right }, 24, 1.0f, BLACK); + } +} + +} diff --git a/src/html_render.hpp b/src/html_render.hpp new file mode 100644 index 0000000..7ddb78d --- /dev/null +++ b/src/html_render.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include + +#include + +#include "html_parse.hpp" + +enum class BoundHintRel { shrink, grow }; + +using BoundHint = std::variant; + +namespace html { + +struct BoundHints { + BoundHint left; + BoundHint right; + BoundHint top; + BoundHint bottom; +}; + +struct Bounds { + int left; + int right; + int top; + int bottom; +}; + +void render_doc(const NodeDoc& doc, Bounds bounds, const raylib::Font& font); +void render_elem(const NodeElem& elem, Bounds bounds, const raylib::Font& font); + +} diff --git a/src/main.cpp b/src/main.cpp index b8e0c50..4e00e63 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,12 +8,13 @@ #include #include "html_parse.hpp" +#include "html_render.hpp" int main() { init_curl(); - std::optional page_data = fetch_url("test://text.html"); + std::optional page_data = fetch_url("test://html.html"); // std::optional page_data = fetch_url("https://example.com"); SetConfigFlags(ConfigFlags::FLAG_WINDOW_RESIZABLE | ConfigFlags::FLAG_MSAA_4X_HINT | ConfigFlags ::FLAG_VSYNC_HINT); @@ -28,10 +29,11 @@ int main() bool is_editing_url = false; // std::string url_input = "https://example.com"; - std::string url_input = "test://text.html"; + std::string url_input = "test://html.html"; url_input.reserve(1024); float scroll_pos = 0.0f; + std::optional doc; if (page_data.has_value()) { html::Tokenizer tokenizer(page_data.value()); std::vector tokens = tokenizer.tokenize(); @@ -39,7 +41,7 @@ int main() // std::cout << token.to_string() << std::endl; // } html::Parser parser(std::move(tokens)); - html::NodeDoc doc = parser.parse(); + doc = parser.parse(); std::cout << "HERE" << std::endl; } @@ -61,8 +63,9 @@ int main() scroll_pos += GetMouseWheelMove(); - if (page_data.has_value()) { - DrawTextEx(sans_font, page_data.value(), { 0, 20 + scroll_pos * 40 }, 24, 1.0f, BLACK); + if (doc.has_value()) { + html::render_doc(doc.value(), { 0, 20, GetScreenWidth(), GetScreenHeight() - 20 }, sans_font); + // DrawTextEx(sans_font, page_data.value(), { 0, 20 + scroll_pos * 40 }, 24, 1.0f, BLACK); } EndDrawing(); diff --git a/src/utf8.hpp b/src/utf8.hpp index bcc3fb6..8020af8 100644 --- a/src/utf8.hpp +++ b/src/utf8.hpp @@ -86,6 +86,11 @@ public: using Iterator = utf8::iterator; using ConstIterator = utf8::iterator; + inline Utf8String() + : m_str() + { + } + explicit inline Utf8String(std::string str) : m_str(std::move(str)) { @@ -114,11 +119,22 @@ public: return ConstIterator(m_str.end(), m_str.begin(), m_str.end()); } + [[nodiscard]] const std::string& str() const + { + return m_str; + } + bool operator==(const Utf8String& other) const { return m_str == other.m_str; } + Utf8String& operator+=(const Utf8String& other) + { + m_str += other.m_str; + return *this; + } + uint32_t operator[](size_t index) { auto it = begin();