From 2a393c134fe3fe8eb85bf818cb7ad6ae4396322a Mon Sep 17 00:00:00 2001 From: Martin Kretzschmar Date: Wed, 18 Sep 2002 22:20:42 +0000 Subject: Synched with Xpdf 1.01 --- (limited to 'pdf/xpdf/TextOutputDev.cc') diff --git a/pdf/xpdf/TextOutputDev.cc b/pdf/xpdf/TextOutputDev.cc index 7540492..5e5761f 100644 --- a/pdf/xpdf/TextOutputDev.cc +++ b/pdf/xpdf/TextOutputDev.cc @@ -2,7 +2,7 @@ // // TextOutputDev.cc // -// Copyright 1997 Derek B. Noonburg +// Copyright 1997-2002 Glyph & Cog, LLC // //======================================================================== @@ -10,16 +10,19 @@ #pragma implementation #endif +#include #include #include #include +#include #include #include "GString.h" #include "gmem.h" #include "config.h" #include "Error.h" +#include "GlobalParams.h" +#include "UnicodeMap.h" #include "GfxState.h" -#include "FontEncoding.h" #include "TextOutputDev.h" #ifdef MACOS @@ -27,730 +30,66 @@ #include "ICSupport.h" #endif -#include "TextOutputFontInfo.h" - -//------------------------------------------------------------------------ -// Character substitutions -//------------------------------------------------------------------------ - -static char *generalSubstNames[] = { - "zerooldstyle", - "oneoldstyle", - "twooldstyle", - "threeoldstyle", - "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", - "sevenoldstyle", - "eightoldstyle", - "nineoldstyle", - "oldstylezero", - "oldstyleone", - "oldstyletwo", - "oldstylethree", - "oldstylefour", - "oldstylefive", - "oldstylesix", - "oldstyleseven", - "oldstyleeight", - "oldstylenine" -}; - -static FontEncoding generalSubstEncoding(generalSubstNames, - sizeof(generalSubstNames) / - sizeof(char *)); - -static char *generalSubst[] = { - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine" -}; - -static char *ascii7Subst[] = { - "A", "A", "A", "A", // A{acute,circumflex,dieresis,grave} - "A", "A", // A{ring,tilde} - "AE", // AE - "C", // Ccedilla - "E", "E", "E", "E", // E{acute,circumflex,dieresis,grave} - "I", "I", "I", "I", // I{acute,circumflex,dieresis,grave} - "L", // Lslash - "N", // Ntilde - "O", "O", "O", "O", // O{acute,circumflex,dieresis,grave} - "O", "O", // O{slash,tilde} - "OE", // OE - "S", // Scaron - "U", "U", "U", "U", // U{acute,circumflex,dieresis,grave} - "Y", "Y", // T{acute,dieresis} - "Z", // Zcaron - "a", "a", "a", "a", // a{acute,circumflex,dieresis,grave} - "a", "a", // a{ring,tilde} - "ae", // ae - "c", // ccedilla - "e", "e", "e", "e", // e{acute,circumflex,dieresis,grave} - "fi", "fl", // ligatures - "ff", "ffi", "ffl", // ligatures - "i", // dotlessi - "i", "i", "i", "i", // i{acute,circumflex,dieresis,grave} - "l", // lslash - "n", // ntilde - "o", "o", "o", "o", // o{acute,circumflex,dieresis,grave} - "o", "o", // o{slash,tilde} - "oe", // oe - "s", // scaron - "u", "u", "u", "u", // u{acute,circumflex,dieresis,grave} - "y", "y", // t{acute,dieresis} - "z", // zcaron - "|", // brokenbar - "*", // bullet - "...", // ellipsis - "-", "-", "-", // emdash, endash, hyphen - "\"", "\"", // quotedblleft, quotedblright - "'", // quotesingle - "(R)", // registered - "TM" // trademark -}; - -static char *isoLatin1Subst[] = { - "L", // Lslash - "OE", // OE - "S", // Scaron - "Y", // Ydieresis - "Z", // Zcaron - "fi", "fl", // ligatures - "ff", "ffi", "ffl", // ligatures - "i", // dotlessi - "l", // lslash - "oe", // oe - "s", // scaron - "z", // zcaron - "*", // bullet - "...", // ellipsis - "-", "-", // emdash, hyphen - "\"", "\"", // quotedblleft, quotedblright - "'", // quotesingle - "TM" // trademark -}; - -static char *isoLatin2Subst[] = { - "fi", "fl", // ligatures - "ff", "ffi", "ffl", // ligatures - "*", // bullet - "...", // ellipsis - "-", "-", // emdash, hyphen - "\"", "\"", // quotedblleft, quotedblright - "'", // quotesingle - "TM" // trademark -}; - -static char **isoLatin5Subst = isoLatin1Subst; - -//------------------------------------------------------------------------ -// 16-bit fonts -//------------------------------------------------------------------------ - -#if JAPANESE_SUPPORT - -// CID 0 .. 96 -static Gushort japan12Map[96] = { - 0x2121, 0x2121, 0x212a, 0x2149, 0x2174, 0x2170, 0x2173, 0x2175, // 00 .. 07 - 0x2147, 0x214a, 0x214b, 0x2176, 0x215c, 0x2124, 0x213e, 0x2123, // 08 .. 0f - 0x213f, 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, // 10 .. 17 - 0x2337, 0x2338, 0x2339, 0x2127, 0x2128, 0x2163, 0x2161, 0x2164, // 18 .. 1f - 0x2129, 0x2177, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, // 20 .. 27 - 0x2347, 0x2348, 0x2349, 0x234a, 0x234b, 0x234c, 0x234d, 0x234e, // 28 .. 2f - 0x234f, 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, // 30 .. 37 - 0x2357, 0x2358, 0x2359, 0x235a, 0x214e, 0x216f, 0x214f, 0x2130, // 38 .. 3f - 0x2132, 0x2146, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, // 40 .. 47 - 0x2367, 0x2368, 0x2369, 0x236a, 0x236b, 0x236c, 0x236d, 0x236e, // 48 .. 4f - 0x236f, 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, // 50 .. 57 - 0x2377, 0x2378, 0x2379, 0x237a, 0x2150, 0x2143, 0x2151, 0x2141 // 58 .. 5f -}; - -// CID 325 .. 421 -static Gushort japan12KanaMap1[97] = { - 0x2131, 0x2121, 0x2123, 0x2156, 0x2157, 0x2122, 0x2126, 0x2572, - 0x2521, 0x2523, 0x2525, 0x2527, 0x2529, 0x2563, 0x2565, 0x2567, - 0x2543, 0x213c, 0x2522, 0x2524, 0x2526, 0x2528, 0x252a, 0x252b, - 0x252d, 0x252f, 0x2531, 0x2533, 0x2535, 0x2537, 0x2539, 0x253b, - 0x253d, 0x253f, 0x2541, 0x2544, 0x2546, 0x2548, 0x254a, 0x254b, - 0x254c, 0x254d, 0x254e, 0x254f, 0x2552, 0x2555, 0x2558, 0x255b, - 0x255e, 0x255f, 0x2560, 0x2561, 0x2562, 0x2564, 0x2566, 0x2568, - 0x2569, 0x256a, 0x256b, 0x256c, 0x256d, 0x256f, 0x2573, 0x212b, - 0x212c, 0x212e, 0x2570, 0x2571, 0x256e, 0x2575, 0x2576, 0x2574, - 0x252c, 0x252e, 0x2530, 0x2532, 0x2534, 0x2536, 0x2538, 0x253a, - 0x253c, 0x253e, 0x2540, 0x2542, 0x2545, 0x2547, 0x2549, 0x2550, - 0x2551, 0x2553, 0x2554, 0x2556, 0x2557, 0x2559, 0x255a, 0x255c, - 0x255d -}; - -// CID 501 .. 598 -static Gushort japan12KanaMap2[98] = { - 0x212d, 0x212f, 0x216d, 0x214c, 0x214d, 0x2152, 0x2153, 0x2154, - 0x2155, 0x2158, 0x2159, 0x215a, 0x215b, 0x213d, 0x2121, 0x2472, - 0x2421, 0x2423, 0x2425, 0x2427, 0x2429, 0x2463, 0x2465, 0x2467, - 0x2443, 0x2422, 0x2424, 0x2426, 0x2428, 0x242a, 0x242b, 0x242d, - 0x242f, 0x2431, 0x2433, 0x2435, 0x2437, 0x2439, 0x243b, 0x243d, - 0x243f, 0x2441, 0x2444, 0x2446, 0x2448, 0x244a, 0x244b, 0x244c, - 0x244d, 0x244e, 0x244f, 0x2452, 0x2455, 0x2458, 0x245b, 0x245e, - 0x245f, 0x2460, 0x2461, 0x2462, 0x2464, 0x2466, 0x2468, 0x2469, - 0x246a, 0x246b, 0x246c, 0x246d, 0x246f, 0x2473, 0x2470, 0x2471, - 0x246e, 0x242c, 0x242e, 0x2430, 0x2432, 0x2434, 0x2436, 0x2438, - 0x243a, 0x243c, 0x243e, 0x2440, 0x2442, 0x2445, 0x2447, 0x2449, - 0x2450, 0x2451, 0x2453, 0x2454, 0x2456, 0x2457, 0x2459, 0x245a, - 0x245c, 0x245d -}; - -static char *japan12Roman[10] = { - "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X" -}; - -static char *japan12Abbrev1[6] = { - "mm", "cm", "km", "mg", "kg", "cc" -}; - -#endif - -#if CHINESE_CNS_SUPPORT - -static Gushort cns13Map1[99] = { - // 0-98 - 0, 0xa140, 0xa149, 0xa1a8, 0xa1ad, 0xa243, 0xa248, 0xa1ae, - 0xa1a6, 0xa15d, 0xa15e, 0xa1af, 0xa1cf, 0xa141, 0xa1df, 0xa144, - 0xa241, 0xa2af, 0xa2b0, 0xa2b1, 0xa2b2, 0xa2b3, 0xa2b4, 0xa2b5, - 0xa2b6, 0xa2b7, 0xa2b8, 0xa147, 0xa146, 0xa1d5, 0xa1d7, 0xa1d6, - 0xa148, 0xa249, 0xa2cf, 0xa2d0, 0xa2d1, 0xa2d2, 0xa2d3, 0xa2d4, - 0xa2d5, 0xa2d6, 0xa2d7, 0xa2d8, 0xa2d9, 0xa2da, 0xa2db, 0xa2dc, - 0xa2dd, 0xa2de, 0xa2df, 0xa2e0, 0xa2e1, 0xa2e2, 0xa2e3, 0xa2e4, - 0xa2e5, 0xa2e6, 0xa2e7, 0xa2e8, 0xa165, 0xa242, 0xa166, 0xa173, - 0xa15a, 0xa1a5, 0xa2e9, 0xa2ea, 0xa2eb, 0xa2ec, 0xa2ed, 0xa2ee, - 0xa2ef, 0xa2f0, 0xa2f1, 0xa2f2, 0xa2f3, 0xa2f4, 0xa2f5, 0xa2f6, - 0xa2f7, 0xa2f8, 0xa2f9, 0xa2fa, 0xa2fb, 0xa2fc, 0xa2fd, 0xa2fe, - 0xa340, 0xa341, 0xa342, 0xa343, 0xa161, 0xa159, 0xa162, 0xa1e3, - 0, 0, 0xa14b -}; - -static Gushort cns13Map2[95] = { - // 13648-13742 - 0xa140, 0xa149, 0xa1a8, 0xa1ad, 0xa244, 0xa248, 0xa1ae, - 0xa1a6, 0xa15d, 0xa15e, 0xa1af, 0xa1cf, 0xa141, 0xa1df, 0xa144, - 0xa241, 0xa2af, 0xa2b0, 0xa2b1, 0xa2b2, 0xa2b3, 0xa2b4, 0xa2b5, - 0xa2b6, 0xa2b7, 0xa2b8, 0xa147, 0xa146, 0xa1d5, 0xa1d7, 0xa1d6, - 0xa148, 0xa249, 0xa2cf, 0xa2d0, 0xa2d1, 0xa2d2, 0xa2d3, 0xa2d4, - 0xa2d5, 0xa2d6, 0xa2d7, 0xa2d8, 0xa2d9, 0xa2da, 0xa2db, 0xa2dc, - 0xa2dd, 0xa2de, 0xa2df, 0xa2e0, 0xa2e1, 0xa2e2, 0xa2e3, 0xa2e4, - 0xa2e5, 0xa2e6, 0xa2e7, 0xa2e8, 0xa165, 0xa242, 0xa166, 0xa173, - 0xa15a, 0xa1a5, 0xa2e9, 0xa2ea, 0xa2eb, 0xa2ec, 0xa2ed, 0xa2ee, - 0xa2ef, 0xa2f0, 0xa2f1, 0xa2f2, 0xa2f3, 0xa2f4, 0xa2f5, 0xa2f6, - 0xa2f7, 0xa2f8, 0xa2f9, 0xa2fa, 0xa2fb, 0xa2fc, 0xa2fd, 0xa2fe, - 0xa340, 0xa341, 0xa342, 0xa343, 0xa161, 0xa159, 0xa162, 0xa1c3 -}; - -#endif - //------------------------------------------------------------------------ // TextString //------------------------------------------------------------------------ -TextString::TextString(GfxState *state, GBool hexCodes1) { - double x, y, h; +TextString::TextString(GfxState *state, double fontSize) { + GfxFont *font; + double x, y; state->transform(state->getCurX(), state->getCurY(), &x, &y); - h = state->getTransformedFontSize(); - //~ yMin/yMax computation should use font ascent/descent values - yMin = y - 0.95 * h; - yMax = yMin + 1.3 * h; + if ((font = state->getFont())) { + yMin = y - font->getAscent() * fontSize; + yMax = y - font->getDescent() * fontSize; + } else { + // this means that the PDF file draws text without a current font, + // which should never happen + yMin = y - 0.95 * fontSize; + yMax = y + 0.35 * fontSize; + } + if (yMin == yMax) { + // this is a sanity check for a case that shouldn't happen -- but + // if it does happen, we want to avoid dividing by zero later + yMin = y; + yMax = y + 1; + } col = 0; - text = new GString(); + text = NULL; xRight = NULL; + len = size = 0; yxNext = NULL; xyNext = NULL; - hexCodes = hexCodes1; } TextString::~TextString() { - delete text; + gfree(text); gfree(xRight); } void TextString::addChar(GfxState *state, double x, double y, - double dx, double dy, - Guchar c, TextOutputCharSet charSet) { - char *charName, *sub; - int c1; - int i, j, n, m; - - // get current index - i = text->getLength(); - - // append translated character(s) to string - sub = NULL; - n = 1; - if ((charName = state->getFont()->getCharName(c))) { - if ((c1 = generalSubstEncoding.getCharCode(charName)) >= 0) { - charName = generalSubst[c1]; - } - switch (charSet) { - case textOutASCII7: - c1 = ascii7Encoding.getCharCode(charName); - break; - case textOutLatin1: - c1 = isoLatin1Encoding.getCharCode(charName); - break; - case textOutLatin2: - c1 = isoLatin2Encoding.getCharCode(charName); - break; - case textOutLatin5: - c1 = isoLatin5Encoding.getCharCode(charName); - break; - } - if (c1 < 0) { - m = strlen(charName); - if (hexCodes && m == 3 && - (charName[0] == 'B' || charName[0] == 'C' || - charName[0] == 'G') && - isxdigit(charName[1]) && isxdigit(charName[2])) { - sscanf(charName+1, "%x", &c1); - } else if (hexCodes && m == 2 && - isxdigit(charName[0]) && isxdigit(charName[1])) { - sscanf(charName, "%x", &c1); - } else if (!hexCodes && m >= 2 && m <= 3 && - isdigit(charName[0]) && isdigit(charName[1])) { - c1 = atoi(charName); - if (c1 >= 256) { - c1 = -1; - } - } else if (m >= 3 && m <= 5 && isdigit(charName[1])) { - c1 = atoi(charName+1); - if (c1 >= 256) { - c1 = -1; - } - } - //~ this is a kludge -- is there a standard internal encoding - //~ used by all/most Type 1 fonts? - if (c1 == 262) // hyphen - c1 = 45; - else if (c1 == 266) // emdash - c1 = 208; - if (c1 >= 0) { - charName = isoLatin1Encoding.getCharName(c1); - if (charName) { - switch (charSet) { - case textOutASCII7: - c1 = ascii7Encoding.getCharCode(charName); - break; - case textOutLatin1: - // no translation - break; - case textOutLatin2: - c1 = isoLatin2Encoding.getCharCode(charName); - break; - case textOutLatin5: - c1 = isoLatin5Encoding.getCharCode(charName); - break; - } - } else { - c1 = -1; - } - } - } - switch (charSet) { - case textOutASCII7: - if (c1 >= 128) { - sub = ascii7Subst[c1 - 128]; - n = strlen(sub); - } - break; - case textOutLatin1: - if (c1 >= 256) { - sub = isoLatin1Subst[c1 - 256]; - n = strlen(sub); - } - break; - case textOutLatin2: - if (c1 >= 256) { - sub = isoLatin2Subst[c1 - 256]; - n = strlen(sub); - } - break; - case textOutLatin5: - if (c1 >= 256) { - sub = isoLatin5Subst[c1 - 256]; - n = strlen(sub); - } - break; - } - } else { - c1 = -1; + double dx, double dy, Unicode u) { + if (len == size) { + size += 16; + text = (Unicode *)grealloc(text, size * sizeof(Unicode)); + xRight = (double *)grealloc(xRight, size * sizeof(double)); } - if (sub) - text->append(sub); - else if (c1 >= ' ') - text->append((char)c1); - else - text->append(' '); - - // update position information - if (i+n > ((i+15) & ~15)) - xRight = (double *)grealloc(xRight, ((i+n+15) & ~15) * sizeof(double)); - if (i == 0) + text[len] = u; + if (len == 0) { xMin = x; - for (j = 0; j < n; ++j) - xRight[i+j] = x + ((j+1) * dx) / n; - xMax = x + dx; -} - -void TextString::addChar16(GfxState *state, double x, double y, - double dx, double dy, - int c, GfxFontCharSet16 charSet) { - int c1, t1, t2; - int sub[8]; - char *p; - int *q; - int i, j, n; - - // get current index - i = text->getLength(); - - // convert the 16-bit character - c1 = 0; - sub[0] = 0; - switch (charSet) { - - // convert Adobe-Japan1-2 to JIS X 0208-1983 - case font16AdobeJapan12: -#if JAPANESE_SUPPORT - if (c <= 96) { - c1 = 0x8080 + japan12Map[c]; - } else if (c <= 632) { - if (c <= 230) - c1 = 0; - else if (c <= 324) - c1 = 0x8080 + japan12Map[c - 230]; - else if (c <= 421) - c1 = 0x8080 + japan12KanaMap1[c - 325]; - else if (c <= 500) - c1 = 0; - else if (c <= 598) - c1 = 0x8080 + japan12KanaMap2[c - 501]; - else - c1 = 0; - } else if (c <= 1124) { - if (c <= 779) { - if (c <= 726) - c1 = 0xa1a1 + (c - 633); - else if (c <= 740) - c1 = 0xa2a1 + (c - 727); - else if (c <= 748) - c1 = 0xa2ba + (c - 741); - else if (c <= 755) - c1 = 0xa2ca + (c - 749); - else if (c <= 770) - c1 = 0xa2dc + (c - 756); - else if (c <= 778) - c1 = 0xa2f2 + (c - 771); - else - c1 = 0xa2fe; - } else if (c <= 841) { - if (c <= 789) - c1 = 0xa3b0 + (c - 780); - else if (c <= 815) - c1 = 0xa3c1 + (c - 790); - else - c1 = 0xa3e1 + (c - 816); - } else if (c <= 1010) { - if (c <= 924) - c1 = 0xa4a1 + (c - 842); - else - c1 = 0xa5a1 + (c - 925); - } else { - if (c <= 1034) - c1 = 0xa6a1 + (c - 1011); - else if (c <= 1058) - c1 = 0xa6c1 + (c - 1035); - else if (c <= 1091) - c1 = 0xa7a1 + (c - 1059); - else - c1 = 0xa7d1 + (c - 1092); - } - } else if (c <= 4089) { - t1 = (c - 1125) / 94; - t2 = (c - 1125) % 94; - c1 = 0xb0a1 + (t1 << 8) + t2; - } else if (c <= 7477) { - t1 = (c - 4090) / 94; - t2 = (c - 4090) % 94; - c1 = 0xd0a1 + (t1 << 8) + t2; - } else if (c <= 7554) { - c1 = 0; - } else if (c <= 7563) { // circled Arabic numbers 1..9 - c1 = 0xa3b1 + (c - 7555); - } else if (c <= 7574) { // circled Arabic numbers 10..20 - t1 = c - 7564 + 10; - sub[0] = 0xa3b0 + (t1 / 10); - sub[1] = 0xa3b0 + (t1 % 10); - sub[2] = 0; - c1 = -1; - } else if (c <= 7584) { // Roman numbers I..X - for (p = japan12Roman[c - 7575], q = sub; *p; ++p, ++q) { - *q = 0xa380 + *p; - } - *q = 0; - c1 = -1; - } else if (c <= 7632) { - if (c <= 7600) { - c1 = 0; - } else if (c <= 7606) { - for (p = japan12Abbrev1[c - 7601], q = sub; *p; ++p, ++q) { - *q = 0xa380 + *p; - } - *q = 0; - c1 = -1; - } else { - c1 = 0; - } - } else { - c1 = 0; - } -#if 0 //~ - if (c1 == 0) { - error(-1, "Unsupported Adobe-Japan1-2 character: %d", c); - } -#endif -#endif // JAPANESE_SUPPORT - break; - - case font16AdobeGB12: -#if CHINESE_GB_SUPPORT -#endif - break; - - case font16AdobeCNS13: -#if CHINESE_CNS_SUPPORT - if (c <= 98) { - c1 = cns13Map1[c]; - } else if (c <= 502) { - if (c == 247) { - c1 = 0xa1f7; - } else if (c == 248) { - c1 = 0xa1f6; - } else { - t1 = (c - 99) / 157; - t2 = (c - 99) % 157; - if (t2 <= 62) { - c1 = 0xa140 + (t1 << 8) + t2; - } else { - c1 = 0xa162 + (t1 << 8) + t2; - } - } - } else if (c <= 505) { - c1 = 0xa3bd + (c - 503); - } else if (c <= 594) { - c1 = 0; - } else if (c <= 5995) { - if (c == 2431) { - c1 = 0xacfe; - } else if (c == 4308) { - c1 = 0xbe52; - } else if (c == 5221) { - c1 = 0xc2cb; - } else if (c == 5495) { - c1 = 0xc456; - } else if (c == 5550) { - c1 = 0xc3ba; - } else if (c == 5551) { - c1 = 0xc3b9; - } else { - if (c >= 2007 && c <= 2430) { - t1 = c - 594; - } else if (c >= 4309 && c <= 4695) { - t1 = c - 596; - } else if (c >= 5222 && c <= 5410) { - t1 = c - 596; - } else if (c >= 5496 && c <= 5641) { - t1 = c - 596; - } else { - t1 = c - 595; - } - t2 = t1 % 157; - t1 /= 157; - if (t2 <= 62) { - c1 = 0xa440 + (t1 << 8) + t2; - } else { - c1 = 0xa462 + (t1 << 8) + t2; - } - } - } else if (c <= 13645) { - if (c == 6039) { - c1 = 0xc9be; - } else if (c == 6134) { - c1 = 0xcaf7; - } else if (c == 8142) { - c1 = 0xdadf; - } else if (c == 8788) { - c1 = 0xd6cc; - } else if (c == 8889) { - c1 = 0xd77a; - } else if (c == 10926) { - c1 = 0xebf1; - } else if (c == 11073) { - c1 = 0xecde; - } else if (c == 11361) { - c1 = 0xf0cb; - } else if (c == 11719) { - c1 = 0xf056; - } else if (c == 12308) { - c1 = 0xeeeb; - } else if (c == 12526) { - c1 = 0xf4b5; - } else if (c == 12640) { - c1 = 0xf16b; - } else if (c == 12783) { - c1 = 0xf268; - } else if (c == 12900) { - c1 = 0xf663; - } else if (c == 13585) { - c1 = 0xf9c4; - } else if (c == 13641) { - c1 = 0xf9c6; - } else { - if (c >= 6006 && c <= 6038) { - t1 = c - 5995; - } else if (c >= 6088 && c <= 6133) { - t1 = c - 5995; - } else if (c >= 6302 && c <= 8250) { - t1 = c - 5995; - } else if (c >= 8251 && c <= 8888) { - t1 = c - 5994; - } else if (c >= 8890 && c <= 9288) { - t1 = c - 5995; - } else if (c >= 9289 && c <= 10925) { - t1 = c - 5994; - } else if (c >= 10927 && c <= 11072) { - t1 = c - 5995; - } else if (c >= 11362 && c <= 11477) { - t1 = c - 5997; - } else if (c >= 11615 && c <= 11718) { - t1 = c - 5995; - } else if (c >= 11942 && c <= 12139) { - t1 = c - 5995; - } else if (c >= 12140 && c <= 12221) { - t1 = c - 5994; - } else if (c >= 12222 && c <= 12307) { - t1 = c - 5993; - } else if (c >= 12309 && c <= 12316) { - t1 = c - 5994; - } else if (c >= 12317 && c <= 12469) { - t1 = c - 5993; - } else if (c >= 12470 && c <= 12525) { - t1 = c - 5992; - } else if (c >= 12527 && c <= 12639) { - t1 = c - 5993; - } else if (c >= 12641 && c <= 12782) { - t1 = c - 5994; - } else if (c >= 12784 && c <= 12828) { - t1 = c - 5995; - } else if (c >= 12829 && c <= 12899) { - t1 = c - 5994; - } else if (c >= 12901 && c <= 13094) { - t1 = c - 5995; - } else if (c >= 13095 && c <= 13584) { - t1 = c - 5994; - } else if (c >= 13586 && c <= 13628) { - t1 = c - 5995; - } else if (c == 13629) { - t1 = c - 5994; - } else if (c >= 13630 && c <= 13640) { - t1 = c - 5993; - } else if (c >= 13642 && c <= 13645) { - t1 = c - 5994; - } else { - t1 = c - 5996; - } - t2 = t1 % 157; - t1 /= 157; - if (t2 <= 62) { - c1 = 0xc940 + (t1 << 8) + t2; - } else { - c1 = 0xc962 + (t1 << 8) + t2; - } - } - } else if (c == 13646) { - c1 = 0xa14b; - } else if (c == 13647) { - c1 = 0xa1e3; - } else if (c <= 13742) { - c1 = cns13Map2[c - 13648]; - } else if (c <= 13746) { - c1 = 0xa159 + (c - 13743); - } else if (c <= 14055) { - c1 = 0; - } else if (c <= 14062) { - c1 = 0xf9d6 + (c - 14056); - } -#if 1 //~ - if (c1 == 0) { - error(-1, "Unsupported Adobe-CNS1-3 character: %d", c); - } -#endif -#endif - break; } - - // append converted character to string - if (c1 == 0) { - text->append(' '); - n = 1; - } else if (c1 > 0) { - text->append(c1 >> 8); - text->append(c1 & 0xff); - n = 2; - } else { - n = 0; - for (q = sub; *q; ++q) { - text->append(*q >> 8); - text->append(*q & 0xff); - n += 2; - } - } - - // update position information - if (i+n > ((i+15) & ~15)) { - xRight = (double *)grealloc(xRight, ((i+n+15) & ~15) * sizeof(double)); - } - if (i == 0) { - xMin = x; - } - for (j = 0; j < n; ++j) { - xRight[i+j] = x + dx; - } - xMax = x + dx; + xMax = xRight[len] = x + dx; + ++len; } //------------------------------------------------------------------------ // TextPage //------------------------------------------------------------------------ -TextPage::TextPage(TextOutputCharSet charSet, GBool rawOrder) { - this->charSet = charSet; - this->rawOrder = rawOrder; +TextPage::TextPage(GBool rawOrderA) { + rawOrder = rawOrderA; curStr = NULL; + fontSize = 0; yxStrings = NULL; xyStrings = NULL; yxCur1 = yxCur2 = NULL; @@ -761,7 +100,43 @@ TextPage::~TextPage() { clear(); } -void TextPage::beginString(GfxState *state, GString *s, GBool hexCodes) { +void TextPage::updateFont(GfxState *state) { + GfxFont *font; + double *fm; + char *name; + int code; + double w; + + // adjust the font size + fontSize = state->getTransformedFontSize(); + if ((font = state->getFont()) && font->getType() == fontType3) { + // This is a hack which makes it possible to deal with some Type 3 + // fonts. The problem is that it's impossible to know what the + // base coordinate system used in the font is without actually + // rendering the font. This code tries to guess by looking at the + // width of the character 'm' (which breaks if the font is a + // subset that doesn't contain 'm'). + for (code = 0; code < 256; ++code) { + if ((name = ((Gfx8BitFont *)font)->getCharName(code)) && + name[0] == 'm' && name[1] == '\0') { + break; + } + } + if (code < 256) { + w = ((Gfx8BitFont *)font)->getWidth(code); + if (w != 0) { + // 600 is a generic average 'm' width -- yes, this is a hack + fontSize *= w / 0.6; + } + } + fm = font->getFontMatrix(); + if (fm[0] != 0) { + fontSize *= fabs(fm[3] / fm[0]); + } + } +} + +void TextPage::beginString(GfxState *state) { // This check is needed because Type 3 characters can contain // text-drawing operations. if (curStr) { @@ -769,56 +144,41 @@ void TextPage::beginString(GfxState *state, GString *s, GBool hexCodes) { return; } - curStr = new TextString(state, hexCodes); + curStr = new TextString(state, fontSize); } void TextPage::addChar(GfxState *state, double x, double y, - double dx, double dy, Guchar c) { + double dx, double dy, Unicode *u, int uLen) { double x1, y1, w1, h1, dx2, dy2; - int n; - GBool hexCodes; + int n, i; state->transform(x, y, &x1, &y1); - state->textTransformDelta(state->getCharSpace(), 0, &dx2, &dy2); - dx -= dx2; - dy -= dy2; - state->transformDelta(dx, dy, &w1, &h1); - n = curStr->text->getLength(); + n = curStr->len; if (n > 0 && x1 - curStr->xRight[n-1] > 0.1 * (curStr->yMax - curStr->yMin)) { - hexCodes = curStr->hexCodes; endString(); - beginString(state, NULL, hexCodes); + beginString(state); } - curStr->addChar(state, x1, y1, w1, h1, c, charSet); -} - -void TextPage::addChar16(GfxState *state, double x, double y, - double dx, double dy, int c, - GfxFontCharSet16 charSet) { - double x1, y1, w1, h1, dx2, dy2; - int n; - GBool hexCodes; - - state->transform(x, y, &x1, &y1); - state->textTransformDelta(state->getCharSpace(), 0, &dx2, &dy2); + state->textTransformDelta(state->getCharSpace() * state->getHorizScaling(), + 0, &dx2, &dy2); dx -= dx2; dy -= dy2; state->transformDelta(dx, dy, &w1, &h1); - n = curStr->text->getLength(); - if (n > 0 && - x1 - curStr->xRight[n-1] > 0.1 * (curStr->yMax - curStr->yMin)) { - hexCodes = curStr->hexCodes; - endString(); - beginString(state, NULL, hexCodes); + if (uLen != 0) { + w1 /= uLen; + h1 /= uLen; + } + for (i = 0; i < uLen; ++i) { + curStr->addChar(state, x1 + i*w1, y1 + i*h1, w1, h1, u[i]); } - curStr->addChar16(state, x1, y1, w1, h1, c, charSet); } void TextPage::endString() { TextString *p1, *p2; double h, y1, y2; + // This check is needed because Type 3 characters can contain + // text-drawing operations. if (nest > 0) { --nest; return; @@ -826,7 +186,7 @@ void TextPage::endString() { // throw away zero-length strings -- they don't have valid xMin/xMax // values, and they're useless anyway - if (curStr->text->getLength() == 0) { + if (curStr->len == 0) { delete curStr; curStr = NULL; return; @@ -849,16 +209,18 @@ void TextPage::endString() { p2 = yxCur2; } else { for (p1 = NULL, p2 = yxStrings; p2; p1 = p2, p2 = p2->yxNext) { - if (y1 < p2->yMin || (y2 < p2->yMax && curStr->xMax < p2->xMin)) + if (y1 < p2->yMin || (y2 < p2->yMax && curStr->xMax < p2->xMin)) { break; + } } yxCur2 = p2; } yxCur1 = curStr; - if (p1) + if (p1) { p1->yxNext = curStr; - else + } else { yxStrings = curStr; + } curStr->yxNext = p2; curStr = NULL; } @@ -866,13 +228,18 @@ void TextPage::endString() { void TextPage::coalesce() { TextString *str1, *str2; double space, d; + GBool addSpace; int n, i; #if 0 //~ for debugging for (str1 = yxStrings; str1; str1 = str1->yxNext) { - printf("x=%3d..%3d y=%3d..%3d size=%2d '%s'\n", + printf("x=%3d..%3d y=%3d..%3d size=%2d '", (int)str1->xMin, (int)str1->xMax, (int)str1->yMin, (int)str1->yMax, - (int)(str1->yMax - str1->yMin), str1->text->getCString()); + (int)(str1->yMax - str1->yMin)); + for (i = 0; i < str1->len; ++i) { + fputc(str1->text[i] & 0xff, stdout); + } + printf("'\n"); } printf("\n------------------------------------------------------------\n\n"); #endif @@ -885,21 +252,31 @@ void TextPage::coalesce() { (str2->yMax >= str1->yMin && str2->yMax <= str1->yMax))) || (!rawOrder && str2->yMin < str1->yMax)) && d > -0.5 * space && d < space) { - n = str1->text->getLength(); - if (d > 0.1 * space) - str1->text->append(' '); - str1->text->append(str2->text); - str1->xRight = (double *) - grealloc(str1->xRight, - ((str1->text->getLength() + 15) & ~15) * sizeof(double)); - if (d > 0.1 * space) - str1->xRight[n++] = str2->xMin; - for (i = 0; i < str2->text->getLength(); ++i) - str1->xRight[n++] = str2->xRight[i]; - if (str2->xMax > str1->xMax) + n = str1->len + str2->len; + if ((addSpace = d > 0.1 * space)) { + ++n; + } + str1->size = (n + 15) & ~15; + str1->text = (Unicode *)grealloc(str1->text, + str1->size * sizeof(Unicode)); + str1->xRight = (double *)grealloc(str1->xRight, + str1->size * sizeof(double)); + if (addSpace) { + str1->text[str1->len] = 0x20; + str1->xRight[str1->len] = str2->xMin; + ++str1->len; + } + for (i = 0; i < str2->len; ++i) { + str1->text[str1->len] = str2->text[i]; + str1->xRight[str1->len] = str2->xRight[i]; + ++str1->len; + } + if (str2->xMax > str1->xMax) { str1->xMax = str2->xMax; - if (str2->yMax > str1->yMax) + } + if (str2->yMax > str1->yMax) { str1->yMax = str2->yMax; + } str1->yxNext = str2->yxNext; delete str2; } else { @@ -908,56 +285,75 @@ void TextPage::coalesce() { } } -GBool TextPage::findText(char *s, GBool top, GBool bottom, +GBool TextPage::findText(Unicode *s, int len, + GBool top, GBool bottom, double *xMin, double *yMin, double *xMax, double *yMax) { TextString *str; - char *p, *p1, *q; - int n, m, i; + Unicode *p; + Unicode u1, u2; + int m, i, j; double x; // scan all strings on page - n = strlen(s); for (str = yxStrings; str; str = str->yxNext) { // check: above top limit? if (!top && (str->yMax < *yMin || - (str->yMin < *yMin && str->xMax <= *xMin))) + (str->yMin < *yMin && str->xMax <= *xMin))) { continue; + } // check: below bottom limit? if (!bottom && (str->yMin > *yMax || - (str->yMax > *yMax && str->xMin >= *xMax))) + (str->yMax > *yMax && str->xMin >= *xMax))) { return gFalse; + } // search each position in this string - m = str->text->getLength(); - for (i = 0, p = str->text->getCString(); i <= m - n; ++i, ++p) { + m = str->len; + for (i = 0, p = str->text; i <= m - len; ++i, ++p) { // check: above top limit? if (!top && str->yMin < *yMin) { x = (((i == 0) ? str->xMin : str->xRight[i-1]) + str->xRight[i]) / 2; - if (x < *xMin) + if (x < *xMin) { continue; + } } // check: below bottom limit? if (!bottom && str->yMax > *yMax) { x = (((i == 0) ? str->xMin : str->xRight[i-1]) + str->xRight[i]) / 2; - if (x > *xMax) + if (x > *xMax) { return gFalse; + } } // compare the strings - for (p1 = p, q = s; *q; ++p1, ++q) { - if (tolower(*p1) != tolower(*q)) + for (j = 0; j < len; ++j) { +#if 1 //~ this lowercases Latin A-Z only -- this will eventually be + //~ extended to handle other character sets + if (p[j] >= 0x41 && p[j] <= 0x5a) { + u1 = p[j] + 0x20; + } else { + u1 = p[j]; + } + if (s[j] >= 0x41 && s[j] <= 0x5a) { + u2 = s[j] + 0x20; + } else { + u2 = s[j]; + } +#endif + if (u1 != u2) { break; + } } // found it - if (!*q) { + if (j == len) { *xMin = (i == 0) ? str->xMin : str->xRight[i-1]; - *xMax = str->xRight[i+n-1]; + *xMax = str->xRight[i + len - 1]; *yMin = str->yMin; *yMax = str->yMax; return gTrue; @@ -970,65 +366,108 @@ GBool TextPage::findText(char *s, GBool top, GBool bottom, GString *TextPage::getText(double xMin, double yMin, double xMax, double yMax) { GString *s; + UnicodeMap *uMap; + char space[8], eol[16], buf[8]; + int spaceLen, eolLen, n; TextString *str1; double x0, x1, x2, y; double xPrev, yPrev; - int i1, i2; + int i1, i2, i; GBool multiLine; s = new GString(); + if (!(uMap = globalParams->getTextEncoding())) { + return s; + } + spaceLen = uMap->mapUnicode(0x20, space, sizeof(space)); + eolLen = 0; // make gcc happy + switch (globalParams->getTextEOL()) { + case eolUnix: + eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol)); + break; + case eolDOS: + eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); + eolLen += uMap->mapUnicode(0x0a, eol + eolLen, sizeof(eol) - eolLen); + break; + case eolMac: + eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); + break; + } xPrev = yPrev = 0; multiLine = gFalse; for (str1 = yxStrings; str1; str1 = str1->yxNext) { y = 0.5 * (str1->yMin + str1->yMax); - if (y > yMax) + if (y > yMax) { break; + } if (y > yMin && str1->xMin < xMax && str1->xMax > xMin) { x0 = x1 = x2 = str1->xMin; - for (i1 = 0; i1 < str1->text->getLength(); ++i1) { + for (i1 = 0; i1 < str1->len; ++i1) { x0 = (i1==0) ? str1->xMin : str1->xRight[i1-1]; x1 = str1->xRight[i1]; - if (0.5 * (x0 + x1) >= xMin) + if (0.5 * (x0 + x1) >= xMin) { break; + } } - for (i2 = str1->text->getLength() - 1; i2 > i1; --i2) { + for (i2 = str1->len - 1; i2 > i1; --i2) { x1 = (i2==0) ? str1->xMin : str1->xRight[i2-1]; x2 = str1->xRight[i2]; - if (0.5 * (x1 + x2) <= xMax) + if (0.5 * (x1 + x2) <= xMax) { break; + } } if (s->getLength() > 0) { if (x0 < xPrev || str1->yMin > yPrev) { -#ifdef MACOS - s->append('\r'); -#else - s->append('\n'); -#endif + s->append(eol, eolLen); multiLine = gTrue; } else { - s->append(" "); + for (i = 0; i < 4; ++i) { + s->append(space, spaceLen); + } } } - s->append(str1->text->getCString() + i1, i2 - i1 + 1); + for (i = i1; i <= i2; ++i) { + n = uMap->mapUnicode(str1->text[i], buf, sizeof(buf)); + s->append(buf, n); + } xPrev = x2; yPrev = str1->yMax; } } if (multiLine) { -#ifdef MACOS - s->append('\r'); -#else - s->append('\n'); -#endif + s->append(eol, eolLen); } + uMap->decRefCnt(); return s; } -void TextPage::dump(FILE *f) { +void TextPage::dump(void *outputStream, TextOutputFunc outputFunc) { + UnicodeMap *uMap; + char space[8], eol[16], eop[8], buf[8]; + int spaceLen, eolLen, eopLen, n; TextString *str1, *str2, *str3; double yMin, yMax; - int col1, col2; - double d; + int col1, col2, d, i; + + // get the output encoding + if (!(uMap = globalParams->getTextEncoding())) { + return; + } + spaceLen = uMap->mapUnicode(0x20, space, sizeof(space)); + eolLen = 0; // make gcc happy + switch (globalParams->getTextEOL()) { + case eolUnix: + eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol)); + break; + case eolDOS: + eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); + eolLen += uMap->mapUnicode(0x0a, eol + eolLen, sizeof(eol) - eolLen); + break; + case eolMac: + eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); + break; + } + eopLen = uMap->mapUnicode(0x0c, eop, sizeof(eop)); // build x-major list xyStrings = NULL; @@ -1037,13 +476,15 @@ void TextPage::dump(FILE *f) { str3; str2 = str3, str3 = str3->xyNext) { if (str1->xMin < str3->xMin || - (str1->xMin == str3->xMin && str1->yMin < str3->yMin)) + (str1->xMin == str3->xMin && str1->yMin < str3->yMin)) { break; + } } - if (str2) + if (str2) { str2->xyNext = str1; - else + } else { xyStrings = str1; + } str1->xyNext = str3; } @@ -1052,13 +493,14 @@ void TextPage::dump(FILE *f) { col1 = 0; for (str2 = xyStrings; str2 != str1; str2 = str2->xyNext) { if (str1->xMin >= str2->xMax) { - col2 = str2->col + str2->text->getLength() + 4; - if (col2 > col1) + col2 = str2->col + str2->len + 4; + if (col2 > col1) { col1 = col2; + } } else if (str1->xMin > str2->xMin) { col2 = str2->col + (int)(((str1->xMin - str2->xMin) / (str2->xMax - str2->xMin)) * - str2->text->getLength()); + str2->len); if (col2 > col1) { col1 = col2; } @@ -1068,13 +510,17 @@ void TextPage::dump(FILE *f) { } #if 0 //~ for debugging - fprintf(f, "~~~~~~~~~~\n"); + fprintf((FILE *)outputStream, "~~~~~~~~~~\n"); for (str1 = yxStrings; str1; str1 = str1->yxNext) { - fprintf(f, "(%4d,%4d) - (%4d,%4d) [%3d] %s\n", - (int)str1->xMin, (int)str1->yMin, (int)str1->xMax, (int)str1->yMax, - str1->col, str1->text->getCString()); + fprintf((FILE *)outputStream, "(%4d,%4d) - (%4d,%4d) [%3d] '", + (int)str1->xMin, (int)str1->yMin, + (int)str1->xMax, (int)str1->yMax, str1->col); + for (i = 0; i < str1->len; ++i) { + fputc(str1->text[i] & 0xff, stdout); + } + printf("'\n"); } - fprintf(f, "~~~~~~~~~~\n"); + fprintf((FILE *)outputStream, "~~~~~~~~~~\n"); #endif // output @@ -1087,19 +533,24 @@ void TextPage::dump(FILE *f) { col1 = str1->col; } else { for (; col1 < str1->col; ++col1) { - fputc(' ', f); + (*outputFunc)(outputStream, space, spaceLen); } } // print the string - fputs(str1->text->getCString(), f); + for (i = 0; i < str1->len; ++i) { + if ((n = uMap->mapUnicode(str1->text[i], buf, sizeof(buf))) > 0) { + (*outputFunc)(outputStream, buf, n); + } + } // increment column - col1 += str1->text->getLength(); + col1 += str1->len; // update yMax for this line - if (str1->yMax > yMax) + if (str1->yMax > yMax) { yMax = str1->yMax; + } // if we've hit the end of the line... if (!(str1->yxNext && @@ -1108,7 +559,7 @@ void TextPage::dump(FILE *f) { str1->yxNext->xMin >= str1->xMax)) { // print a return - fputc('\n', f); + (*outputFunc)(outputStream, eol, eolLen); // print extra vertical space if necessary if (str1->yxNext) { @@ -1116,8 +567,9 @@ void TextPage::dump(FILE *f) { // find yMin for next line yMin = str1->yxNext->yMin; for (str2 = str1->yxNext; str2; str2 = str2->yxNext) { - if (str2->yMin < yMin) + if (str2->yMin < yMin) { yMin = str2->yMin; + } if (!(str2->yxNext && str2->yxNext->yMin < str2->yMax && str2->yxNext->xMin >= str2->xMax)) break; @@ -1125,11 +577,15 @@ void TextPage::dump(FILE *f) { // print the space d = (int)((yMin - yMax) / (str1->yMax - str1->yMin) + 0.5); + // various things (weird font matrices) can result in bogus + // values here, so do a sanity check if (rawOrder && d > 2) { d = 2; + } else if (!rawOrder && d > 5) { + d = 5; } for (; d > 0; --d) { - fputc('\n', f); + (*outputFunc)(outputStream, eol, eolLen); } } @@ -1138,6 +594,13 @@ void TextPage::dump(FILE *f) { yMax = str1->yxNext ? str1->yxNext->yMax : 0; } } + + // end of page + (*outputFunc)(outputStream, eol, eolLen); + (*outputFunc)(outputStream, eop, eopLen); + (*outputFunc)(outputStream, eol, eolLen); + + uMap->decRefCnt(); } void TextPage::clear() { @@ -1160,38 +623,52 @@ void TextPage::clear() { // TextOutputDev //------------------------------------------------------------------------ -TextOutputDev::TextOutputDev(char *fileName, TextOutputCharSet charSet, - GBool rawOrder) { +static void outputToFile(void *stream, char *text, int len) { + fwrite(text, 1, len, (FILE *)stream); +} + +TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) { text = NULL; - this->rawOrder = rawOrder; + rawOrder = rawOrderA; ok = gTrue; // open file needClose = gFalse; if (fileName) { if (!strcmp(fileName, "-")) { - f = stdout; - } else if ((f = fopen(fileName, "w"))) { + outputStream = stdout; + } else if ((outputStream = fopen(fileName, append ? "ab" : "wb"))) { needClose = gTrue; } else { error(-1, "Couldn't open text file '%s'", fileName); ok = gFalse; return; } + outputFunc = &outputToFile; } else { - f = NULL; + outputStream = NULL; } // set up text object - text = new TextPage(charSet, rawOrder); + text = new TextPage(rawOrder); +} + +TextOutputDev::TextOutputDev(TextOutputFunc func, void *stream, + GBool rawOrderA) { + outputFunc = func; + outputStream = stream; + needClose = gFalse; + rawOrder = rawOrderA; + text = new TextPage(rawOrder); + ok = gTrue; } TextOutputDev::~TextOutputDev() { if (needClose) { #ifdef MACOS - ICS_MapRefNumAndAssign((short)f->handle); + ICS_MapRefNumAndAssign((short)((FILE *)outputStream)->handle); #endif - fclose(f); + fclose((FILE *)outputStream); } if (text) { delete text; @@ -1204,50 +681,17 @@ void TextOutputDev::startPage(int pageNum, GfxState *state) { void TextOutputDev::endPage() { text->coalesce(); - if (f) { - text->dump(f); - fputc('\n', f); - fputs("\f\n", f); - fputc('\n', f); + if (outputStream) { + text->dump(outputStream, outputFunc); } } void TextOutputDev::updateFont(GfxState *state) { - GfxFont *font; - char *charName; - int c; - - // look for hex char codes in subsetted font - hexCodes = gFalse; - if ((font = state->getFont()) && !font->is16Bit()) { - for (c = 0; c < 256; ++c) { - if ((charName = font->getCharName(c))) { - if ((charName[0] == 'B' || charName[0] == 'C' || - charName[0] == 'G') && - strlen(charName) == 3 && - isxdigit(charName[1]) && isxdigit(charName[2]) && - ((charName[1] >= 'a' && charName[1] <= 'f') || - (charName[1] >= 'A' && charName[1] <= 'F') || - (charName[2] >= 'a' && charName[2] <= 'f') || - (charName[2] >= 'A' && charName[2] <= 'F'))) { - hexCodes = gTrue; - break; - } else if ((strlen(charName) == 2) && - isxdigit(charName[0]) && isxdigit(charName[1]) && - ((charName[0] >= 'a' && charName[0] <= 'f') || - (charName[0] >= 'A' && charName[0] <= 'F') || - (charName[1] >= 'a' && charName[1] <= 'f') || - (charName[1] >= 'A' && charName[1] <= 'F'))) { - hexCodes = gTrue; - break; - } - } - } - } + text->updateFont(state); } void TextOutputDev::beginString(GfxState *state, GString *s) { - text->beginString(state, s, hexCodes); + text->beginString(state); } void TextOutputDev::endString(GfxState *state) { @@ -1255,17 +699,15 @@ void TextOutputDev::endString(GfxState *state) { } void TextOutputDev::drawChar(GfxState *state, double x, double y, - double dx, double dy, Guchar c) { - text->addChar(state, x, y, dx, dy, c); -} - -void TextOutputDev::drawChar16(GfxState *state, double x, double y, - double dx, double dy, int c) { - text->addChar16(state, x, y, dx, dy, c, state->getFont()->getCharSet16()); + double dx, double dy, + double originX, double originY, + CharCode c, Unicode *u, int uLen) { + text->addChar(state, x, y, dx, dy, u, uLen); } -GBool TextOutputDev::findText(char *s, GBool top, GBool bottom, +GBool TextOutputDev::findText(Unicode *s, int len, + GBool top, GBool bottom, double *xMin, double *yMin, double *xMax, double *yMax) { - return text->findText(s, top, bottom, xMin, yMin, xMax, yMax); + return text->findText(s, len, top, bottom, xMin, yMin, xMax, yMax); } -- cgit v0.9.1