summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--markdown.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/markdown.cpp b/markdown.cpp
index e8b4e71..6c94a97 100644
--- a/markdown.cpp
+++ b/markdown.cpp
@@ -11,6 +11,7 @@
#include <string>
#include <string_view>
#include <thread>
+#include <unordered_map>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
@@ -20,11 +21,23 @@
#include <imgui_impl_opengl3.h>
#include <imgui_md.h>
+#define STB_IMAGE_IMPLEMENTATION
+#include <stb_image.h>
+
std::string g_base_address;
ImFont * g_font_regular;
ImFont * g_font_bold;
ImFont * g_font_bold_large;
+struct Image
+{
+ ImTextureID m_texture_id;
+ int m_width;
+ int m_height;
+};
+
+std::unordered_map<std::string, Image> g_images;
+
static std::string get(const std::string & command)
{
std::string result;
@@ -65,6 +78,31 @@ static std::string expand_url(const std::string & href)
}
}
+static bool load_image(const std::string & filename, Image & image)
+{
+ unsigned char * data = stbi_load(filename.c_str(), &image.m_width, &image.m_height, nullptr, 4);
+ if (nullptr == data)
+ return false;
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+#if defined(GL_UNPACK_ROW_LENGTH)
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+#endif
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.m_width, image.m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+ stbi_image_free(data);
+ image.m_texture_id = reinterpret_cast<ImTextureID>(texture);
+
+ return true;
+}
+
struct Markdown : public imgui_md
{
ImFont * get_font() const override
@@ -91,6 +129,32 @@ struct Markdown : public imgui_md
std::thread t(std::move(task), command);
t.detach();
}
+
+ bool get_image(image_info & nfo) const override
+ {
+ auto search = g_images.find(m_href);
+ if (g_images.end() == search)
+ {
+ std::string command = "phttp " + expand_url(m_href);
+ std::packaged_task<std::string (const std::string &)> task(get);
+ auto future = task.get_future();
+ std::thread t(std::move(task), command);
+ t.detach();
+ const auto result = future.get();
+ auto n = result.find(" ");
+ n = result.find(" ", n + 1);
+ const auto filename = result.substr(n + 1, result.size() - n - 2);
+ if (!load_image(filename, g_images[m_href]))
+ throw std::runtime_error("could not load image");
+ }
+ nfo.texture_id = g_images[m_href].m_texture_id;
+ nfo.size = {g_images[m_href].m_width, g_images[m_href].m_height};
+ nfo.uv0 = {0, 0};
+ nfo.uv1 = {1, 1};
+ nfo.col_tint = {1, 1, 1, 1};
+ nfo.col_border = {0, 0, 0, 0};
+ return true;
+ }
};
static void glfw_error_callback(int error, const char * description)