summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2018-03-14 17:52:17 +0100
committerTor Andersson <tor.andersson@artifex.com>2018-03-16 14:51:41 +0100
commit2612c20b725319833caeef36ccf4240f34e0e24b (patch)
treeeb58090f9a78187690bc5197b11284576a50b8c3
parent5a2b234c8e93a2c3acdb21e79da684dbcfe677c7 (diff)
downloadmupdf-2612c20b725319833caeef36ccf4240f34e0e24b.tar.xz
Add simple CJK font creation.
Create a non-embedded CJK font using UTF-16 encoding. This can be used in mutool create like so: %%CJKFont Ming GB1 BT /Ming 10 Tf 100 100 Td <4F60 597D> Tj ET
-rw-r--r--include/mupdf/pdf/font.h1
-rw-r--r--include/mupdf/pdf/resource.h4
-rw-r--r--platform/java/mupdf_native.c22
-rw-r--r--platform/java/mupdf_native.h16
-rw-r--r--platform/java/src/com/artifex/mupdf/fitz/Font.java5
-rw-r--r--platform/java/src/com/artifex/mupdf/fitz/PDFDocument.java1
-rw-r--r--source/pdf/pdf-font.c89
-rw-r--r--source/pdf/pdf-resources.c3
-rw-r--r--source/tools/murun.c23
-rw-r--r--source/tools/pdfcreate.c37
10 files changed, 196 insertions, 5 deletions
diff --git a/include/mupdf/pdf/font.h b/include/mupdf/pdf/font.h
index 10571f0b..730d3459 100644
--- a/include/mupdf/pdf/font.h
+++ b/include/mupdf/pdf/font.h
@@ -125,6 +125,7 @@ void pdf_run_glyph(fz_context *ctx, pdf_document *doc, pdf_obj *resources, fz_bu
pdf_obj *pdf_add_simple_font(fz_context *ctx, pdf_document *doc, fz_font *font);
pdf_obj *pdf_add_cid_font(fz_context *ctx, pdf_document *doc, fz_font *font);
+pdf_obj *pdf_add_cjk_font(fz_context *ctx, pdf_document *doc, fz_font *font, int script);
int pdf_font_writing_supported(fz_font *font);
diff --git a/include/mupdf/pdf/resource.h b/include/mupdf/pdf/resource.h
index 6bede024..885a404e 100644
--- a/include/mupdf/pdf/resource.h
+++ b/include/mupdf/pdf/resource.h
@@ -17,9 +17,9 @@ void pdf_empty_store(fz_context *ctx, pdf_document *doc);
* the data, enabling rapid lookup.
*/
-enum { PDF_SIMPLE_FONT_RESOURCE=1, PDF_CID_FONT_RESOURCE=2 };
+enum { PDF_SIMPLE_FONT_RESOURCE=1, PDF_CID_FONT_RESOURCE=2, PDF_CJK_FONT_RESOURCE=3 };
-pdf_obj *pdf_find_font_resource(fz_context *ctx, pdf_document *doc, int type, fz_buffer *item, unsigned char md5[16]);
+pdf_obj *pdf_find_font_resource(fz_context *ctx, pdf_document *doc, int type, int encoding, fz_buffer *item, unsigned char md5[16]);
pdf_obj *pdf_insert_font_resource(fz_context *ctx, pdf_document *doc, unsigned char md5[16], pdf_obj *obj);
pdf_obj *pdf_find_image_resource(fz_context *ctx, pdf_document *doc, fz_image *item, unsigned char md5[16]);
pdf_obj *pdf_insert_image_resource(fz_context *ctx, pdf_document *doc, unsigned char md5[16], pdf_obj *obj);
diff --git a/platform/java/mupdf_native.c b/platform/java/mupdf_native.c
index 7235d50e..31f76d7b 100644
--- a/platform/java/mupdf_native.c
+++ b/platform/java/mupdf_native.c
@@ -7054,6 +7054,28 @@ FUN(PDFDocument_addFont)(JNIEnv *env, jobject self, jobject jfont)
}
JNIEXPORT jobject JNICALL
+FUN(PDFDocument_addCJKFont)(JNIEnv *env, jobject self, jobject jfont, jint ordering)
+{
+ fz_context *ctx = get_context(env);
+ pdf_document *pdf = from_PDFDocument(env, self);
+ fz_font *font = from_Font(env, jfont);
+ pdf_obj *ind = NULL;
+
+ if (!ctx || !pdf) return NULL;
+ if (!font) { jni_throw_arg(env, "font must not be null"); return NULL; }
+
+ fz_try(ctx)
+ ind = pdf_add_cjk_font(ctx, pdf, font, ordering);
+ fz_catch(ctx)
+ {
+ jni_rethrow(env, ctx);
+ return NULL;
+ }
+
+ return to_PDFObject_safe_own(ctx, env, self, ind);
+}
+
+JNIEXPORT jobject JNICALL
FUN(PDFDocument_addSimpleFont)(JNIEnv *env, jobject self, jobject jfont)
{
fz_context *ctx = get_context(env);
diff --git a/platform/java/mupdf_native.h b/platform/java/mupdf_native.h
index 8bfe3480..42d54345 100644
--- a/platform/java/mupdf_native.h
+++ b/platform/java/mupdf_native.h
@@ -889,6 +889,14 @@ extern "C" {
#ifdef __cplusplus
extern "C" {
#endif
+#undef com_artifex_mupdf_fitz_Font_CN
+#define com_artifex_mupdf_fitz_Font_CN 0L
+#undef com_artifex_mupdf_fitz_Font_TW
+#define com_artifex_mupdf_fitz_Font_TW 1L
+#undef com_artifex_mupdf_fitz_Font_JP
+#define com_artifex_mupdf_fitz_Font_JP 2L
+#undef com_artifex_mupdf_fitz_Font_KR
+#define com_artifex_mupdf_fitz_Font_KR 3L
/*
* Class: com_artifex_mupdf_fitz_Font
* Method: finalize
@@ -1904,6 +1912,14 @@ JNIEXPORT jobject JNICALL Java_com_artifex_mupdf_fitz_PDFDocument_addSimpleFont
/*
* Class: com_artifex_mupdf_fitz_PDFDocument
+ * Method: addCJKFont
+ * Signature: (Lcom/artifex/mupdf/fitz/Font;I)Lcom/artifex/mupdf/fitz/PDFObject;
+ */
+JNIEXPORT jobject JNICALL Java_com_artifex_mupdf_fitz_PDFDocument_addCJKFont
+ (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class: com_artifex_mupdf_fitz_PDFDocument
* Method: addFont
* Signature: (Lcom/artifex/mupdf/fitz/Font;)Lcom/artifex/mupdf/fitz/PDFObject;
*/
diff --git a/platform/java/src/com/artifex/mupdf/fitz/Font.java b/platform/java/src/com/artifex/mupdf/fitz/Font.java
index 9eb6f61a..2910d543 100644
--- a/platform/java/src/com/artifex/mupdf/fitz/Font.java
+++ b/platform/java/src/com/artifex/mupdf/fitz/Font.java
@@ -6,6 +6,11 @@ public class Font
Context.init();
}
+ public static final int CN = 0;
+ public static final int TW = 1;
+ public static final int JP = 2;
+ public static final int KR = 3;
+
private long pointer;
protected native void finalize();
diff --git a/platform/java/src/com/artifex/mupdf/fitz/PDFDocument.java b/platform/java/src/com/artifex/mupdf/fitz/PDFDocument.java
index 945294f3..b650df52 100644
--- a/platform/java/src/com/artifex/mupdf/fitz/PDFDocument.java
+++ b/platform/java/src/com/artifex/mupdf/fitz/PDFDocument.java
@@ -97,6 +97,7 @@ public class PDFDocument extends Document
public native void deletePage(int at);
public native PDFObject addImage(Image image);
public native PDFObject addSimpleFont(Font font);
+ public native PDFObject addCJKFont(Font font, int ordering);
public native PDFObject addFont(Font font);
public native boolean hasUnsavedChanges();
public native boolean canBeSavedIncrementally();
diff --git a/source/pdf/pdf-font.c b/source/pdf/pdf-font.c
index 9e8a50dc..6be72250 100644
--- a/source/pdf/pdf-font.c
+++ b/source/pdf/pdf-font.c
@@ -2099,7 +2099,7 @@ pdf_add_cid_font(fz_context *ctx, pdf_document *doc, fz_font *font)
/* Before we add this font as a resource check if the same font
* already exists in our resources for this doc. If yes, then
* hand back that reference */
- fref = pdf_find_font_resource(ctx, doc, PDF_CID_FONT_RESOURCE, font->buffer, digest);
+ fref = pdf_find_font_resource(ctx, doc, PDF_CID_FONT_RESOURCE, 0, font->buffer, digest);
if (fref == NULL)
{
/* Set up desc, width, and font file */
@@ -2174,7 +2174,7 @@ pdf_add_simple_font(fz_context *ctx, pdf_document *doc, fz_font *font)
/* Before we add this font as a resource check if the same font
* already exists in our resources for this doc. If yes, then
* hand back that reference */
- fref = pdf_find_font_resource(ctx, doc, PDF_SIMPLE_FONT_RESOURCE, font->buffer, digest);
+ fref = pdf_find_font_resource(ctx, doc, PDF_SIMPLE_FONT_RESOURCE, 0, font->buffer, digest);
if (fref == NULL)
{
fobj = pdf_new_dict(ctx, doc, 10);
@@ -2247,3 +2247,88 @@ pdf_font_writing_supported(fz_font *font)
}
return 0;
}
+
+/* Add a non-embedded UTF16-encoded CID-font for the CJK scripts: CNS1, GB1, Japan1, or Korea1 */
+pdf_obj *
+pdf_add_cjk_font(fz_context *ctx, pdf_document *doc, fz_font *fzfont, int script)
+{
+ pdf_obj *fref, *font, *subfont, *fontdesc;
+ pdf_obj *dfonts, *ros;
+ fz_rect bbox = { -200, -200, 1200, 1200 };
+ unsigned char digest[16];
+
+ const char *basefont, *encoding, *ordering;
+ int supplement;
+
+ switch (script)
+ {
+ case FZ_ADOBE_CNS_1:
+ basefont = "Song";
+ encoding = "UniCNS-UTF16-H";
+ ordering = "CNS1";
+ supplement = 7;
+ break;
+ case FZ_ADOBE_GB_1:
+ basefont = "Ming";
+ encoding = "UniGB-UTF16-H";
+ ordering = "GB1";
+ supplement = 5;
+ break;
+ default:
+ script = FZ_ADOBE_JAPAN_1;
+ /* fall through */
+ case FZ_ADOBE_JAPAN_1:
+ basefont = "Mincho";
+ encoding = "UniJIS-UTF16-H";
+ ordering = "Japan1";
+ supplement = 6;
+ break;
+ case FZ_ADOBE_KOREA_1:
+ basefont = "Batang";
+ encoding = "UniKS-UTF16-H";
+ ordering = "Korea1";
+ supplement = 2;
+ break;
+ }
+
+ fref = pdf_find_font_resource(ctx, doc, PDF_CJK_FONT_RESOURCE, script, fzfont->buffer, digest);
+ if (fref)
+ return fref;
+
+ font = pdf_new_dict(ctx, doc, 5);
+ pdf_dict_put(ctx, font, PDF_NAME_Type, PDF_NAME_Font);
+ pdf_dict_put(ctx, font, PDF_NAME_Subtype, PDF_NAME_Type0);
+ pdf_dict_put_name(ctx, font, PDF_NAME_BaseFont, basefont);
+ pdf_dict_put_name(ctx, font, PDF_NAME_Encoding, encoding);
+ pdf_dict_put_drop(ctx, font, PDF_NAME_DescendantFonts, dfonts = pdf_new_array(ctx, doc, 1));
+ subfont = pdf_new_dict(ctx, doc, 5);
+ {
+ pdf_dict_put(ctx, subfont, PDF_NAME_Type, PDF_NAME_Font);
+ pdf_dict_put(ctx, subfont, PDF_NAME_Subtype, PDF_NAME_CIDFontType0);
+ pdf_dict_put_name(ctx, subfont, PDF_NAME_BaseFont, basefont);
+ pdf_dict_put_drop(ctx, subfont, PDF_NAME_CIDSystemInfo, ros = pdf_new_dict(ctx, doc, 3));
+ pdf_dict_put_text_string(ctx, ros, PDF_NAME_Registry, "Adobe");
+ pdf_dict_put_text_string(ctx, ros, PDF_NAME_Ordering, ordering);
+ pdf_dict_put_int(ctx, ros, PDF_NAME_Supplement, supplement);
+ fontdesc = pdf_new_dict(ctx, doc, 8);
+ {
+ pdf_dict_put(ctx, fontdesc, PDF_NAME_Type, PDF_NAME_FontDescriptor);
+ pdf_dict_put_text_string(ctx, fontdesc, PDF_NAME_FontName, basefont);
+ pdf_dict_put_int(ctx, fontdesc, PDF_NAME_Flags, 0);
+ pdf_dict_put_rect(ctx, fontdesc, PDF_NAME_FontBBox, &bbox);
+ pdf_dict_put_int(ctx, fontdesc, PDF_NAME_ItalicAngle, 0);
+ pdf_dict_put_int(ctx, fontdesc, PDF_NAME_Ascent, 1000);
+ pdf_dict_put_int(ctx, fontdesc, PDF_NAME_Descent, -200);
+ pdf_dict_put_int(ctx, fontdesc, PDF_NAME_StemV, 80);
+ }
+ pdf_dict_put_drop(ctx, subfont, PDF_NAME_FontDescriptor, pdf_add_object_drop(ctx, doc, fontdesc));
+ }
+ pdf_array_push_drop(ctx, dfonts, pdf_add_object_drop(ctx, doc, subfont));
+
+ fref = pdf_add_object_drop(ctx, doc, font);
+
+ /* Add ref to our font resource hash table. */
+ fref = pdf_insert_font_resource(ctx, doc, digest, fref);
+
+ return fref;
+}
diff --git a/source/pdf/pdf-resources.c b/source/pdf/pdf-resources.c
index 72adf081..720ee2b1 100644
--- a/source/pdf/pdf-resources.c
+++ b/source/pdf/pdf-resources.c
@@ -109,7 +109,7 @@ pdf_insert_image_resource(fz_context *ctx, pdf_document *doc, unsigned char dige
* it may be more problematic. */
pdf_obj *
-pdf_find_font_resource(fz_context *ctx, pdf_document *doc, int type, fz_buffer *item, unsigned char digest[16])
+pdf_find_font_resource(fz_context *ctx, pdf_document *doc, int type, int encoding, fz_buffer *item, unsigned char digest[16])
{
fz_md5 state;
unsigned char *data;
@@ -124,6 +124,7 @@ pdf_find_font_resource(fz_context *ctx, pdf_document *doc, int type, fz_buffer *
/* Create md5 and see if we have the item in our table */
fz_md5_init(&state);
fz_md5_update(&state, (unsigned char*)&type, sizeof type);
+ fz_md5_update(&state, (unsigned char*)&encoding, sizeof encoding);
fz_md5_update(&state, data, size);
fz_md5_final(&state, digest);
diff --git a/source/tools/murun.c b/source/tools/murun.c
index bed686a7..911fcf35 100644
--- a/source/tools/murun.c
+++ b/source/tools/murun.c
@@ -3261,6 +3261,28 @@ static void ffi_PDFDocument_addSimpleFont(js_State *J)
ffi_pushobj(J, ind);
}
+static void ffi_PDFDocument_addCJKFont(js_State *J)
+{
+ fz_context *ctx = js_getcontext(J);
+ pdf_document *pdf = js_touserdata(J, 0, "pdf_document");
+ fz_font *font = js_touserdata(J, 1, "fz_font");
+ const char *on = js_tostring(J, 2);
+ int ord = FZ_ADOBE_JAPAN_1;
+ pdf_obj *ind = NULL;
+
+ if (!strcmp(on, "CNS1") || !strcmp(on, "CN")) ord = FZ_ADOBE_CNS_1;
+ else if (!strcmp(on, "GB1") || !strcmp(on, "TW")) ord = FZ_ADOBE_GB_1;
+ else if (!strcmp(on, "Korea1") || !strcmp(on, "KR") || !strcmp(on, "KO")) ord = FZ_ADOBE_KOREA_1;
+ else if (!strcmp(on, "Japan1") || !strcmp(on, "JP") || !strcmp(on, "JA")) ord = FZ_ADOBE_JAPAN_1;
+
+ fz_try(ctx)
+ ind = pdf_add_cjk_font(ctx, pdf, font, ord);
+ fz_catch(ctx)
+ rethrow(J);
+
+ ffi_pushobj(J, ind);
+}
+
static void ffi_PDFDocument_addFont(js_State *J)
{
fz_context *ctx = js_getcontext(J);
@@ -4676,6 +4698,7 @@ int murun_main(int argc, char **argv)
jsB_propfun(J, "PDFDocument.addStream", ffi_PDFDocument_addStream, 2);
jsB_propfun(J, "PDFDocument.addRawStream", ffi_PDFDocument_addRawStream, 2);
jsB_propfun(J, "PDFDocument.addSimpleFont", ffi_PDFDocument_addSimpleFont, 1);
+ jsB_propfun(J, "PDFDocument.addCJKFont", ffi_PDFDocument_addCJKFont, 2);
jsB_propfun(J, "PDFDocument.addFont", ffi_PDFDocument_addFont, 1);
jsB_propfun(J, "PDFDocument.addImage", ffi_PDFDocument_addImage, 1);
jsB_propfun(J, "PDFDocument.addPage", ffi_PDFDocument_addPage, 4);
diff --git a/source/tools/pdfcreate.c b/source/tools/pdfcreate.c
index b1649500..93dff5fb 100644
--- a/source/tools/pdfcreate.c
+++ b/source/tools/pdfcreate.c
@@ -22,6 +22,7 @@ static void usage(void)
"\t%%%%MediaBox LLX LLY URX URY\n"
"\t%%%%Rotate Angle\n"
"\t%%%%Font Name Filename (or base 14 font name)\n"
+ "\t%%%%CJKFont Name Ordering (CNS1, GB1, Japan1, or Korea1)\n"
"\t%%%%Image Name Filename\n\n"
);
fputs(fz_pdf_write_options_usage, stderr);
@@ -58,6 +59,36 @@ static void add_font_res(pdf_obj *resources, char *name, char *path)
fz_drop_font(ctx, font);
}
+static void add_cjkfont_res(pdf_obj *resources, char *name, char *on)
+{
+ const unsigned char *data;
+ int size, index, ordering;
+ fz_font *font;
+ pdf_obj *subres, *ref;
+
+ if (!strcmp(on, "CNS1") || !strcmp(on, "CN")) ordering = FZ_ADOBE_CNS_1;
+ else if (!strcmp(on, "GB1") || !strcmp(on, "TW")) ordering = FZ_ADOBE_GB_1;
+ else if (!strcmp(on, "Japan1") || !strcmp(on, "JP") || !strcmp(on, "JA")) ordering = FZ_ADOBE_JAPAN_1;
+ else if (!strcmp(on, "Korea1") || !strcmp(on, "KR") || !strcmp(on, "KO")) ordering = FZ_ADOBE_KOREA_1;
+ else ordering = FZ_ADOBE_JAPAN_1;
+
+ data = fz_lookup_cjk_font(ctx, ordering, 0, 0, &size, &index);
+ font = fz_new_font_from_memory(ctx, NULL, data, size, index, 0);
+
+ subres = pdf_dict_get(ctx, resources, PDF_NAME_Font);
+ if (!subres)
+ {
+ subres = pdf_new_dict(ctx, doc, 10);
+ pdf_dict_put_drop(ctx, resources, PDF_NAME_Font, subres);
+ }
+
+ ref = pdf_add_cjk_font(ctx, doc, font, ordering);
+ pdf_dict_puts(ctx, subres, name, ref);
+ pdf_drop_obj(ctx, ref);
+
+ fz_drop_font(ctx, font);
+}
+
static void add_image_res(pdf_obj *resources, char *name, char *path)
{
fz_image *image;
@@ -85,6 +116,7 @@ The input is a raw content stream, with commands embedded in comments:
%%MediaBox LLX LLY URX URY
%%Rotate Angle
%%Font Name Filename (or base 14 font name)
+%%CJKFont Name Ordering (CNS1, GB1, Japan1, or Korea1)
%%Image Name Filename
*/
static void create_page(char *input)
@@ -126,6 +158,11 @@ static void create_page(char *input)
s = fz_strsep(&p, " ");
add_font_res(resources, s, p);
}
+ else if (!strcmp(s, "%%CJKFont"))
+ {
+ s = fz_strsep(&p, " ");
+ add_cjkfont_res(resources, s, p);
+ }
else if (!strcmp(s, "%%Image"))
{
s = fz_strsep(&p, " ");