Changeset 367
- Timestamp:
- Apr 8, 2010, 10:16:54 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 14 deleted
- 11 edited
- 157 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property
svn:ignore
set to
out
LocalConfig.kmk
LocalEnv.cmd
-
Property
svn:mergeinfo
set to
/branches/kmk merged eligible
-
Property
svn:ignore
set to
-
trunk/libdjvu/DjVuGlobal.h
r280 r367 70 70 inline void * operator new(size_t, void * ptr) { return ptr; } 71 71 # endif 72 #elif defined(AUTOCONF) && defined(HAVE_STDINCLUDES)72 #elif (defined(AUTOCONF) || defined(OS2)) && defined(HAVE_STDINCLUDES) 73 73 # include <new> 74 74 #else -
trunk/libdjvu/config.h
r280 r367 131 131 132 132 /* define if the compiler comes with standard includes */ 133 #if defined(__WATCOM__) 133 134 #undef HAVE_STDINCLUDES 135 #else 136 #define HAVE_STDINCLUDES 1 137 #endif 134 138 135 139 /* Define to 1 if you have the <stdint.h> header file. */ -
trunk/poppler/fc-emulate-os2/fontconfig/fontconfig.cpp
r272 r367 22 22 #define INCL_DOS 23 23 #define INCL_WIN 24 #if defined(__EMX__) 25 #define OS2EMX_PLAIN_CHAR 26 #endif 24 27 #include <os2.h> 25 28 … … 29 32 30 33 #include <stdio.h> 34 #include <string.h> 35 36 #if defined( __WATCOMC__ ) 31 37 #include <dos.h> 32 #include <string.h> 38 #else 39 #include <io.h> 40 #include <sys/stat.h> 41 #endif 33 42 34 43 #include "fontconfig.h" … … 247 256 248 257 string key = familyName; 249 if ( stricmp( styleName.c_str(), "regular" ) != 0 ) { 258 if ( stricmp( styleName.c_str(), "regular" ) != 0 && 259 stricmp( styleName.c_str(), "book" ) != 0 ) { 250 260 key += ' '; 251 261 key += styleName; … … 278 288 char dir[ _MAX_DIR ]; 279 289 char fname[ _MAX_FNAME ]; 290 #if defined( __WATCOMC__ ) 280 291 _splitpath( __argv[0], drive, dir, fname, NULL ); 292 #else 293 _execname( fullpath, sizeof(fullpath) ); 294 _splitpath( fullpath, drive, dir, fname, NULL ); 295 #endif 281 296 strlwr( fname ); 282 297 _makepath( fullpath, drive, dir, fname, ".fcf" ); … … 435 450 #define DEFAULT_SANSSERIF_FONT "helvetica" 436 451 #define DEFAULT_MONOSPACED_FONT "courier" 452 #define DEFAULT_SYMBOL_FONT "symbol set" 437 453 438 454 static bool isSansserif( const char *family ) … … 445 461 } 446 462 447 static string buildFontKey( FcPattern *p , bool useDefaultFonts)463 static string buildFontKey( FcPattern *p ) 448 464 { 449 465 string key = p->family; 450 466 451 if ( useDefaultFonts ) 452 { 467 // From http://en.wikipedia.org/wiki/Portable_Document_Format: 468 // 469 // There are fourteen typefaces that have a special significance to PDF 470 // documents: 471 // 472 // * Times (v3) (in regular, italic, bold, and bold italic) 473 // * Courier (in regular, oblique, bold and bold oblique) 474 // * Helvetica (v3) (in regular, oblique, bold and bold oblique) 475 // * Symbol 476 // * Zapf Dingbats 477 // 478 // These fonts, sometimes referred to as the "base fourteen fonts" should 479 // always be present (actually present or a close substitute) and so need 480 // not be embedded in a PDF.[46] PDF viewers must know about the metrics 481 // of these fonts. Other fonts may be substituted if they are not embedded 482 // in a PDF. 483 // 484 // The following code is based on this information and guarantees that we 485 // always return a valid font for those (except Zapf Dingbats for which we 486 // don't have a pre-installed OS/2 font). 487 488 bool ignoreStyle = false; 489 490 if ( fontmap->find( key ) == fontmap->end() ) { 491 // not found: try substitutions 453 492 if ( p->spacing == FC_MONO ) { 454 493 key = DEFAULT_MONOSPACED_FONT; 455 } 456 else 457 { 494 } else { 458 495 if ( isSansserif( p->family ) ) { 459 496 key = DEFAULT_SANSSERIF_FONT; 497 } else { 498 if ( key == "symbol" ) { 499 ignoreStyle = true; 500 key = "opensymbol"; 501 if ( fontmap->find( key ) == fontmap->end() ) 502 key = DEFAULT_SYMBOL_FONT; 503 } else if ( key == "zapfdingbats" || key == "zapf dingbats" ) { 504 ignoreStyle = true; 505 key = "dejavu sans"; 506 // last resort, quite meaningless but we must provide something 507 if ( fontmap->find( key ) == fontmap->end() ) 508 key = DEFAULT_SYMBOL_FONT; 509 } else { 510 key = DEFAULT_SERIF_FONT; 511 } 460 512 } 461 else { 462 key = DEFAULT_SERIF_FONT; 463 } 464 } 465 } 466 else 467 { 468 // use 'Symbol Set' (SYMB.PFB) instead of 'Symbol' 469 if ( strcmp( p->family, "symbol" ) == 0 ) { 470 key = "symbol set"; 471 } 472 } 473 474 if ( p->weight > FC_WEIGHT_NORMAL ) { 475 key += ' '; 476 key += "bold"; 477 } 478 479 if ( (p->slant == FC_SLANT_ITALIC) || (p->slant == FC_SLANT_OBLIQUE) ) { 480 key += ' '; 481 key += "italic"; 513 } 514 515 } 516 517 if ( !ignoreStyle ) { 518 if ( p->weight > FC_WEIGHT_NORMAL ) { 519 key += ' '; 520 key += "bold"; 521 } 522 if ( (p->slant == FC_SLANT_ITALIC) || (p->slant == FC_SLANT_OBLIQUE) ) { 523 key += ' '; 524 key += "italic"; 525 } 482 526 } 483 527 … … 497 541 pat->filename = NULL; 498 542 499 string key = buildFontKey( pat, false ); 500 501 if ( fontmap->find( key ) == fontmap->end() ) { 502 key = buildFontKey( pat, true ); 503 pat->filename = newstrdup( (*fontmap)[ key ].c_str() ); 504 } 505 else { 506 pat->filename = newstrdup( (*fontmap)[ key ].c_str() ); 507 } 543 string key = buildFontKey( pat ); 544 pat->filename = newstrdup( (*fontmap)[ key ].c_str() ); 508 545 509 546 //printf( "MATCHED STYLE: %s, FILENAME: %s\n", key.c_str(), pat->filename ); -
trunk/poppler/fc-emulate-os2/fontconfig/fontconfig.h
r71 r367 23 23 #define _ERFONTCONFIG_H_ 24 24 25 typedef unsigned charFcChar8;26 typedef unsigned shortFcChar16;27 typedef unsigned intFcChar32;28 typedef int 25 typedef char FcChar8; 26 typedef short FcChar16; 27 typedef int FcChar32; 28 typedef int FcBool; 29 29 30 30 -
trunk/poppler/mypoppler/config.h
r250 r367 14 14 #undef HAVE_CAIRO 15 15 16 /* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'. 17 */ 16 /* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'. */ 17 #if defined(__WATCOMC__) 18 18 #undef HAVE_DIRENT_H 19 #else 20 #define HAVE_DIRENT_H 1 21 #endif 19 22 20 23 #define HAVE_DIRECT_H 1 -
trunk/poppler/mypoppler/goo/gstrtod.cc
r290 r367 26 26 #include <locale.h> 27 27 #include <errno.h> 28 #include <stdlib >28 #include <stdlib.h> 29 29 #include <string.h> 30 30 -
trunk/poppler/mypoppler/poppler/GfxFont.cc
r277 r367 542 542 char *charName; 543 543 GBool missing, hex; 544 char alpha; 544 545 Unicode toUnicode[256]; 545 546 CharCodeToUnicode *utu, *ctu2; … … 827 828 828 829 // pass 1: use the name-to-Unicode mapping table 829 missing = hex = gFalse; 830 missing = gFalse; 831 hex = gTrue; 832 alpha = -1; 830 833 for (code = 0; code < 256; ++code) { 831 834 if ((charName = enc[code])) { … … 834 837 // if it wasn't in the name-to-Unicode table, check for a 835 838 // name that looks like 'Axx' or 'xx', where 'A' is any letter 836 // and 'xx' is two hex digits 837 if ((strlen(charName) == 3 && 838 isalpha(charName[0]) && 839 isxdigit(charName[1]) && isxdigit(charName[2]) && 840 ((charName[1] >= 'a' && charName[1] <= 'f') || 841 (charName[1] >= 'A' && charName[1] <= 'F') || 842 (charName[2] >= 'a' && charName[2] <= 'f') || 843 (charName[2] >= 'A' && charName[2] <= 'F'))) || 844 (strlen(charName) == 2 && 845 isxdigit(charName[0]) && isxdigit(charName[1]) && 846 ((charName[0] >= 'a' && charName[0] <= 'f') || 847 (charName[0] >= 'A' && charName[0] <= 'F') || 848 (charName[1] >= 'a' && charName[1] <= 'f') || 849 (charName[1] >= 'A' && charName[1] <= 'F')))) { 850 hex = gTrue; 839 // and 'xx' is two hex digits. Be strict and assume that names are 840 // consistent (i.e. either all are 'Axx' or 'xx') 841 if (hex) { 842 if (strlen(charName) == 3 && 843 isalpha(charName[0]) && 844 isxdigit(charName[1]) && isxdigit(charName[2]) && 845 ((charName[1] >= 'a' && charName[1] <= 'f') || 846 (charName[1] >= 'A' && charName[1] <= 'F') || 847 (charName[2] >= 'a' && charName[2] <= 'f') || 848 (charName[2] >= 'A' && charName[2] <= 'F'))) { 849 if (alpha == -1) 850 alpha = charName[0]; 851 else if (alpha != charName[0]) 852 hex = gFalse; 853 } else 854 if (strlen(charName) == 2 && 855 isxdigit(charName[0]) && isxdigit(charName[1]) && 856 ((charName[0] >= 'a' && charName[0] <= 'f') || 857 (charName[0] >= 'A' && charName[0] <= 'F') || 858 (charName[1] >= 'a' && charName[1] <= 'f') || 859 (charName[1] >= 'A' && charName[1] <= 'F'))) { 860 if (alpha == -1) 861 alpha = 0; 862 else if (alpha != 0) 863 hex = gFalse; 864 } else { 865 hex = gFalse; 866 } 851 867 } 852 868 missing = gTrue; -
trunk/poppler/mypoppler/poppler/NameToUnicodeTable.h
r2 r367 1094 1094 {0x007d, "}"}, 1095 1095 {0x007e, "~"}, 1096 // Zapf Dingbats PS character name to Unicode mappings according to: 1097 // http://unicode.org/Public/MAPPINGS/VENDORS/ADOBE/zdingbat.txt 1098 {0x2701, "a1"}, 1099 {0x2702, "a2"}, 1100 {0x2703, "a202"}, 1101 {0x2704, "a3"}, 1102 {0x260E, "a4"}, 1103 {0x2706, "a5"}, 1104 {0x2707, "a119"}, 1105 {0x2708, "a118"}, 1106 {0x2709, "a117"}, 1107 {0x261B, "a11"}, 1108 {0x261E, "a12"}, 1109 {0x270C, "a13"}, 1110 {0x270D, "a14"}, 1111 {0x270E, "a15"}, 1112 {0x270F, "a16"}, 1113 {0x2710, "a105"}, 1114 {0x2711, "a17"}, 1115 {0x2712, "a18"}, 1116 {0x2713, "a19"}, 1117 {0x2714, "a20"}, 1118 {0x2715, "a21"}, 1119 {0x2716, "a22"}, 1120 {0x2717, "a23"}, 1121 {0x2718, "a24"}, 1122 {0x2719, "a25"}, 1123 {0x271A, "a26"}, 1124 {0x271B, "a27"}, 1125 {0x271C, "a28"}, 1126 {0x271D, "a6"}, 1127 {0x271E, "a7"}, 1128 {0x271F, "a8"}, 1129 {0x2720, "a9"}, 1130 {0x2721, "a10"}, 1131 {0x2722, "a29"}, 1132 {0x2723, "a30"}, 1133 {0x2724, "a31"}, 1134 {0x2725, "a32"}, 1135 {0x2726, "a33"}, 1136 {0x2727, "a34"}, 1137 {0x2605, "a35"}, 1138 {0x2729, "a36"}, 1139 {0x272A, "a37"}, 1140 {0x272B, "a38"}, 1141 {0x272C, "a39"}, 1142 {0x272D, "a40"}, 1143 {0x272E, "a41"}, 1144 {0x272F, "a42"}, 1145 {0x2730, "a43"}, 1146 {0x2731, "a44"}, 1147 {0x2732, "a45"}, 1148 {0x2733, "a46"}, 1149 {0x2734, "a47"}, 1150 {0x2735, "a48"}, 1151 {0x2736, "a49"}, 1152 {0x2737, "a50"}, 1153 {0x2738, "a51"}, 1154 {0x2739, "a52"}, 1155 {0x273A, "a53"}, 1156 {0x273B, "a54"}, 1157 {0x273C, "a55"}, 1158 {0x273D, "a56"}, 1159 {0x273E, "a57"}, 1160 {0x273F, "a58"}, 1161 {0x2740, "a59"}, 1162 {0x2741, "a60"}, 1163 {0x2742, "a61"}, 1164 {0x2743, "a62"}, 1165 {0x2744, "a63"}, 1166 {0x2745, "a64"}, 1167 {0x2746, "a65"}, 1168 {0x2747, "a66"}, 1169 {0x2748, "a67"}, 1170 {0x2749, "a68"}, 1171 {0x274A, "a69"}, 1172 {0x274B, "a70"}, 1173 {0x25CF, "a71"}, 1174 {0x274D, "a72"}, 1175 {0x25A0, "a73"}, 1176 {0x274F, "a74"}, 1177 {0x2750, "a203"}, 1178 {0x2751, "a75"}, 1179 {0x2752, "a204"}, 1180 {0x25B2, "a76"}, 1181 {0x25BC, "a77"}, 1182 {0x25C6, "a78"}, 1183 {0x2756, "a79"}, 1184 {0x25D7, "a81"}, 1185 {0x2758, "a82"}, 1186 {0x2759, "a83"}, 1187 {0x275A, "a84"}, 1188 {0x275B, "a97"}, 1189 {0x275C, "a98"}, 1190 {0x275D, "a99"}, 1191 {0x275E, "a100"}, 1192 {0xF8D7, "a89"}, 1193 {0xF8D8, "a90"}, 1194 {0xF8D9, "a93"}, 1195 {0xF8DA, "a94"}, 1196 {0xF8DB, "a91"}, 1197 {0xF8DC, "a92"}, 1198 {0xF8DD, "a205"}, 1199 {0xF8DE, "a85"}, 1200 {0xF8DF, "a206"}, 1201 {0xF8E0, "a86"}, 1202 {0xF8E1, "a87"}, 1203 {0xF8E2, "a88"}, 1204 {0xF8E3, "a95"}, 1205 {0xF8E4, "a96"}, 1206 {0x2761, "a101"}, 1207 {0x2762, "a102"}, 1208 {0x2763, "a103"}, 1209 {0x2764, "a104"}, 1210 {0x2765, "a106"}, 1211 {0x2766, "a107"}, 1212 {0x2767, "a108"}, 1213 {0x2663, "a112"}, 1214 {0x2666, "a111"}, 1215 {0x2665, "a110"}, 1216 {0x2660, "a109"}, 1217 {0x2460, "a120"}, 1218 {0x2461, "a121"}, 1219 {0x2462, "a122"}, 1220 {0x2463, "a123"}, 1221 {0x2464, "a124"}, 1222 {0x2465, "a125"}, 1223 {0x2466, "a126"}, 1224 {0x2467, "a127"}, 1225 {0x2468, "a128"}, 1226 {0x2469, "a129"}, 1227 {0x2776, "a130"}, 1228 {0x2777, "a131"}, 1229 {0x2778, "a132"}, 1230 {0x2779, "a133"}, 1231 {0x277A, "a134"}, 1232 {0x277B, "a135"}, 1233 {0x277C, "a136"}, 1234 {0x277D, "a137"}, 1235 {0x277E, "a138"}, 1236 {0x277F, "a139"}, 1237 {0x2780, "a140"}, 1238 {0x2781, "a141"}, 1239 {0x2782, "a142"}, 1240 {0x2783, "a143"}, 1241 {0x2784, "a144"}, 1242 {0x2785, "a145"}, 1243 {0x2786, "a146"}, 1244 {0x2787, "a147"}, 1245 {0x2788, "a148"}, 1246 {0x2789, "a149"}, 1247 {0x278A, "a150"}, 1248 {0x278B, "a151"}, 1249 {0x278C, "a152"}, 1250 {0x278D, "a153"}, 1251 {0x278E, "a154"}, 1252 {0x278F, "a155"}, 1253 {0x2790, "a156"}, 1254 {0x2791, "a157"}, 1255 {0x2792, "a158"}, 1256 {0x2793, "a159"}, 1257 {0x2794, "a160"}, 1258 {0x2192, "a161"}, 1259 {0x2194, "a163"}, 1260 {0x2195, "a164"}, 1261 {0x2798, "a196"}, 1262 {0x2799, "a165"}, 1263 {0x279A, "a192"}, 1264 {0x279B, "a166"}, 1265 {0x279C, "a167"}, 1266 {0x279D, "a168"}, 1267 {0x279E, "a169"}, 1268 {0x279F, "a170"}, 1269 {0x27A0, "a171"}, 1270 {0x27A1, "a172"}, 1271 {0x27A2, "a173"}, 1272 {0x27A3, "a162"}, 1273 {0x27A4, "a174"}, 1274 {0x27A5, "a175"}, 1275 {0x27A6, "a176"}, 1276 {0x27A7, "a177"}, 1277 {0x27A8, "a178"}, 1278 {0x27A9, "a179"}, 1279 {0x27AA, "a193"}, 1280 {0x27AB, "a180"}, 1281 {0x27AC, "a199"}, 1282 {0x27AD, "a181"}, 1283 {0x27AE, "a200"}, 1284 {0x27AF, "a182"}, 1285 {0x27B1, "a201"}, 1286 {0x27B2, "a183"}, 1287 {0x27B3, "a184"}, 1288 {0x27B4, "a197"}, 1289 {0x27B5, "a185"}, 1290 {0x27B6, "a194"}, 1291 {0x27B7, "a198"}, 1292 {0x27B8, "a186"}, 1293 {0x27B9, "a195"}, 1294 {0x27BA, "a187"}, 1295 {0x27BB, "a188"}, 1296 {0x27BC, "a189"}, 1297 {0x27BD, "a190"}, 1298 {0x27BE, "a191"}, 1299 // end of Zapf Dingbats 1096 1300 { 0, NULL } 1097 1301 }; -
trunk/poppler/mypoppler/poppler/TextOutputDev.cc
r277 r367 1616 1616 } 1617 1617 1618 GBool TextBlock::isBeforeByRule1(TextBlock *blk1) { 1619 GBool before = gFalse; 1620 GBool overlap = gFalse; 1621 1622 switch (this->page->primaryRot) { 1623 case 0: 1624 case 2: 1625 overlap = ((this->xMin <= blk1->xMin) && 1626 (blk1->xMin <= this->xMax)) || 1627 ((blk1->xMin <= this->xMin) && 1628 (this->xMin <= blk1->xMax)); 1629 break; 1630 case 1: 1631 case 3: 1632 overlap = ((this->yMin <= blk1->yMin) && 1633 (blk1->yMin <= this->yMax)) || 1634 ((blk1->yMin <= this->yMin) && 1635 (this->yMin <= blk1->yMax)); 1636 break; 1637 } 1638 switch (this->page->primaryRot) { 1639 case 0: 1640 before = overlap && this->yMin < blk1->yMin; 1641 break; 1642 case 1: 1643 before = overlap && this->xMax > blk1->xMax; 1644 break; 1645 case 2: 1646 before = overlap && this->yMax > blk1->yMax; 1647 break; 1648 case 3: 1649 before = overlap && this->xMin < blk1->xMin; 1650 break; 1651 } 1652 return before; 1653 } 1654 1655 GBool TextBlock::isBeforeByRule2(TextBlock *blk1) { 1656 double cmp = 0; 1657 int rotLR = rot; 1658 1659 if (!page->primaryLR) { 1660 rotLR = (rotLR + 2) % 4; 1661 } 1662 1663 switch (rotLR) { 1664 case 0: 1665 cmp = xMax - blk1->xMin; 1666 break; 1667 case 1: 1668 cmp = yMin - blk1->yMax; 1669 break; 1670 case 2: 1671 cmp = blk1->xMax - xMin; 1672 break; 1673 case 3: 1674 cmp = blk1->yMin - yMax; 1675 break; 1676 } 1677 return cmp <= 0; 1678 } 1679 1680 // Sort into reading order by performing a topological sort using the rules 1681 // given in "High Performance Document Layout Analysis", T.M. Breuel, 2003. 1682 // See http://pubs.iupr.org/#2003-breuel-sdiut 1683 // Topological sort is done by depth first search, see 1684 // http://en.wikipedia.org/wiki/Topological_sorting 1685 int TextBlock::visitDepthFirst(TextBlock *blkList, int pos1, 1686 TextBlock **sorted, int sortPos, 1687 GBool* visited) { 1688 int pos2; 1689 TextBlock *blk1, *blk2, *blk3; 1690 GBool before; 1691 1692 if (visited[pos1]) { 1693 return sortPos; 1694 } 1695 1696 blk1 = this; 1697 1698 #if 0 // for debugging 1699 printf("visited: %d %.2f..%.2f %.2f..%.2f\n", 1700 sortPos, blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax); 1701 #endif 1702 visited[pos1] = gTrue; 1703 pos2 = -1; 1704 for (blk2 = blkList; blk2; blk2 = blk2->next) { 1705 pos2++; 1706 if (visited[pos2]) { 1707 // skip visited nodes 1708 continue; 1709 } 1710 before = gFalse; 1711 if (blk2->isBeforeByRule1(blk1)) { 1712 // Rule (1) blk1 and blk2 overlap, and blk2 is above blk1. 1713 before = gTrue; 1714 #if 0 // for debugging 1715 printf("rule1: %.2f..%.2f %.2f..%.2f %.2f..%.2f %.2f..%.2f\n", 1716 blk2->xMin, blk2->xMax, blk2->yMin, blk2->yMax, 1717 blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax); 1718 #endif 1719 } else if (blk2->isBeforeByRule2(blk1)) { 1720 // Rule (2) blk2 left of blk1, and no intervening blk3 1721 // such that blk1 is before blk3 by rule 1, 1722 // and blk3 is before blk2 by rule 1. 1723 before = gTrue; 1724 for (blk3 = blkList; blk3; blk3 = blk3->next) { 1725 if (blk3 == blk2 || blk3 == blk1) { 1726 continue; 1727 } 1728 if (blk1->isBeforeByRule1(blk3) && 1729 blk3->isBeforeByRule1(blk2)) { 1730 before = gFalse; 1731 break; 1732 } 1733 } 1734 #if 0 // for debugging 1735 if (before) { 1736 printf("rule2: %.2f..%.2f %.2f..%.2f %.2f..%.2f %.2f..%.2f\n", 1737 blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax, 1738 blk2->xMin, blk2->xMax, blk2->yMin, blk2->yMax); 1739 } 1740 #endif 1741 } 1742 if (before) { 1743 // blk2 is before blk1, so it needs to be visited 1744 // before we can add blk1 to the sorted list. 1745 sortPos = blk2->visitDepthFirst(blkList, pos2, sorted, sortPos, visited); 1746 } 1747 } 1748 #if 0 // for debugging 1749 printf("sorted: %d %.2f..%.2f %.2f..%.2f\n", 1750 sortPos, blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax); 1751 #endif 1752 sorted[sortPos++] = blk1; 1753 return sortPos; 1754 } 1755 1618 1756 //------------------------------------------------------------------------ 1619 1757 // TextFlow … … 2184 2322 TextWord *word0, *word1, *word2; 2185 2323 TextLine *line; 2186 TextBlock *blkList, *blkStack, *blk, *lastBlk, *blk0, *blk1; 2187 TextBlock **blkArray; 2324 TextBlock *blkList, *blk, *lastBlk, *blk0, *blk1; 2188 2325 TextFlow *flow, *lastFlow; 2189 2326 TextUnderline *underline; … … 2195 2332 int count[4]; 2196 2333 int lrCount; 2197 int firstBlkIdx, nBlocksLeft;2198 2334 int col1, col2; 2199 2335 int i, j, n; … … 2688 2824 } 2689 2825 2690 #if 0 // for debugging 2826 #if 0 // for debugging 2691 2827 printf("*** rotation ***\n"); 2692 2828 for (rot = 0; rot < 4; ++rot) { … … 2842 2978 //----- reading order sort 2843 2979 2844 // sort blocks into yx order (in preparation for reading order sort)2845 qsort(blocks, nBlocks, sizeof(TextBlock *), &TextBlock::cmpYXPrimaryRot);2846 2847 2980 // compute space on left and right sides of each block 2848 2981 for (i = 0; i < nBlocks; ++i) { … … 2857 2990 2858 2991 #if 0 // for debugging 2859 printf("*** blocks, after yx sort ***\n"); 2992 printf("PAGE\n"); 2993 #endif 2994 2995 int sortPos = 0; 2996 GBool *visited = (GBool *)gmallocn(nBlocks, sizeof(GBool)); 2997 for (i = 0; i < nBlocks; i++) { 2998 visited[i] = gFalse; 2999 } 3000 i = -1; 3001 for (blk1 = blkList; blk1; blk1 = blk1->next) { 3002 i++; 3003 sortPos = blk1->visitDepthFirst(blkList, i, blocks, sortPos, visited); 3004 } 3005 if (visited) { 3006 gfree(visited); 3007 } 3008 3009 #if 0 // for debugging 3010 printf("*** blocks, after ro sort ***\n"); 2860 3011 for (i = 0; i < nBlocks; ++i) { 2861 3012 blk = blocks[i]; … … 2877 3028 } 2878 3029 printf("\n"); 3030 fflush(stdout); 2879 3031 #endif 2880 3032 … … 2882 3034 //~ this needs to be adjusted for writing mode (vertical text) 2883 3035 //~ this also needs to account for right-to-left column ordering 2884 blkArray = (TextBlock **)gmallocn(nBlocks, sizeof(TextBlock *)); 2885 memcpy(blkArray, blocks, nBlocks * sizeof(TextBlock *)); 3036 flow = NULL; 2886 3037 while (flows) { 2887 3038 flow = flows; … … 2890 3041 } 2891 3042 flows = lastFlow = NULL; 2892 firstBlkIdx = 0; 2893 nBlocksLeft = nBlocks; 2894 while (nBlocksLeft > 0) { 2895 2896 // find the upper-left-most block 2897 for (; !blkArray[firstBlkIdx]; ++firstBlkIdx) ; 2898 i = firstBlkIdx; 2899 blk = blkArray[i]; 2900 for (j = firstBlkIdx + 1; j < nBlocks; ++j) { 2901 blk1 = blkArray[j]; 2902 if (blk1) { 2903 if (blk && blk->secondaryDelta(blk1) > 0) { 2904 break; 2905 } 2906 if (blk1->primaryCmp(blk) < 0) { 2907 i = j; 2908 blk = blk1; 2909 } 2910 } 2911 } 2912 blkArray[i] = NULL; 2913 --nBlocksLeft; 3043 // assume blocks are already in reading order, 3044 // and construct flows accordingly. 3045 for (i = 0; i < nBlocks; i++) { 3046 blk = blocks[i]; 2914 3047 blk->next = NULL; 2915 2916 // create a new flow, starting with the upper-left-most block 3048 if (flow) { 3049 blk1 = blocks[i - 1]; 3050 blkSpace = maxBlockSpacing * blk1->lines->words->fontSize; 3051 if (blk1->secondaryDelta(blk) <= blkSpace && 3052 blk->isBelow(blk1) && 3053 flow->blockFits(blk, blk1)) { 3054 flow->addBlock(blk); 3055 continue; 3056 } 3057 } 2917 3058 flow = new TextFlow(this, blk); 2918 3059 if (lastFlow) { … … 2922 3063 } 2923 3064 lastFlow = flow; 2924 fontSize = blk->lines->words->fontSize; 2925 2926 // push the upper-left-most block on the stack 2927 blk->stackNext = NULL; 2928 blkStack = blk; 2929 2930 // find the other blocks in this flow 2931 while (blkStack) { 2932 2933 // find the upper-left-most block under (but within 2934 // maxBlockSpacing of) the top block on the stack 2935 blkSpace = maxBlockSpacing * blkStack->lines->words->fontSize; 2936 blk = NULL; 2937 i = -1; 2938 for (j = firstBlkIdx; j < nBlocks; ++j) { 2939 blk1 = blkArray[j]; 2940 if (blk1) { 2941 if (blkStack->secondaryDelta(blk1) > blkSpace) { 2942 break; 2943 } 2944 if (blk && blk->secondaryDelta(blk1) > 0) { 2945 break; 2946 } 2947 if (blk1->isBelow(blkStack) && 2948 (!blk || blk1->primaryCmp(blk) < 0)) { 2949 i = j; 2950 blk = blk1; 2951 } 2952 } 2953 } 2954 2955 // if a suitable block was found, add it to the flow and push it 2956 // onto the stack 2957 if (blk && flow->blockFits(blk, blkStack)) { 2958 blkArray[i] = NULL; 2959 --nBlocksLeft; 2960 blk->next = NULL; 2961 flow->addBlock(blk); 2962 fontSize = blk->lines->words->fontSize; 2963 blk->stackNext = blkStack; 2964 blkStack = blk; 2965 2966 // otherwise (if there is no block under the top block or the 2967 // block is not suitable), pop the stack 2968 } else { 2969 blkStack = blkStack->stackNext; 2970 } 2971 } 2972 } 2973 gfree(blkArray); 3065 } 2974 3066 2975 3067 #if 0 // for debugging … … 3522 3614 GooString *TextSelectionDumper::getText (void) 3523 3615 { 3524 GBool oneRot = gTrue;3525 3616 GooString *s; 3526 3617 TextLineFrag *frag; 3527 int i , col;3618 int i; 3528 3619 GBool multiLine; 3529 3620 UnicodeMap *uMap; … … 3542 3633 3543 3634 if (nFrags > 0) { 3544 for (i = 0; i < nFrags; ++i) {3545 frags[i].computeCoords(oneRot);3546 }3547 page->assignColumns(frags, nFrags, oneRot);3548 3549 // if all lines in the region have the same rotation, use it;3550 // otherwise, use the page's primary rotation3551 if (oneRot) {3552 qsort(frags, nFrags, sizeof(TextLineFrag),3553 &TextLineFrag::cmpYXLineRot);3554 } else {3555 qsort(frags, nFrags, sizeof(TextLineFrag),3556 &TextLineFrag::cmpYXPrimaryRot);3557 }3558 3559 col = 0;3560 3635 multiLine = gFalse; 3561 3636 for (i = 0; i < nFrags; ++i) { 3562 3637 frag = &frags[i]; 3563 3638 3564 // insert a return 3565 if (frag->col < col || 3566 (i > 0 && fabs(frag->base - frags[i-1].base) > 3567 maxIntraLineDelta * frags[i-1].line->words->fontSize)) { 3568 s->append(eol, eolLen); 3569 col = 0; 3570 multiLine = gTrue; 3571 } 3572 3573 // column alignment 3574 for (; col < frag->col; ++col) { 3575 s->append(space, spaceLen); 3576 } 3577 3578 // get the fragment text 3579 col += page->dumpFragment(frag->line->text + frag->start, frag->len, uMap, s); 3580 } 3581 3582 if (multiLine) { 3639 page->dumpFragment(frag->line->text + frag->start, frag->len, uMap, s); 3583 3640 s->append(eol, eolLen); 3584 3641 } … … 3860 3917 PDFRectangle *selection, 3861 3918 SelectionStyle style) { 3862 TextLine *p, *begin, *end;3863 3919 PDFRectangle child_selection; 3864 double start_x, start_y, stop_x, stop_y; 3865 3866 begin = NULL; 3867 end = NULL; 3868 start_x = selection->x1; 3869 start_y = selection->y1; 3870 stop_x = selection->x2; 3871 stop_y = selection->y2; 3872 3873 for (p = lines; p != NULL; p = p->next) { 3874 if (selection->x1 < p->xMax && selection->y1 < p->yMax && 3875 selection->x2 < p->xMax && selection->y2 < p->yMax && begin == NULL) { 3876 begin = p; 3877 if (selection->x1 < selection->x2) { 3878 start_x = selection->x1; 3879 start_y = selection->y1; 3880 stop_x = selection->x2; 3881 stop_y = selection->y2; 3920 double x[2], y[2], d, best_d[2]; 3921 TextLine *p, *best_line[2]; 3922 int i, count = 0, best_count[2], start, stop; 3923 GBool all[2]; 3924 3925 x[0] = selection->x1; 3926 y[0] = selection->y1; 3927 x[1] = selection->x2; 3928 y[1] = selection->y2; 3929 3930 for (i = 0; i < 2; i++) { 3931 // the first/last lines are often not nearest 3932 // the corners, so we have to force them to be 3933 // selected when the selection runs outside this 3934 // block. 3935 if (page->primaryLR) { 3936 all[i] = x[i] >= this->xMax && y[i] >= this->yMax; 3937 if (x[i] <= this->xMin && y[i] <= this->yMin) { 3938 best_line[i] = this->lines; 3939 best_count[i] = 1; 3882 3940 } else { 3883 start_x = selection->x2; 3884 start_y = selection->y2; 3885 stop_x = selection->x1; 3886 stop_y = selection->y1; 3887 } 3888 } else if (selection->x1 < p->xMax && selection->y1 < p->yMax && begin == NULL) { 3889 begin = p; 3890 start_x = selection->x1; 3891 start_y = selection->y1; 3892 stop_x = selection->x2; 3893 stop_y = selection->y2; 3894 } else if (selection->x2 < p->xMax && selection->y2 < p->yMax && begin == NULL) { 3895 begin = p; 3896 start_x = selection->x2; 3897 start_y = selection->y2; 3898 stop_x = selection->x1; 3899 stop_y = selection->y1; 3900 } 3901 3902 if (((selection->x1 > p->xMin && selection->y1 > p->yMin) || 3903 (selection->x2 > p->xMin && selection->y2 > p->yMin)) 3904 && (begin != NULL)) 3905 end = p->next; 3906 } 3907 3908 /* Skip empty selection. */ 3909 if (end == begin) 3941 best_line[i] = NULL; 3942 best_count[i] = 0; 3943 } 3944 } else { 3945 all[i] = x[i] <= this->xMin && y[i] >= this->yMax; 3946 if (x[i] >= this->xMax && y[i] <= this->yMin) { 3947 best_line[i] = this->lines; 3948 best_count[i] = 1; 3949 } else { 3950 best_line[i] = NULL; 3951 best_count[i] = 0; 3952 } 3953 } 3954 best_d[i] = 0; 3955 } 3956 3957 // find the nearest line to the selection points 3958 // using the manhattan distance. 3959 for (p = this->lines; p; p = p->next) { 3960 count++; 3961 for (i = 0; i < 2; i++) { 3962 d = fmax(p->xMin - x[i], 0.0) + 3963 fmax(x[i] - p->xMax, 0.0) + 3964 fmax(p->yMin - y[i], 0.0) + 3965 fmax(y[i] - p->yMax, 0.0); 3966 if (!best_line[i] || all[i] || 3967 d < best_d[i]) { 3968 best_line[i] = p; 3969 best_count[i] = count; 3970 best_d[i] = d; 3971 } 3972 } 3973 } 3974 // assert: best is always set. 3975 if (!best_line[0] || !best_line[1]) { 3910 3976 return; 3911 3912 visitor->visitBlock (this, begin, end, selection); 3913 3914 for (p = begin; p != end; p = p->next) { 3915 if (p == begin && style != selectionStyleLine) { 3916 child_selection.x1 = start_x; 3917 child_selection.y1 = start_y; 3977 } 3978 3979 // Now decide which point was first. 3980 if (best_count[0] < best_count[1] || 3981 (best_count[0] == best_count[1] && 3982 y[0] < y[1])) { 3983 start = 0; 3984 stop = 1; 3985 } else { 3986 start = 1; 3987 stop = 0; 3988 } 3989 3990 visitor->visitBlock(this, best_line[start], best_line[stop], selection); 3991 3992 for (p = best_line[start]; p; p = p->next) { 3993 if (page->primaryLR) { 3994 child_selection.x1 = p->xMin; 3995 child_selection.x2 = p->xMax; 3918 3996 } else { 3919 child_selection.x1 = 0; 3920 child_selection.y1 = 0; 3921 } 3922 if (p->next == end && style != selectionStyleLine) { 3923 child_selection.x2 = stop_x; 3924 child_selection.y2 = stop_y; 3997 child_selection.x1 = p->xMax; 3998 child_selection.x2 = p->xMin; 3999 } 4000 child_selection.y1 = p->yMin; 4001 child_selection.y2 = p->yMax; 4002 if (style == selectionStyleLine) { 4003 if (p == best_line[start]) { 4004 child_selection.x1 = 0; 4005 child_selection.y1 = 0; 4006 } 4007 if (p == best_line[stop]) { 4008 child_selection.x2 = page->pageWidth; 4009 child_selection.y2 = page->pageHeight; 4010 } 3925 4011 } else { 3926 child_selection.x2 = page->pageWidth; 3927 child_selection.y2 = page->pageHeight; 3928 } 3929 4012 if (p == best_line[start]) { 4013 child_selection.x1 = fmax(p->xMin, fmin(p->xMax, x[start])); 4014 child_selection.y1 = fmax(p->yMin, fmin(p->yMax, y[start])); 4015 } 4016 if (p == best_line[stop]) { 4017 child_selection.x2 = fmax(p->xMin, fmin(p->xMax, x[stop])); 4018 child_selection.y2 = fmax(p->yMin, fmin(p->yMax, y[stop])); 4019 } 4020 } 3930 4021 p->visitSelection(visitor, &child_selection, style); 4022 if (p == best_line[stop]) { 4023 return; 4024 } 3931 4025 } 3932 4026 } … … 3936 4030 SelectionStyle style) 3937 4031 { 3938 int i, begin, end;3939 4032 PDFRectangle child_selection; 3940 double start_x, start_y, stop_x, stop_y; 3941 TextBlock *b; 3942 3943 begin = nBlocks; 3944 end = 0; 3945 start_x = selection->x1; 3946 start_y = selection->y1; 3947 stop_x = selection->x2; 3948 stop_y = selection->y2; 3949 3950 for (i = 0; i < nBlocks; i++) { 3951 b = blocks[i]; 3952 3953 if (selection->x1 < b->xMax && selection->y1 < b->yMax && 3954 selection->x2 < b->xMax && selection->y2 < b->yMax && i < begin) { 3955 begin = i; 3956 if (selection->y1 < selection->y2) { 3957 start_x = selection->x1; 3958 start_y = selection->y1; 3959 stop_x = selection->x2; 3960 stop_y = selection->y2; 4033 double x[2], y[2], d, best_d[2]; 4034 double xMin, yMin, xMax, yMax; 4035 TextFlow *flow, *best_flow[2]; 4036 TextBlock *blk, *best_block[2]; 4037 int i, count = 0, best_count[2], start, stop; 4038 4039 if (!flows) 4040 return; 4041 4042 x[0] = selection->x1; 4043 y[0] = selection->y1; 4044 x[1] = selection->x2; 4045 y[1] = selection->y2; 4046 4047 xMin = pageWidth; 4048 yMin = pageHeight; 4049 xMax = 0.0; 4050 yMax = 0.0; 4051 4052 for (i = 0; i < 2; i++) { 4053 best_block[i] = NULL; 4054 best_flow[i] = NULL; 4055 best_count[i] = 0; 4056 best_d[i] = 0; 4057 } 4058 4059 // find the nearest blocks to the selection points 4060 // using the manhattan distance. 4061 for (flow = flows; flow; flow = flow->next) { 4062 for (blk = flow->blocks; blk; blk = blk->next) { 4063 count++; 4064 // the first/last blocks in reading order are 4065 // often not the closest to the page corners; 4066 // track the corners, force those blocks to 4067 // be selected if the selection runs across 4068 // multiple pages. 4069 xMin = fmin(xMin, blk->xMin); 4070 yMin = fmin(yMin, blk->yMin); 4071 xMax = fmax(xMax, blk->xMax); 4072 yMax = fmax(yMax, blk->yMax); 4073 for (i = 0; i < 2; i++) { 4074 d = fmax(blk->xMin - x[i], 0.0) + 4075 fmax(x[i] - blk->xMax, 0.0) + 4076 fmax(blk->yMin - y[i], 0.0) + 4077 fmax(y[i] - blk->yMax, 0.0); 4078 if (!best_block[i] || 4079 d < best_d[i] || 4080 (!blk->next && !flow->next && 4081 x[i] > xMax && y[i] > yMax)) { 4082 best_block[i] = blk; 4083 best_flow[i] = flow; 4084 best_count[i] = count; 4085 best_d[i] = d; 4086 } 4087 } 4088 } 4089 } 4090 for (i = 0; i < 2; i++) { 4091 if (primaryLR) { 4092 if (x[i] < xMin && y[i] < yMin) { 4093 best_block[i] = flows->blocks; 4094 best_flow[i] = flows; 4095 best_count[i] = 1; 4096 } 4097 } else { 4098 if (x[i] > xMax && y[i] < yMin) { 4099 best_block[i] = flows->blocks; 4100 best_flow[i] = flows; 4101 best_count[i] = 1; 4102 } 4103 } 4104 } 4105 // assert: best is always set. 4106 if (!best_block[0] || !best_block[1]) { 4107 return; 4108 } 4109 4110 // Now decide which point was first. 4111 if (best_count[0] < best_count[1] || 4112 (best_count[0] == best_count[1] && y[0] < y[1])) { 4113 start = 0; 4114 stop = 1; 4115 } else { 4116 start = 1; 4117 stop = 0; 4118 } 4119 4120 for (flow = best_flow[start]; flow; flow = flow->next) { 4121 if (flow == best_flow[start]) { 4122 blk = best_block[start]; 4123 } else { 4124 blk = flow->blocks; 4125 } 4126 for (; blk; blk = blk->next) { 4127 if (primaryLR) { 4128 child_selection.x1 = blk->xMin; 4129 child_selection.x2 = blk->xMax; 3961 4130 } else { 3962 start_x = selection->x2; 3963 start_y = selection->y2; 3964 stop_x = selection->x1; 3965 stop_y = selection->y1; 3966 } 3967 } else if (selection->x1 < b->xMax && selection->y1 < b->yMax && i < begin) { 3968 begin = i; 3969 start_x = selection->x1; 3970 start_y = selection->y1; 3971 stop_x = selection->x2; 3972 stop_y = selection->y2; 3973 } else if (selection->x2 < b->xMax && selection->y2 < b->yMax && i < begin) { 3974 begin = i; 3975 start_x = selection->x2; 3976 start_y = selection->y2; 3977 stop_x = selection->x1; 3978 stop_y = selection->y1; 3979 } 3980 3981 if ((selection->x1 > b->xMin && selection->y1 > b->yMin) || 3982 (selection->x2 > b->xMin && selection->y2 > b->yMin)) 3983 end = i + 1; 3984 } 3985 3986 for (i = begin; i < end; i++) { 3987 if (blocks[i]->xMin < start_x && start_x < blocks[i]->xMax && 3988 blocks[i]->yMin < start_y && start_y < blocks[i]->yMax) { 3989 child_selection.x1 = start_x; 3990 child_selection.y1 = start_y; 3991 } else { 3992 child_selection.x1 = 0; 3993 child_selection.y1 = 0; 3994 } 3995 if (blocks[i]->xMin < stop_x && stop_x < blocks[i]->xMax && 3996 blocks[i]->yMin < stop_y && stop_y < blocks[i]->yMax) { 3997 child_selection.x2 = stop_x; 3998 child_selection.y2 = stop_y; 3999 } else { 4000 child_selection.x2 = pageWidth; 4001 child_selection.y2 = pageHeight; 4002 } 4003 4004 blocks[i]->visitSelection(visitor, &child_selection, style); 4131 child_selection.x1 = blk->xMax; 4132 child_selection.x2 = blk->xMin; 4133 } 4134 child_selection.y1 = blk->yMin; 4135 child_selection.y2 = blk->yMax; 4136 if (blk == best_block[start]) { 4137 child_selection.x1 = fmax(blk->xMin, fmin(blk->xMax, x[start])); 4138 child_selection.y1 = fmax(blk->yMin, fmin(blk->yMax, y[start])); 4139 } 4140 if (blk == best_block[stop]) { 4141 child_selection.x2 = fmax(blk->xMin, fmin(blk->xMax, x[stop])); 4142 child_selection.y2 = fmax(blk->yMin, fmin(blk->yMax, y[stop])); 4143 blk->visitSelection(visitor, &child_selection, style); 4144 return; 4145 } 4146 blk->visitSelection(visitor, &child_selection, style); 4147 } 4005 4148 } 4006 4149 } … … 4287 4430 (*outputFunc)(outputStream, s->getCString(), s->getLength()); 4288 4431 delete s; 4289 if (!line->hyphenated) { 4290 if (line->next) { 4291 (*outputFunc)(outputStream, space, spaceLen); 4292 } else if (blk->next) { 4293 //~ this is a bit of a kludge - we should really do a more 4294 //~ intelligent determination of paragraphs 4295 if (blk->next->lines->words->fontSize == 4296 blk->lines->words->fontSize) { 4297 (*outputFunc)(outputStream, space, spaceLen); 4298 } else { 4299 (*outputFunc)(outputStream, eol, eolLen); 4300 } 4301 } 4432 // output a newline when a hyphen is not suppressed 4433 if (n == line->len) { 4434 (*outputFunc)(outputStream, eol, eolLen); 4302 4435 } 4303 4436 } 4304 4437 } 4305 (*outputFunc)(outputStream, eol, eolLen);4306 4438 (*outputFunc)(outputStream, eol, eolLen); 4307 4439 } -
trunk/poppler/mypoppler/poppler/TextOutputDev.h
r277 r367 362 362 private: 363 363 364 GBool isBeforeByRule1(TextBlock *blk1); 365 GBool isBeforeByRepeatedRule1(TextBlock *blkList, TextBlock *blk1); 366 GBool isBeforeByRule2(TextBlock *blk1); 367 368 int visitDepthFirst(TextBlock *blkList, int pos1, 369 TextBlock **sorted, int sortPos, 370 GBool* visited); 371 364 372 TextPage *page; // the parent page 365 373 int rot; // text rotation
Note: See TracChangeset
for help on using the changeset viewer.