summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOskari Timperi <oskari.timperi@iki.fi>2017-04-09 17:43:43 +0300
committerOskari Timperi <oskari.timperi@iki.fi>2017-04-09 17:43:43 +0300
commit6babc4110ebb377ff74d7a2db6d02fc559cf9b1a (patch)
tree26cfb6b5dce80b1dda24b2af0e8cf1719d8b17de
downloadmkpdf-6babc4110ebb377ff74d7a2db6d02fc559cf9b1a.tar.gz
mkpdf-6babc4110ebb377ff74d7a2db6d02fc559cf9b1a.zip
Initial commit
-rw-r--r--CMakeLists.txt16
-rw-r--r--lib/CMakeLists.txt25
-rw-r--r--src/CMakeLists.txt18
-rw-r--r--src/bin2c.c66
-rw-r--r--src/main.c43
-rw-r--r--src/mkpdf.lua182
6 files changed, 350 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..50d69e4
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,16 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
+PROJECT(mkpdf C)
+
+IF(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/lib/stage)
+ FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib/build)
+ EXECUTE_PROCESS(
+ COMMAND ${CMAKE_COMMAND} ..
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib/build
+ )
+ EXECUTE_PROCESS(
+ COMMAND ${CMAKE_COMMAND} --build .
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib/build
+ )
+ENDIF()
+
+ADD_SUBDIRECTORY(src)
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
new file mode 100644
index 0000000..8cb172a
--- /dev/null
+++ b/lib/CMakeLists.txt
@@ -0,0 +1,25 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
+PROJECT(lib)
+
+INCLUDE(ExternalProject)
+
+ExternalProject_Add(lua
+ URL https://www.lua.org/ftp/lua-5.3.4.tar.gz
+ URL_HASH SHA1=79790cfd40e09ba796b01a571d4d63b52b1cd950
+ PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/lua.cmake <SOURCE_DIR>/CMakeLists.txt
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/stage
+)
+
+ExternalProject_Add(libharu
+ GIT_REPOSITORY https://github.com/libharu/libharu.git
+ GIT_TAG d84867ebf9f3de6afd661d2cdaff102457fbc371
+ CMAKE_ARGS -DLIBHPDF_SHARED=OFF -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/stage
+)
+
+ExternalProject_Add(luahpdf
+ GIT_REPOSITORY https://github.com/jung-kurt/luahpdf.git
+ GIT_TAG d8c93345d87a96135739017566d98b02774f558a
+ DEPENDS lua libharu
+ PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/luahpdf.cmake <SOURCE_DIR>/CMakeLists.txt
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/stage
+)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..2fa12b5
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,18 @@
+FIND_LIBRARY(hpdfs hpdfs PATHS ${PROJECT_SOURCE_DIR}/lib/stage/lib)
+FIND_LIBRARY(lua lua PATHS ${PROJECT_SOURCE_DIR}/lib/stage/lib)
+FIND_LIBRARY(luahpdf luahpdf PATHS ${PROJECT_SOURCE_DIR}/lib/stage/lib)
+FIND_LIBRARY(z z)
+FIND_LIBRARY(png png)
+
+ADD_EXECUTABLE(bin2c bin2c.c)
+
+ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mkpdf.lua.c
+ COMMAND bin2c ${CMAKE_CURRENT_SOURCE_DIR}/mkpdf.lua ${CMAKE_CURRENT_BINARY_DIR}/mkpdf.lua.c
+ DEPENDS mkpdf.lua
+)
+
+ADD_EXECUTABLE(mkpdf main.c ${CMAKE_CURRENT_BINARY_DIR}/mkpdf.lua.c)
+
+TARGET_LINK_LIBRARIES(mkpdf PRIVATE ${luahpdf} ${lua} ${hpdfs} ${z} ${png} m)
+
+TARGET_INCLUDE_DIRECTORIES(mkpdf PRIVATE ${PROJECT_SOURCE_DIR}/lib/stage/include)
diff --git a/src/bin2c.c b/src/bin2c.c
new file mode 100644
index 0000000..c86b238
--- /dev/null
+++ b/src/bin2c.c
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+
+static char *id(const char *s)
+{
+ char *r;
+ char *b = (char *) strrchr(s, '/');
+ if (!b)
+ b = (char *) strrchr(s, '\\');
+ if (!b)
+ b = (char *) s;
+ else
+ ++b;
+ b = strdup(b);
+ r = b;
+ while (*r)
+ {
+ if (!isalnum(*r))
+ {
+ *r = '_';
+ }
+ ++r;
+ }
+ if (!isalpha(*b))
+ {
+ *b = '_';
+ }
+ return b;
+}
+
+int main(int argc, char** argv) {
+ assert(argc >= 2);
+
+ char* fn = argv[1];
+
+ char *outfn = NULL;
+ if (argc > 2)
+ outfn = argv[2];
+
+ char *varname = id(fn);
+
+ FILE* f = fopen(fn, "r");
+ FILE *fout;
+
+ if (!outfn)
+ fout = stdout;
+ else
+ fout = fopen(outfn, "w");
+
+ fprintf(fout, "const char %s[] = {\n", varname);
+ unsigned long n = 0;
+ while(!feof(f)) {
+ unsigned char c;
+ if(fread(&c, 1, 1, f) == 0) break;
+ fprintf(fout, "%s0x%.2X", (n > 0) ? "," : "", (int)c);
+ ++n;
+ if(n % 10 == 0) fprintf(fout, "\n");
+ }
+ fprintf(fout, ",0x00};\n");
+ fprintf(fout, "const unsigned long %s_size = %lu;\n", varname, n);
+
+ fclose(fout);
+ fclose(f);
+}
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..7b3bd26
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+int luaopen_hpdf(lua_State *L);
+
+extern const char mkpdf_lua[];
+extern const unsigned long mkpdf_lua_size;
+
+int main(int argc, char **argv)
+{
+ lua_State *L;
+ int rc = 0;
+
+ L = luaL_newstate();
+
+ luaL_openlibs(L);
+
+ lua_getglobal(L, "package");
+ lua_getfield(L, -1, "preload");
+ lua_pushcfunction(L, luaopen_hpdf);
+ lua_setfield(L, -2, "hpdf");
+ lua_pop(L, 2);
+
+ if (luaL_dostring(L, mkpdf_lua))
+ {
+ fprintf(stderr, "%s\n", lua_tostring(L, -1));
+ rc = 1;
+ }
+
+ if (luaL_dofile(L, argv[1]))
+ {
+ fprintf(stderr, "%s\n", lua_tostring(L, -1));
+ rc = 1;
+ }
+
+ lua_close(L);
+
+ return rc;
+}
diff --git a/src/mkpdf.lua b/src/mkpdf.lua
new file mode 100644
index 0000000..244f1b7
--- /dev/null
+++ b/src/mkpdf.lua
@@ -0,0 +1,182 @@
+hpdf = require("hpdf")
+
+mm = function(mm)
+ return mm * (72.0 / 25.4)
+end
+
+inch = function(inch)
+ return inch * 72.0
+end
+
+Document = {}
+
+function Document:New()
+ local o = {
+ _inst = hpdf.New()
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function Document:SetCompressionMode(mode)
+ local modes = {
+ all = hpdf.COMP_ALL,
+ none = hpdf.COMP_NONE,
+ text = hpdf.COMP_TEXT,
+ image = hpdf.COMP_IMAGE,
+ metadata = hpdf.COMP_METADATA,
+ all = hpdf.COMP_ALL,
+ mask = hpdf.COMP_MASK,
+ }
+ hpdf.SetCompressionMode(self._inst, modes[mode])
+end
+
+function Document:UseUTFEncodings()
+ hpdf.UseUTFEncodings(self._inst)
+end
+
+function Document:GetFont(name, encoding)
+ return hpdf.GetFont(self._inst, name, encoding)
+end
+
+function Document:LoadTTFontFromFile(filename, embed, encoding)
+ local name = hpdf.LoadTTFontFromFile(self._inst, filename, embed)
+ return self:GetFont(name, encoding)
+end
+
+function Document:Save(filename)
+ hpdf.SaveToFile(self._inst, filename)
+end
+
+function Document:AddPage()
+ return Page:New(self)
+end
+
+Page = {}
+
+function Page:New(doc)
+ local o = {
+ _inst = hpdf.AddPage(doc._inst),
+ default_line_width = mm(0.2),
+ margin = mm(10)
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function Page:SetSize(size, ori)
+ local sizes = {
+ A4 = "HPDF_PAGE_SIZE_A4",
+ }
+ local orientations = {
+ portrait = "HPDF_PAGE_PORTRAIT",
+ landscape = "HPDF_PAGE_LANDSCAPE",
+ }
+ hpdf.Page_SetSize(self._inst, sizes[size], orientations[ori])
+end
+
+function Page:BeginText()
+ hpdf.Page_BeginText(self._inst)
+end
+
+function Page:EndText()
+ hpdf.Page_EndText(self._inst)
+end
+
+function Page:TextRect(left, top, right, bottom, text, align)
+ local aligns = {
+ left = "HPDF_TALIGN_LEFT",
+ right = "HPDF_TALIGN_RIGHT",
+ center = "HPDF_TALIGN_CENTER",
+ justify = "HPDF_TALIGN_JUSTIFY",
+ }
+ hpdf.Page_TextRect(self._inst, left, top, right, bottom, text,
+ aligns[align])
+end
+
+function Page:SetFontAndSize(font, size)
+ hpdf.Page_SetFontAndSize(self._inst, font, size)
+end
+
+function Page:SetLineWidth(width)
+ hpdf.Page_SetLineWidth(self._inst, width)
+end
+
+function Page:MoveTo(x, y)
+ hpdf.Page_MoveTo(self._inst, x, y)
+end
+
+function Page:LineTo(x, y)
+ hpdf.Page_LineTo(self._inst, x, y)
+end
+
+function Page:Stroke()
+ hpdf.Page_Stroke(self._inst)
+end
+
+function Page:Line(x1, y1, x2, y2, width)
+ width = width or self.default_line_width
+ self:SetLineWidth(width)
+ self:MoveTo(x1, y1)
+ self:LineTo(x2, y2)
+ self:Stroke()
+end
+
+function Page:GetWidth()
+ return hpdf.Page_GetWidth(self._inst)
+end
+
+function Page:GetHeight()
+ return hpdf.Page_GetHeight(self._inst)
+end
+
+function Page:GetContentWidth()
+ return self:GetWidth() - self.margin * 2
+end
+
+function Page:GetContentHeight()
+ return self:GetHeight() - self.margin * 2
+end
+
+function Page:SetMargin(margin)
+ self.margin = margin
+end
+
+function Page:GetMargin()
+ return self.margin
+end
+
+function Page:CreateGrid(columns, rows)
+ self.columns = columns
+ self.column_width = self:GetContentWidth() / columns
+
+ self.rows = rows
+ self.row_height = self:GetContentHeight() / rows
+end
+
+function Page:DrawGrid()
+ local left = self:GetMargin()
+ local top = self:GetHeight() - self:GetMargin()
+ local right = self:GetWidth() - self:GetMargin()
+ local bottom = self:GetMargin()
+
+ for col = 0, self.columns do
+ local x = left + col * self.column_width
+ self:Line(x, top, x, bottom)
+ end
+
+ for row = 0, self.rows do
+ local y = top - row * self.row_height
+ self:Line(left, y, right, y)
+ end
+end
+
+function Page:TextCell(column, row, colspan, rowspan, text, align)
+ local left = self:GetMargin() + column * self.column_width
+ local top = self:GetHeight() - self:GetMargin() - row * self.row_height
+ local right = left + colspan * self.column_width
+ local bottom = top - rowspan * self.row_height
+ self:TextRect(left, top, right, bottom, text, align)
+end