diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..e8f0748 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,23 @@ +uahgi2 + +MIT License + +Copyright (c) 2025 chenjt30 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..62522dc --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +uahgi2 +====== +README text here. + +## Dependencies + - Racket 8.10 + - fontconfig (for its `fc-match`) diff --git a/fonts/LICENSE b/fonts/LICENSE new file mode 100644 index 0000000..c948db2 --- /dev/null +++ b/fonts/LICENSE @@ -0,0 +1,5 @@ +NotoSerifCJKtc-VF.ttf and NotoSansCJKtc-VF.ttf are under +under Open Font License https://openfontlicense.org/ +from https://github.com/notofonts/ + + diff --git a/fonts/NotoSansCJKtc-VF.ttf b/fonts/NotoSansCJKtc-VF.ttf new file mode 100644 index 0000000..d79f331 Binary files /dev/null and b/fonts/NotoSansCJKtc-VF.ttf differ diff --git a/fonts/NotoSerifCJKtc-VF.ttf b/fonts/NotoSerifCJKtc-VF.ttf new file mode 100644 index 0000000..827c0d2 Binary files /dev/null and b/fonts/NotoSerifCJKtc-VF.ttf differ diff --git a/info.rkt b/info.rkt new file mode 100644 index 0000000..9824c5e --- /dev/null +++ b/info.rkt @@ -0,0 +1,9 @@ +#lang info +(define collection "uahgi2") +(define deps '("base")) +(define build-deps '("scribble-lib" "racket-doc" "rackunit-lib")) +(define scribblings '(("scribblings/uahgi2.scrbl" ()))) +(define pkg-desc "Description Here") +(define version "0.0") +(define pkg-authors '(chenjt30)) +(define license '(Apache-2.0 OR MIT)) diff --git a/lexer-test.rkt b/lexer-test.rkt index 34bfaaa..26b6cb6 100644 --- a/lexer-test.rkt +++ b/lexer-test.rkt @@ -2,7 +2,8 @@ (require "lexer.rkt" brag/support rackunit) (define (lex str) - (apply-port-proc basic-lexer str)) + (apply-port-proc uahgi2-lexer str)) (lex "@a123") -(lex "{@_a12|foo|123.12}123abc\\@\\{mn̂g他@@愛@@貓,也愛這塊土地%註解%。這也是%%。") \ No newline at end of file +(lex "{@_a12|foo|123.12}123abc\\@\\{mn̂g他@@愛@@貓,也愛這塊土地%註解%。這也是%%。") +(lex "|測試}abc") \ No newline at end of file diff --git a/lexer.rkt b/lexer.rkt index c587cf2..4958d0b 100644 --- a/lexer.rkt +++ b/lexer.rkt @@ -5,7 +5,7 @@ (define-lex-abbrev raw-id (:: (:or "_" (:/ "a" "z") (:/ "A" "Z")) (:* (:or "_" (:/ "0" "9") (:/ "a" "z") (:/ "A" "Z"))))) (define-lex-abbrev any-other-char (:~ (char-set "0123456789@\\{}%|"))) -(define basic-lexer +(define uahgi2-lexer (lexer-srcloc [(:or "\r\n" "\n") (token 'NEWLINE lexeme)] ; newline [whitespace (token lexeme #:skip? #t)] ; whitespace @@ -17,10 +17,11 @@ ["}" (token 'R_PAREN lexeme)] ; } ["|" (token 'SEPERATOR lexeme)] ; | (general) seperator ["@@" (token 'G_SEPERATOR lexeme)] ; @@ great seperator + ["`" (token 'NUM_CONVERTER lexeme)] ; ` convert to number [digits (token 'INTEGER (string->number lexeme))] ;123 [(:: (:? (char-set "-")) digits "." digits) ; 123.456 (token 'DECIMAL (string->number lexeme))] [ (from/to "%" "%") ; %COMMENT% (token 'COMMENT #:skip? #t)] [any-other-char (token 'CHAR lexeme)])) ; any char into char -(provide basic-lexer) \ No newline at end of file +(provide uahgi2-lexer) \ No newline at end of file diff --git a/parser-test.rkt b/parser-test.rkt new file mode 100644 index 0000000..ff6205a --- /dev/null +++ b/parser-test.rkt @@ -0,0 +1,13 @@ +#lang br +(require uahgi2/parser uahgi2/tokenizer brag/support) +(define str #< _pointer))) + +;void +;hb_buffer_add_utf8 (hb_buffer_t *buffer, +; const char *text, +; int text_length, +; unsigned int item_offset, +; int item_length); +(define hb-buffer-add-utf8-raw + (get-ffi-obj "hb_buffer_add_utf8" libhb + (_fun _pointer _string/utf-8 _int _uint _int -> _void))) + +; not implemented for now. maybe implemented in the future. +; // If you know the direction, script, and language +; hb_buffer_set_direction(buf, HB_DIRECTION_LTR) +; hb_buffer_set_script(buf, HB_SCRIPT_LATIN); +; hb_buffer_set_language(buf, hb_language_from_string("en", -1)); + +;hb_blob_t * +;hb_blob_create_from_file (const char *file_name); +(define hb-blob-create-from-file-raw + (get-ffi-obj "hb_blob_create_from_file" libhb + (_fun _string/utf-8 -> _pointer))) + +;hb_face_t * +;hb_face_create (hb_blob_t *blob, +; unsigned int index); +(define hb-face-create-raw + (get-ffi-obj "hb_face_create" libhb + (_fun _pointer _uint -> _hb_face_t))) +; hb_font_t * +; hb_font_create (hb_face_t *face); +(define hb-font-create-raw + (get-ffi-obj "hb_font_create" libhb + (_fun _hb_face_t -> _hb_font_t))) +;void +;hb_shape (hb_font_t *font, +; hb_buffer_t *buffer, +; const hb_feature_t *features, +; unsigned int num_features); +(define hb-shape-raw + (get-ffi-obj "hb_shape" libhb + (_fun _hb_font_t _pointer _pointer _uint -> _void))) +;void +;hb_buffer_guess_segment_properties (hb_buffer_t *buffer) +(define hb-buffer-guess-segment-properties-raw + (get-ffi-obj "hb_buffer_guess_segment_properties" libhb + (_fun _pointer -> _void))) + +(define hb-buffer-get-glyph-infos-raw + (get-ffi-obj "hb_buffer_get_glyph_infos" libhb + (_fun + [buf : _pointer] + [glyph-length : (_ptr o _uint)] + -> [glyph-info : _pointer] + -> (values glyph-info glyph-length)))) + +(define hb-buffer-get-glyph-positions-raw + (get-ffi-obj "hb_buffer_get_glyph_positions" libhb + (_fun + [buf : _pointer] + [glyph-length : (_ptr o _uint)] + -> [glyph-position : _pointer] + -> (values glyph-position glyph-length)))) +(define hb-buffer-has-positions-raw + (get-ffi-obj "hb_buffer_has_positions" libhb + (_fun [buf : _pointer] -> _bool))) + +(define (create-hb-buffer) (hb-buffer-create-raw)) + + +; test area +(define buf (create-hb-buffer)) +(hb-buffer-add-utf8-raw buf "123abc" -1 0 -1) +(define font-path "/usr/share/fonts/truetype/freefont/FreeSansBold.ttf") +(define blob (hb-blob-create-from-file-raw font-path)) +(define NULL (cast 0 _int64 _pointer)) +(define face (hb-face-create-raw blob 0)) +(define font (hb-font-create-raw face)) +(hb-buffer-guess-segment-properties-raw buf) +(hb-shape-raw font buf NULL 0) +(define-values (glyph-info glyph-length) (hb-buffer-get-glyph-infos-raw buf)) +(define-values (glyph-pos glyph-length2) (hb-buffer-get-glyph-positions-raw buf)) + +(printf "has pos ?: ~a" (hb-buffer-has-positions-raw buf)) + + +(for ([i glyph-length]) + (displayln (hb_glyph_info_t-cluster (ptr-ref glyph-info _hb_glyph_info_t i)))) +(for ([i glyph-length2]) + (displayln (hb_glyph_position_t-x_advance (ptr-ref glyph-pos _hb_glyph_position_t i)))) diff --git a/unsafe/libharfbuzz.rkt-autorec.libharfbuzz b/unsafe/libharfbuzz.rkt-autorec.libharfbuzz new file mode 100644 index 0000000..74b5a9c Binary files /dev/null and b/unsafe/libharfbuzz.rkt-autorec.libharfbuzz differ diff --git a/unsafe/libharu.rkt b/unsafe/libharu.rkt new file mode 100644 index 0000000..4fde9f5 --- /dev/null +++ b/unsafe/libharu.rkt @@ -0,0 +1,83 @@ +#lang racket/base + +(require ffi/unsafe) + +(define libhpdf (ffi-lib "../3rdparty/libhpdf")) + +(define pdf-new-raw + (get-ffi-obj "HPDF_New" libhpdf + (_fun _int _int -> _pointer))) + +(define pdf-save-raw + (get-ffi-obj "HPDF_SaveToFile" libhpdf + (_fun _pointer _string/utf-8 -> _int))) + +(define pdf-free-raw + (get-ffi-obj "HPDF_Free" libhpdf + (_fun _pointer -> _void))) + +(define add-page-raw + (get-ffi-obj "HPDF_AddPage" libhpdf + (_fun _pointer -> _pointer))) + +(define load-ttf-raw + (get-ffi-obj "HPDF_LoadTTFontFromFile" libhpdf + (_fun _pointer _string/utf-8 _bool -> _string))) + +(define use-utf-encodingd-raw + (get-ffi-obj "HPDF_UseUTFEncodings" libhpdf + (_fun _pointer -> _int))) + +(define set-current-encoder-raw + (get-ffi-obj "HPDF_SetCurrentEncoder" libhpdf + (_fun _pointer _string -> _pointer))) + +(define get-font-raw + (get-ffi-obj "HPDF_GetFont" libhpdf + (_fun _pointer _string _string/utf-8 -> _pointer))) + +(define set-font-size-raw + (get-ffi-obj "HPDF_Page_SetFontAndSize" libhpdf + (_fun _pointer _pointer _float -> _pointer))) + +(define page-begin-text-raw + (get-ffi-obj "HPDF_Page_BeginText" libhpdf + (_fun _pointer -> _pointer))) + +(define page-text-out-raw + (get-ffi-obj "HPDF_Page_TextOut" libhpdf + (_fun _pointer _float _float _string/utf-8 -> _pointer))) + +(define page-end-text-raw + (get-ffi-obj "HPDF_Page_EndText" libhpdf + (_fun _pointer -> _pointer))) + + +(define (new-pdf) (pdf-new-raw 0 0)) +(define (save-pdf pdf path) (pdf-save-raw pdf path)) +(define (new-page pdf) (add-page-raw pdf)) +(define (free-pdf p) (pdf-free-raw p)) ; Error invalid memory reference. Some debugging context lost + +(define (new-ttf-font p font) + (define ttf-loaded (load-ttf-raw p font #t)) + (get-font-raw p ttf-loaded "UTF-8")) +(define (use-utf8 p) + (use-utf-encodingd-raw p) + (set-current-encoder-raw p "UTF-8")) + +(define (set-font-size page font size) (set-font-size-raw page font size)) +(define (put-text page x y text) + (page-begin-text-raw page) + (page-text-out-raw page x y text) + (page-end-text-raw page) + ) + +; 以下是測試區 +(define doc (new-pdf)) +(define pg (new-page doc)) +(use-utf8 doc) +(define ian-sui (new-ttf-font doc "/home/yoxem/.local/share/fonts/Iansui-Regular.ttf")) +(set-font-size pg ian-sui 15.0) +(put-text pg 140.0 150.0 "天地人123abc") +(save-pdf doc "/tmp/a.pdf") +(free-pdf doc) \ No newline at end of file