diff -ur dvipdfmx-20110311.orig/src/dvi.c dvipdfmx-20110311/src/dvi.c --- dvipdfmx-20110311.orig/src/dvi.c Wed Mar 09 16:43:18 2011 +++ dvipdfmx-20110311/src/dvi.c Sat Nov 05 22:25:11 2011 @@ -58,6 +58,10 @@ #define TEX_FONTS_ALLOC_SIZE 16u #define VF_NESTING_MAX 16u +/* UTF-32 over U+FFFF -> UTF-16 surrogate pair */ +#define UTF32toUTF16HS(x) (0xd800 + (((x-0x10000) >> 10) & 0x3ff)) +#define UTF32toUTF16LS(x) (0xdc00 + ( x & 0x3ff)) + /* Interal Variables */ static FILE *dvi_file = NULL; @@ -734,7 +738,7 @@ { struct loaded_font *font; spt_t width, height, depth; - unsigned char wbuf[2]; + unsigned char wbuf[4]; if (current_font < 0) { ERROR("No font selected!"); @@ -753,7 +757,14 @@ switch (font->type) { case PHYSICAL: - if (ch > 255) { /* _FIXME_ */ + if (ch > 65535) { /* _FIXME_ */ + wbuf[0] = (UTF32toUTF16HS(ch) >> 8) & 0xff; + wbuf[1] = UTF32toUTF16HS(ch) & 0xff; + wbuf[2] = (UTF32toUTF16LS(ch) >> 8) & 0xff; + wbuf[3] = UTF32toUTF16LS(ch) & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 4, + width, font->font_id, 2); + } else if (ch > 255) { /* _FIXME_ */ wbuf[0] = (ch >> 8) & 0xff; wbuf[1] = ch & 0xff; pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2, @@ -805,7 +816,7 @@ { struct loaded_font *font; spt_t width, height, depth; - unsigned char wbuf[2]; + unsigned char wbuf[4]; if (current_font < 0) { ERROR("No font selected!"); @@ -821,7 +832,14 @@ /* Treat a single character as a one byte string and use the * string routine. */ - if (ch > 255) { /* _FIXME_ */ + if (ch > 65535) { /* _FIXME_ */ + wbuf[0] = (UTF32toUTF16HS(ch) >> 8) & 0xff; + wbuf[1] = UTF32toUTF16HS(ch) & 0xff; + wbuf[2] = (UTF32toUTF16LS(ch) >> 8) & 0xff; + wbuf[3] = UTF32toUTF16LS(ch) & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 4, + width, font->font_id, 2); + } else if (ch > 255) { /* _FIXME_ */ wbuf[0] = (ch >> 8) & 0xff; wbuf[1] = ch & 0xff; pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2, @@ -899,6 +917,12 @@ } static void +do_set3 (void) +{ + dvi_set(get_unsigned_triple(dvi_file)); +} + +static void do_setrule (void) { SIGNED_QUAD width, height; @@ -935,6 +959,12 @@ dvi_put(get_unsigned_pair(dvi_file)); } +static void +do_put3 (void) +{ + dvi_put(get_unsigned_triple(dvi_file)); +} + void dvi_push (void) { @@ -1414,8 +1444,9 @@ switch (opcode) { case SET1: do_set1(); break; case SET2: do_set2(); break; - case SET3: case SET4: - ERROR("Multibyte (>16 bits) character not supported!"); + case SET3: do_set3(); break; + case SET4: + ERROR("Multibyte (>24 bits) character not supported!"); break; case SET_RULE: @@ -1424,8 +1455,9 @@ case PUT1: do_put1(); break; case PUT2: do_put2(); break; - case PUT3: case PUT4: - ERROR ("Multibyte character (>16 bits) not supported!"); + case PUT3: do_put3(); break; + case PUT4: + ERROR ("Multibyte character (>24 bits) not supported!"); break; case PUT_RULE: diff -ur dvipdfmx-20110311.orig/src/tfm.c dvipdfmx-20110311/src/tfm.c --- dvipdfmx-20110311.orig/src/tfm.c Sat Mar 05 13:44:49 2011 +++ dvipdfmx-20110311/src/tfm.c Sat Nov 05 22:33:49 2011 @@ -55,6 +55,12 @@ #define IS_JFM(i) ((i) == JFM_ID || (i) == JFMV_ID) #endif /* !WITHOUT_ASCII_PTEX */ +#if !defined(WITHOUT_ASCII_PTEX) +#define CHARACTER_INDEX(i) ((i>0xFFFFul ? 0x10000ul : i)) +#else +#define CHARACTER_INDEX(i) ((i)) +#endif + /* * TFM Record structure: * Multiple TFM's may be read in at once. @@ -162,7 +168,7 @@ struct coverage { long first_char; - unsigned short num_chars; + long num_chars; }; /* @@ -208,7 +214,7 @@ { if (charcode >= map->coverage.first_char && charcode <= map->coverage.first_char + map->coverage.num_chars) - return map->indices[charcode - map->coverage.first_char]; + return map->indices[CHARACTER_INDEX(charcode - map->coverage.first_char)]; else return -1; @@ -224,7 +230,7 @@ charcode >= map->coverages[idx].first_char; idx--) { if (charcode <= map->coverages[idx].first_char + map->coverages[idx].num_chars) - return map->indices[idx]; + return map->indices[CHARACTER_INDEX(idx)]; } return -1; @@ -479,12 +485,13 @@ fm->charmap.type = MAPTYPE_CHAR; fm->charmap.data = map = NEW(1, struct char_map); map->coverage.first_char = 0; - map->coverage.num_chars = 0xFFFFu; - map->indices = NEW(0x10000L, unsigned short); + map->coverage.num_chars = 0x10FFFFu; + map->indices = NEW(0x10001ul, unsigned short); for (code = 0; code <= 0xFFFFu; code++) { map->indices[code] = tfm->chartypes[code]; } + map->indices[0x10000ul] = tfm->chartypes[0]; } else { struct range_map *map; @@ -493,7 +500,7 @@ map->num_coverages = 1; map->coverages = NEW(map->num_coverages, struct coverage); map->coverages[0].first_char = 0; - map->coverages[0].num_chars = 0xFFFFu; + map->coverages[0].num_chars = 0x10FFFFu; map->indices = NEW(1, unsigned short); map->indices[0] = 0; /* Only default type used. */ } @@ -784,7 +791,7 @@ jfm_do_char_type_array(tfm_file, &tfm); jfm_make_charmap(fm, &tfm); fm->firstchar = 0; - fm->lastchar = 0xFFFFl; + fm->lastchar = 0x10FFFFl; fm->fontdir = (tfm.id == JFMV_ID) ? FONT_DIR_VERT : FONT_DIR_HORIZ; fm->source = SOURCE_TYPE_JFM; } diff -ur dvipdfmx-20110311.orig/src/vf.c dvipdfmx-20110311/src/vf.c --- dvipdfmx-20110311.orig/src/vf.c Sat Mar 05 13:44:49 2011 +++ dvipdfmx-20110311/src/vf.c Sat Nov 05 22:35:40 2011 @@ -238,11 +238,11 @@ ch = get_unsigned_quad (vf_file); /* Skip over TFM width since we already know it */ get_unsigned_quad (vf_file); - if (ch < 65536L) + if (ch < 0x1000000L) read_a_char_def (vf_file, thisfont, pkt_len, ch); else { fprintf (stderr, "char=%ld\n", ch); - ERROR ("Long character (>16 bits) in VF file.\nI can't handle long characters!\n"); + ERROR ("Long character (>24 bits) in VF file.\nI can't handle long characters!\n"); } break; } @@ -455,6 +455,12 @@ return; } +static void vf_set3(unsigned char **start, unsigned char *end) +{ + vf_set (unsigned_triple(start, end)); + return; +} + static void vf_putrule(unsigned char **start, unsigned char *end, spt_t ptsize) { SIGNED_QUAD width, height; @@ -491,6 +497,12 @@ return; } +static void vf_put3(unsigned char **start, unsigned char *end) +{ + dvi_put (unsigned_triple(start, end)); + return; +} + static void vf_push(void) { dvi_push(); @@ -851,8 +863,10 @@ vf_set2(&start, end); break; case SET3: + vf_set3(&start, end); + break; case SET4: - ERROR ("Multibyte (>16 bits) character in VF packet.\nI can't handle this!"); + ERROR ("Multibyte (>24 bits) character in VF packet.\nI can't handle this!"); break; case SET_RULE: vf_setrule(&start, end, ptsize); @@ -864,8 +878,10 @@ vf_put2(&start, end); break; case PUT3: + vf_put3(&start, end); + break; case PUT4: - ERROR ("Multibyte (>16 bits) character in VF packet.\nI can't handle this!"); + ERROR ("Multibyte (>24 bits) character in VF packet.\nI can't handle this!"); break; case PUT_RULE: vf_putrule(&start, end, ptsize);