Skip to content

Commit be39cd7

Browse files
committed
Identity-H CMap parsing (#6)
- Adds the groundwork for a postscript interpreter (currently supports bare minimum to parse the Identity-H CMap) - Some of the CIDInit ProcSet - Adds some more deserialization functions for Type0 fonts
1 parent fd71516 commit be39cd7

68 files changed

Lines changed: 5656 additions & 325 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/build
22
/.cache
33
/pdf-1.7-spec.pdf
4+
/postscript-spec.pdf
45
/*.bmp
56
/*.svg

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "assets/fonts-urw-base35"]
22
path = assets/fonts-urw-base35
33
url = https://github.com/ArtifexSoftware/urw-base35-fonts.git
4+
[submodule "assets/cmap-resources"]
5+
path = assets/cmap-resources
6+
url = https://github.com/adobe-type-tools/cmap-resources.git

.zed/debug.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,25 @@
3232
"request": "launch",
3333
"adapter": "CodeLLDB"
3434
},
35+
{
36+
"label": "Debug cmap-example",
37+
"build": {
38+
"command": "scripts/dev-build.sh",
39+
"args": [],
40+
"cwd": "$ZED_WORKTREE_ROOT"
41+
},
42+
"program": "$ZED_WORKTREE_ROOT/build/examples/cmap-example",
43+
"request": "launch",
44+
"adapter": "CodeLLDB"
45+
},
3546
{
3647
"label": "Debug test",
3748
"build": {
3849
"command": "scripts/dev-build.sh",
3950
"args": [],
4051
"cwd": "$ZED_WORKTREE_ROOT",
4152
"env": {
42-
"DEBUG_TEST_FUNCTION": "test_object_indirect_nested"
53+
"DEBUG_TEST_FUNCTION": "test_postscript_tokenize_single_plus_name_non_eof"
4354
}
4455
},
4556
"program": "$ZED_WORKTREE_ROOT/build/libs/test/pdf-test-main",

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# References/Resources
22

33
- [PDF Specification](https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/PDF32000_2008.pdf)
4+
- [PostScript Language Reference](https://www.adobe.com/jp/print/postscript/pdfs/PLRM.pdf)
5+
- [Adobe CMap and CIDFont Files Specification](https://adobe-type-tools.github.io/font-tech-notes/pdfs/5014.CIDFont_Spec.pdf)
46
- [Let's write a PDF file](https://speakerdeck.com/ange/lets-write-a-pdf-file)
57
- [TrueType Reference Manual](https://developer.apple.com/fonts/TrueType-Reference-Manual/)
68
- [BMP Wiki](https://en.wikipedia.org/wiki/BMP_file_format)

assets/cmap-resources

Submodule cmap-resources added at f5cf3bc

examples/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ if (NOT MSVC)
66
target_link_options(pdf-example PRIVATE -fsanitize=address,undefined)
77
endif()
88

9+
add_executable(cmap-example cmap.c)
10+
target_link_libraries(cmap-example PRIVATE pdf-logger pdf)
11+
target_compile_definitions(cmap-example PRIVATE DEBUG TEST)
12+
if (NOT MSVC)
13+
target_compile_options(cmap-example PRIVATE -fsanitize=address,undefined)
14+
target_link_options(cmap-example PRIVATE -fsanitize=address,undefined)
15+
endif()
16+
917
add_executable(font-example font.c)
1018
target_link_libraries(font-example PRIVATE pdf-error pdf-logger sfnt)
1119
target_compile_definitions(font-example PRIVATE DEBUG TEST)

examples/cmap.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "pdf/fonts/cmap.h"
2+
3+
#include <stdint.h>
4+
#include <stdio.h>
5+
6+
#include "arena/arena.h"
7+
#include "logger/log.h"
8+
#include "pdf_error/error.h"
9+
10+
static char*
11+
load_file_to_buffer(Arena* arena, const char* path, size_t* out_size) {
12+
FILE* file = fopen(path, "rb");
13+
*out_size = 0;
14+
if (!file) {
15+
return NULL;
16+
}
17+
18+
if (fseek(file, 0, SEEK_END) != 0) {
19+
fclose(file);
20+
return NULL;
21+
}
22+
23+
long len = ftell(file);
24+
if (len < 0) {
25+
fclose(file);
26+
return NULL;
27+
}
28+
29+
if (fseek(file, 0, SEEK_SET) != 0) {
30+
fclose(file);
31+
return NULL;
32+
}
33+
34+
char* buffer = arena_alloc(arena, (size_t)len);
35+
if (!buffer) {
36+
fclose(file);
37+
return NULL;
38+
}
39+
40+
if (fread(buffer, 1, (size_t)len, file) != (size_t)len) {
41+
fclose(file);
42+
return NULL;
43+
}
44+
fclose(file);
45+
46+
*out_size = (size_t)len;
47+
return buffer;
48+
}
49+
50+
int main(void) {
51+
Arena* arena = arena_new(1024);
52+
53+
size_t buffer_len;
54+
const char* buffer = load_file_to_buffer(
55+
arena,
56+
"assets/cmap-resources/Adobe-Identity-0/CMap/Identity-H",
57+
&buffer_len
58+
);
59+
60+
PdfCMap* cmap = NULL;
61+
PDF_REQUIRE(pdf_parse_cmap(arena, buffer, buffer_len, &cmap));
62+
63+
for (uint32_t codepoint = 0; codepoint <= 0xffff; codepoint++) {
64+
uint32_t cid;
65+
PDF_REQUIRE(
66+
pdf_cmap_get_cid(cmap, codepoint, &cid),
67+
"Failed to get cid for codepoint 0x%04x",
68+
(unsigned int)codepoint
69+
);
70+
71+
LOG_DIAG(
72+
INFO,
73+
CMAP,
74+
"0x%04x = %llu",
75+
codepoint,
76+
(unsigned long long int)cid
77+
);
78+
}
79+
80+
arena_free(arena);
81+
return 0;
82+
}

examples/pdf.c

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ int main(int argc, char** argv) {
6262

6363
size_t buffer_size;
6464
char* buffer =
65-
load_file_to_buffer(arena, "test-files/test.pdf", &buffer_size);
65+
load_file_to_buffer(arena, "test-files/embedded.pdf", &buffer_size);
6666

6767
PdfResolver* resolver;
6868
PDF_REQUIRE(
@@ -92,28 +92,6 @@ int main(int argc, char** argv) {
9292
render_page(arena, pdf_op_resolver_some(resolver), &page, &canvas)
9393
);
9494
canvas_write_file(canvas, "test.svg");
95-
96-
// if (page.contents.discriminant) {
97-
// for (size_t contents_idx = 0;
98-
// contents_idx <
99-
// pdf_void_vec_len(page.contents.value.elements);
100-
// contents_idx++) {
101-
// void* content_ptr;
102-
// RELEASE_ASSERT(pdf_void_vec_get(
103-
// page.contents.value.elements,
104-
// contents_idx,
105-
// &content_ptr
106-
// ));
107-
// PdfStream* content = content_ptr;
108-
109-
// printf("%s\n", content->stream_bytes);
110-
111-
// PdfContentStream stream;
112-
// PDF_REQUIRE(
113-
// pdf_deserialize_content_stream(content, arena, &stream)
114-
// );
115-
// }
116-
// }
11795
}
11896

11997
LOG_DIAG(INFO, EXAMPLE, "Finished");

libs/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ add_subdirectory(geom)
55
add_subdirectory(logger)
66
add_subdirectory(pdf)
77
add_subdirectory(pdf_error)
8+
add_subdirectory(postscript)
89
add_subdirectory(render)
910
add_subdirectory(sfnt)
1011
add_subdirectory(test)

libs/arena/include/arena/darray_impl.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
#ifndef DARRAY_IMPL_H
2-
#define DARRAY_IMPL_H
3-
41
#include <stdbool.h>
52
#include <string.h>
63

74
#include "arena/arena.h"
85
#include "logger/log.h"
96

10-
#endif // DARRAY_IMPL_H
11-
127
// Check arguments
138
#ifndef DARRAY_NAME
149
#error "DARRAY_NAME is not defined"

0 commit comments

Comments
 (0)