diff options
| author | Oskari Timperi <oskari.timperi@iki.fi> | 2017-04-09 17:43:43 +0300 |
|---|---|---|
| committer | Oskari Timperi <oskari.timperi@iki.fi> | 2017-04-09 17:43:43 +0300 |
| commit | 6babc4110ebb377ff74d7a2db6d02fc559cf9b1a (patch) | |
| tree | 26cfb6b5dce80b1dda24b2af0e8cf1719d8b17de | |
| download | mkpdf-6babc4110ebb377ff74d7a2db6d02fc559cf9b1a.tar.gz mkpdf-6babc4110ebb377ff74d7a2db6d02fc559cf9b1a.zip | |
Initial commit
| -rw-r--r-- | CMakeLists.txt | 16 | ||||
| -rw-r--r-- | lib/CMakeLists.txt | 25 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 18 | ||||
| -rw-r--r-- | src/bin2c.c | 66 | ||||
| -rw-r--r-- | src/main.c | 43 | ||||
| -rw-r--r-- | src/mkpdf.lua | 182 |
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 |
