PK JvK?|
FontMetrics/zapfdingbats.fmnu W+A 746, 1 => 746, 2 => 746, 3 => 746, 4 => 746, 5 => 746, 6 => 746, 7 => 746,
8 => 746, 9 => 746, 10 => 746, 11 => 746, 12 => 746, 13 => 746, 14 => 746, 15 => 746,
16 => 746, 17 => 746, 18 => 746, 19 => 746, 20 => 746, 21 => 746, 22 => 746, 23 => 746,
24 => 746, 25 => 746, 26 => 746, 27 => 746, 28 => 746, 29 => 746, 30 => 746, 31 => 746,
32 => 278, 33 => 974, 34 => 961, 35 => 974, 36 => 980, 37 => 719, 38 => 789, 39 => 790,
40 => 791, 41 => 690, 42 => 960, 43 => 939, 44 => 549, 45 => 855, 46 => 911, 47 => 933,
48 => 911, 49 => 945, 50 => 974, 51 => 755, 52 => 846, 53 => 762, 54 => 761, 55 => 571,
56 => 677, 57 => 763, 58 => 760, 59 => 759, 60 => 754, 61 => 494, 62 => 552, 63 => 537,
64 => 577, 65 => 692, 66 => 786, 67 => 788, 68 => 788, 69 => 790, 70 => 793, 71 => 794,
72 => 816, 73 => 823, 74 => 789, 75 => 841, 76 => 823, 77 => 833, 78 => 816, 79 => 831,
80 => 923, 81 => 744, 82 => 723, 83 => 749, 84 => 790, 85 => 792, 86 => 695, 87 => 776,
88 => 768, 89 => 792, 90 => 759, 91 => 707, 92 => 708, 93 => 682, 94 => 701, 95 => 826,
96 => 815, 97 => 789, 98 => 789, 99 => 707, 100 => 687, 101 => 696, 102 => 689, 103 => 786,
104 => 787, 105 => 713, 106 => 791, 107 => 785, 108 => 791, 109 => 873, 110 => 761, 111 => 762,
112 => 762, 113 => 759, 114 => 759, 115 => 892, 116 => 892, 117 => 788, 118 => 784, 119 => 438,
120 => 138, 121 => 277, 122 => 415, 123 => 392, 124 => 392, 125 => 668, 126 => 668, 127 => 746,
128 => 390, 129 => 390, 130 => 317, 131 => 317, 132 => 276, 133 => 276, 134 => 509, 135 => 509,
136 => 410, 137 => 410, 138 => 234, 139 => 234, 140 => 334, 141 => 334, 142 => 746, 143 => 746,
144 => 746, 145 => 746, 146 => 746, 147 => 746, 148 => 746, 149 => 746, 150 => 746, 151 => 746,
152 => 746, 153 => 746, 154 => 746, 155 => 746, 156 => 746, 157 => 746, 158 => 746, 159 => 746,
160 => 746, 161 => 732, 162 => 544, 163 => 544, 164 => 910, 165 => 667, 166 => 760, 167 => 760,
168 => 776, 169 => 595, 170 => 694, 171 => 626, 172 => 788, 173 => 788, 174 => 788, 175 => 788,
176 => 788, 177 => 788, 178 => 788, 179 => 788, 180 => 788, 181 => 788, 182 => 788, 183 => 788,
184 => 788, 185 => 788, 186 => 788, 187 => 788, 188 => 788, 189 => 788, 190 => 788, 191 => 788,
192 => 788, 193 => 788, 194 => 788, 195 => 788, 196 => 788, 197 => 788, 198 => 788, 199 => 788,
200 => 788, 201 => 788, 202 => 788, 203 => 788, 204 => 788, 205 => 788, 206 => 788, 207 => 788,
208 => 788, 209 => 788, 210 => 788, 211 => 788, 212 => 894, 213 => 838, 214 => 1016, 215 => 458,
216 => 748, 217 => 924, 218 => 748, 219 => 918, 220 => 927, 221 => 928, 222 => 928, 223 => 834,
224 => 873, 225 => 828, 226 => 924, 227 => 924, 228 => 917, 229 => 930, 230 => 931, 231 => 463,
232 => 883, 233 => 836, 234 => 836, 235 => 867, 236 => 867, 237 => 696, 238 => 696, 239 => 874,
240 => 746, 241 => 874, 242 => 760, 243 => 946, 244 => 771, 245 => 865, 246 => 771, 247 => 888,
248 => 967, 249 => 888, 250 => 831, 251 => 873, 252 => 927, 253 => 970, 254 => 918, 255 => 746,
) ;
PK JvK%
FontMetrics/timesi.fmnu W+A 250, 1 => 250, 2 => 250, 3 => 250, 4 => 250, 5 => 250, 6 => 250, 7 => 250,
8 => 250, 9 => 250, 10 => 250, 11 => 250, 12 => 250, 13 => 250, 14 => 250, 15 => 250,
16 => 250, 17 => 250, 18 => 250, 19 => 250, 20 => 250, 21 => 250, 22 => 250, 23 => 250,
24 => 250, 25 => 250, 26 => 250, 27 => 250, 28 => 250, 29 => 250, 30 => 250, 31 => 250,
32 => 250, 33 => 333, 34 => 420, 35 => 500, 36 => 500, 37 => 833, 38 => 778, 39 => 214,
40 => 333, 41 => 333, 42 => 500, 43 => 675, 44 => 250, 45 => 333, 46 => 250, 47 => 278,
48 => 500, 49 => 500, 50 => 500, 51 => 500, 52 => 500, 53 => 500, 54 => 500, 55 => 500,
56 => 500, 57 => 500, 58 => 333, 59 => 333, 60 => 675, 61 => 675, 62 => 675, 63 => 500,
64 => 920, 65 => 611, 66 => 611, 67 => 667, 68 => 722, 69 => 611, 70 => 611, 71 => 722,
72 => 722, 73 => 333, 74 => 444, 75 => 667, 76 => 556, 77 => 833, 78 => 667, 79 => 722,
80 => 611, 81 => 722, 82 => 611, 83 => 500, 84 => 556, 85 => 722, 86 => 611, 87 => 833,
88 => 611, 89 => 556, 90 => 556, 91 => 389, 92 => 278, 93 => 389, 94 => 422, 95 => 500,
96 => 333, 97 => 500, 98 => 500, 99 => 444, 100 => 500, 101 => 444, 102 => 278, 103 => 500,
104 => 500, 105 => 278, 106 => 278, 107 => 444, 108 => 278, 109 => 722, 110 => 500, 111 => 500,
112 => 500, 113 => 500, 114 => 389, 115 => 389, 116 => 278, 117 => 500, 118 => 444, 119 => 667,
120 => 444, 121 => 444, 122 => 389, 123 => 400, 124 => 275, 125 => 400, 126 => 541, 127 => 350,
128 => 500, 129 => 350, 130 => 333, 131 => 500, 132 => 556, 133 => 889, 134 => 500, 135 => 500,
136 => 333, 137 => 1000, 138 => 500, 139 => 333, 140 => 944, 141 => 350, 142 => 556, 143 => 350,
144 => 350, 145 => 333, 146 => 333, 147 => 556, 148 => 556, 149 => 350, 150 => 500, 151 => 889,
152 => 333, 153 => 980, 154 => 389, 155 => 333, 156 => 667, 157 => 350, 158 => 389, 159 => 556,
160 => 250, 161 => 389, 162 => 500, 163 => 500, 164 => 500, 165 => 500, 166 => 275, 167 => 500,
168 => 333, 169 => 760, 170 => 276, 171 => 500, 172 => 675, 173 => 333, 174 => 760, 175 => 333,
176 => 400, 177 => 675, 178 => 300, 179 => 300, 180 => 333, 181 => 500, 182 => 523, 183 => 250,
184 => 333, 185 => 300, 186 => 310, 187 => 500, 188 => 750, 189 => 750, 190 => 750, 191 => 500,
192 => 611, 193 => 611, 194 => 611, 195 => 611, 196 => 611, 197 => 611, 198 => 889, 199 => 667,
200 => 611, 201 => 611, 202 => 611, 203 => 611, 204 => 333, 205 => 333, 206 => 333, 207 => 333,
208 => 722, 209 => 667, 210 => 722, 211 => 722, 212 => 722, 213 => 722, 214 => 722, 215 => 675,
216 => 722, 217 => 722, 218 => 722, 219 => 722, 220 => 722, 221 => 556, 222 => 611, 223 => 500,
224 => 500, 225 => 500, 226 => 500, 227 => 500, 228 => 500, 229 => 500, 230 => 667, 231 => 444,
232 => 444, 233 => 444, 234 => 444, 235 => 444, 236 => 278, 237 => 278, 238 => 278, 239 => 278,
240 => 500, 241 => 500, 242 => 500, 243 => 500, 244 => 500, 245 => 500, 246 => 500, 247 => 675,
248 => 500, 249 => 500, 250 => 500, 251 => 500, 252 => 500, 253 => 444, 254 => 500, 255 => 444,
) ;
PK JvKFp a
FontMetrics/courierb.fmnu W+A 600, 1 => 600, 2 => 600, 3 => 600, 4 => 600, 5 => 600, 6 => 600, 7 => 600,
8 => 600, 9 => 600, 10 => 600, 11 => 600, 12 => 600, 13 => 600, 14 => 600, 15 => 600,
16 => 600, 17 => 600, 18 => 600, 19 => 600, 20 => 600, 21 => 600, 22 => 600, 23 => 600,
24 => 600, 25 => 600, 26 => 600, 27 => 600, 28 => 600, 29 => 600, 30 => 600, 31 => 600,
32 => 600, 33 => 600, 34 => 600, 35 => 600, 36 => 600, 37 => 600, 38 => 600, 39 => 600,
40 => 600, 41 => 600, 42 => 600, 43 => 600, 44 => 600, 45 => 600, 46 => 600, 47 => 600,
48 => 600, 49 => 600, 50 => 600, 51 => 600, 52 => 600, 53 => 600, 54 => 600, 55 => 600,
56 => 600, 57 => 600, 58 => 600, 59 => 600, 60 => 600, 61 => 600, 62 => 600, 63 => 600,
64 => 600, 65 => 600, 66 => 600, 67 => 600, 68 => 600, 69 => 600, 70 => 600, 71 => 600,
72 => 600, 73 => 600, 74 => 600, 75 => 600, 76 => 600, 77 => 600, 78 => 600, 79 => 600,
80 => 600, 81 => 600, 82 => 600, 83 => 600, 84 => 600, 85 => 600, 86 => 600, 87 => 600,
88 => 600, 89 => 600, 90 => 600, 91 => 600, 92 => 600, 93 => 600, 94 => 600, 95 => 600,
96 => 600, 97 => 600, 98 => 600, 99 => 600, 100 => 600, 101 => 600, 102 => 600, 103 => 600,
104 => 600, 105 => 600, 106 => 600, 107 => 600, 108 => 600, 109 => 600, 110 => 600, 111 => 600,
112 => 600, 113 => 600, 114 => 600, 115 => 600, 116 => 600, 117 => 600, 118 => 600, 119 => 600,
120 => 600, 121 => 600, 122 => 600, 123 => 600, 124 => 600, 125 => 600, 126 => 600, 127 => 600,
128 => 600, 129 => 600, 130 => 600, 131 => 600, 132 => 600, 133 => 600, 134 => 600, 135 => 600,
136 => 600, 137 => 600, 138 => 600, 139 => 600, 140 => 600, 141 => 600, 142 => 600, 143 => 600,
144 => 600, 145 => 600, 146 => 600, 147 => 600, 148 => 600, 149 => 600, 150 => 600, 151 => 600,
152 => 600, 153 => 600, 154 => 600, 155 => 600, 156 => 600, 157 => 600, 158 => 600, 159 => 600,
160 => 600, 161 => 600, 162 => 600, 163 => 600, 164 => 600, 165 => 600, 166 => 600, 167 => 600,
168 => 600, 169 => 600, 170 => 600, 171 => 600, 172 => 600, 173 => 600, 174 => 600, 175 => 600,
176 => 600, 177 => 600, 178 => 600, 179 => 600, 180 => 600, 181 => 600, 182 => 600, 183 => 600,
184 => 600, 185 => 600, 186 => 600, 187 => 600, 188 => 600, 189 => 600, 190 => 600, 191 => 600,
192 => 600, 193 => 600, 194 => 600, 195 => 600, 196 => 600, 197 => 600, 198 => 600, 199 => 600,
200 => 600, 201 => 600, 202 => 600, 203 => 600, 204 => 600, 205 => 600, 206 => 600, 207 => 600,
208 => 600, 209 => 600, 210 => 600, 211 => 600, 212 => 600, 213 => 600, 214 => 600, 215 => 600,
216 => 600, 217 => 600, 218 => 600, 219 => 600, 220 => 600, 221 => 600, 222 => 600, 223 => 600,
224 => 600, 225 => 600, 226 => 600, 227 => 600, 228 => 600, 229 => 600, 230 => 600, 231 => 600,
232 => 600, 233 => 600, 234 => 600, 235 => 600, 236 => 600, 237 => 600, 238 => 600, 239 => 600,
240 => 600, 241 => 600, 242 => 600, 243 => 600, 244 => 600, 245 => 600, 246 => 600, 247 => 600,
248 => 600, 249 => 600, 250 => 600, 251 => 600, 252 => 600, 253 => 600, 254 => 600, 255 => 600,
) ;
PK JvKK
FontMetrics/helvetica.fmnu W+A 500, 1 => 500, 2 => 500, 3 => 500, 4 => 500, 5 => 500, 6 => 500, 7 => 500,
8 => 500, 9 => 500, 10 => 500, 11 => 500, 12 => 500, 13 => 500, 14 => 500, 15 => 500,
16 => 500, 17 => 500, 18 => 500, 19 => 500, 20 => 500, 21 => 500, 22 => 500, 23 => 500,
24 => 500, 25 => 500, 26 => 500, 27 => 500, 28 => 500, 29 => 500, 30 => 500, 31 => 500,
32 => 278, 33 => 278, 34 => 355, 35 => 556, 36 => 556, 37 => 889, 38 => 667, 39 => 191,
40 => 333, 41 => 333, 42 => 389, 43 => 584, 44 => 278, 45 => 333, 46 => 278, 47 => 278,
48 => 556, 49 => 556, 50 => 556, 51 => 556, 52 => 556, 53 => 556, 54 => 556, 55 => 556,
56 => 556, 57 => 556, 58 => 278, 59 => 278, 60 => 584, 61 => 584, 62 => 584, 63 => 556,
64 => 1015, 65 => 667, 66 => 667, 67 => 722, 68 => 722, 69 => 667, 70 => 611, 71 => 778,
72 => 722, 73 => 278, 74 => 500, 75 => 667, 76 => 556, 77 => 833, 78 => 722, 79 => 778,
80 => 667, 81 => 778, 82 => 722, 83 => 667, 84 => 611, 85 => 722, 86 => 667, 87 => 944,
88 => 667, 89 => 667, 90 => 611, 91 => 278, 92 => 278, 93 => 277, 94 => 469, 95 => 556,
96 => 333, 97 => 556, 98 => 556, 99 => 500, 100 => 556, 101 => 556, 102 => 278, 103 => 556,
104 => 556, 105 => 222, 106 => 222, 107 => 500, 108 => 222, 109 => 833, 110 => 556, 111 => 556,
112 => 556, 113 => 556, 114 => 333, 115 => 500, 116 => 278, 117 => 556, 118 => 500, 119 => 722,
120 => 500, 121 => 500, 122 => 500, 123 => 334, 124 => 260, 125 => 334, 126 => 584, 127 => 500,
128 => 655, 129 => 500, 130 => 222, 131 => 278, 132 => 333, 133 => 1000, 134 => 556, 135 => 556,
136 => 333, 137 => 1000, 138 => 667, 139 => 250, 140 => 1000, 141 => 500, 142 => 611, 143 => 500,
144 => 500, 145 => 222, 146 => 221, 147 => 333, 148 => 333, 149 => 350, 150 => 556, 151 => 1000,
152 => 333, 153 => 1000, 154 => 500, 155 => 250, 156 => 938, 157 => 500, 158 => 500, 159 => 667,
160 => 278, 161 => 278, 162 => 556, 163 => 556, 164 => 556, 165 => 556, 166 => 260, 167 => 556,
168 => 333, 169 => 737, 170 => 370, 171 => 448, 172 => 584, 173 => 333, 174 => 737, 175 => 333,
176 => 606, 177 => 584, 178 => 350, 179 => 350, 180 => 333, 181 => 556, 182 => 537, 183 => 278,
184 => 333, 185 => 350, 186 => 365, 187 => 448, 188 => 869, 189 => 869, 190 => 879, 191 => 556,
192 => 667, 193 => 667, 194 => 667, 195 => 667, 196 => 667, 197 => 667, 198 => 1000, 199 => 722,
200 => 667, 201 => 667, 202 => 667, 203 => 667, 204 => 278, 205 => 278, 206 => 278, 207 => 278,
208 => 722, 209 => 722, 210 => 778, 211 => 778, 212 => 778, 213 => 778, 214 => 778, 215 => 584,
216 => 778, 217 => 722, 218 => 722, 219 => 722, 220 => 722, 221 => 667, 222 => 666, 223 => 611,
224 => 556, 225 => 556, 226 => 556, 227 => 556, 228 => 556, 229 => 556, 230 => 896, 231 => 500,
232 => 556, 233 => 556, 234 => 556, 235 => 556, 236 => 251, 237 => 251, 238 => 251, 239 => 251,
240 => 556, 241 => 556, 242 => 556, 243 => 556, 244 => 556, 245 => 556, 246 => 556, 247 => 584,
248 => 611, 249 => 556, 250 => 556, 251 => 556, 252 => 556, 253 => 500, 254 => 555, 255 => 500,
) ;
PK JvK2t~m
FontMetrics/helveticab.fmnu W+A 278, 1 => 278, 2 => 278, 3 => 278, 4 => 278, 5 => 278, 6 => 278, 7 => 278,
8 => 278, 9 => 278, 10 => 278, 11 => 278, 12 => 278, 13 => 278, 14 => 278, 15 => 278,
16 => 278, 17 => 278, 18 => 278, 19 => 278, 20 => 278, 21 => 278, 22 => 278, 23 => 278,
24 => 278, 25 => 278, 26 => 278, 27 => 278, 28 => 278, 29 => 278, 30 => 278, 31 => 278,
32 => 278, 33 => 333, 34 => 474, 35 => 556, 36 => 556, 37 => 889, 38 => 722, 39 => 238,
40 => 333, 41 => 333, 42 => 389, 43 => 584, 44 => 278, 45 => 333, 46 => 278, 47 => 278,
48 => 556, 49 => 556, 50 => 556, 51 => 556, 52 => 556, 53 => 556, 54 => 556, 55 => 556,
56 => 556, 57 => 556, 58 => 333, 59 => 333, 60 => 584, 61 => 584, 62 => 584, 63 => 611,
64 => 975, 65 => 722, 66 => 722, 67 => 722, 68 => 722, 69 => 667, 70 => 611, 71 => 778,
72 => 722, 73 => 278, 74 => 556, 75 => 722, 76 => 611, 77 => 833, 78 => 722, 79 => 778,
80 => 667, 81 => 778, 82 => 722, 83 => 667, 84 => 611, 85 => 722, 86 => 667, 87 => 944,
88 => 667, 89 => 667, 90 => 611, 91 => 333, 92 => 278, 93 => 333, 94 => 584, 95 => 556,
96 => 333, 97 => 556, 98 => 611, 99 => 556, 100 => 611, 101 => 556, 102 => 333, 103 => 611,
104 => 611, 105 => 278, 106 => 278, 107 => 556, 108 => 278, 109 => 889, 110 => 611, 111 => 611,
112 => 611, 113 => 611, 114 => 389, 115 => 556, 116 => 333, 117 => 611, 118 => 556, 119 => 778,
120 => 556, 121 => 556, 122 => 500, 123 => 389, 124 => 280, 125 => 389, 126 => 584, 127 => 350,
128 => 556, 129 => 350, 130 => 278, 131 => 556, 132 => 500, 133 => 1000, 134 => 556, 135 => 556,
136 => 333, 137 => 1000, 138 => 667, 139 => 333, 140 => 1000, 141 => 350, 142 => 611, 143 => 350,
144 => 350, 145 => 278, 146 => 278, 147 => 500, 148 => 500, 149 => 350, 150 => 556, 151 => 1000,
152 => 333, 153 => 1000, 154 => 556, 155 => 333, 156 => 944, 157 => 350, 158 => 500, 159 => 667,
160 => 278, 161 => 333, 162 => 556, 163 => 556, 164 => 556, 165 => 556, 166 => 280, 167 => 556,
168 => 333, 169 => 737, 170 => 370, 171 => 556, 172 => 584, 173 => 333, 174 => 737, 175 => 333,
176 => 400, 177 => 584, 178 => 333, 179 => 333, 180 => 333, 181 => 611, 182 => 556, 183 => 278,
184 => 333, 185 => 333, 186 => 365, 187 => 556, 188 => 834, 189 => 834, 190 => 834, 191 => 611,
192 => 722, 193 => 722, 194 => 722, 195 => 722, 196 => 722, 197 => 722, 198 => 1000, 199 => 722,
200 => 667, 201 => 667, 202 => 667, 203 => 667, 204 => 278, 205 => 278, 206 => 278, 207 => 278,
208 => 722, 209 => 722, 210 => 778, 211 => 778, 212 => 778, 213 => 778, 214 => 778, 215 => 584,
216 => 778, 217 => 722, 218 => 722, 219 => 722, 220 => 722, 221 => 667, 222 => 667, 223 => 611,
224 => 556, 225 => 556, 226 => 556, 227 => 556, 228 => 556, 229 => 556, 230 => 889, 231 => 556,
232 => 556, 233 => 556, 234 => 556, 235 => 556, 236 => 278, 237 => 278, 238 => 278, 239 => 278,
240 => 611, 241 => 611, 242 => 611, 243 => 611, 244 => 611, 245 => 611, 246 => 611, 247 => 584,
248 => 611, 249 => 611, 250 => 611, 251 => 611, 252 => 611, 253 => 556, 254 => 611, 255 => 556,
) ;
PK JvKFh*
FontMetrics/timesb.fmnu W+A 250, 1 => 250, 2 => 250, 3 => 250, 4 => 250, 5 => 250, 6 => 250, 7 => 250,
8 => 250, 9 => 250, 10 => 250, 11 => 250, 12 => 250, 13 => 250, 14 => 250, 15 => 250,
16 => 250, 17 => 250, 18 => 250, 19 => 250, 20 => 250, 21 => 250, 22 => 250, 23 => 250,
24 => 250, 25 => 250, 26 => 250, 27 => 250, 28 => 250, 29 => 250, 30 => 250, 31 => 250,
32 => 250, 33 => 333, 34 => 555, 35 => 500, 36 => 500, 37 => 1000, 38 => 833, 39 => 278,
40 => 333, 41 => 333, 42 => 500, 43 => 570, 44 => 250, 45 => 333, 46 => 250, 47 => 278,
48 => 500, 49 => 500, 50 => 500, 51 => 500, 52 => 500, 53 => 500, 54 => 500, 55 => 500,
56 => 500, 57 => 500, 58 => 333, 59 => 333, 60 => 570, 61 => 570, 62 => 570, 63 => 500,
64 => 930, 65 => 722, 66 => 667, 67 => 722, 68 => 722, 69 => 667, 70 => 611, 71 => 778,
72 => 778, 73 => 389, 74 => 500, 75 => 778, 76 => 667, 77 => 944, 78 => 722, 79 => 778,
80 => 611, 81 => 778, 82 => 722, 83 => 556, 84 => 667, 85 => 722, 86 => 722, 87 => 1000,
88 => 722, 89 => 722, 90 => 667, 91 => 333, 92 => 278, 93 => 333, 94 => 581, 95 => 500,
96 => 333, 97 => 500, 98 => 556, 99 => 444, 100 => 556, 101 => 444, 102 => 333, 103 => 500,
104 => 556, 105 => 278, 106 => 333, 107 => 556, 108 => 278, 109 => 833, 110 => 556, 111 => 500,
112 => 556, 113 => 556, 114 => 444, 115 => 389, 116 => 333, 117 => 556, 118 => 500, 119 => 722,
120 => 500, 121 => 500, 122 => 444, 123 => 394, 124 => 220, 125 => 394, 126 => 520, 127 => 350,
128 => 500, 129 => 350, 130 => 333, 131 => 500, 132 => 500, 133 => 1000, 134 => 500, 135 => 500,
136 => 333, 137 => 1000, 138 => 556, 139 => 333, 140 => 1000, 141 => 350, 142 => 667, 143 => 350,
144 => 350, 145 => 333, 146 => 333, 147 => 500, 148 => 500, 149 => 350, 150 => 500, 151 => 1000,
152 => 333, 153 => 1000, 154 => 389, 155 => 333, 156 => 722, 157 => 350, 158 => 444, 159 => 722,
160 => 250, 161 => 333, 162 => 500, 163 => 500, 164 => 500, 165 => 500, 166 => 220, 167 => 500,
168 => 333, 169 => 747, 170 => 300, 171 => 500, 172 => 570, 173 => 333, 174 => 747, 175 => 333,
176 => 400, 177 => 570, 178 => 300, 179 => 300, 180 => 333, 181 => 556, 182 => 540, 183 => 250,
184 => 333, 185 => 300, 186 => 330, 187 => 500, 188 => 750, 189 => 750, 190 => 750, 191 => 500,
192 => 722, 193 => 722, 194 => 722, 195 => 722, 196 => 722, 197 => 722, 198 => 1000, 199 => 722,
200 => 667, 201 => 667, 202 => 667, 203 => 667, 204 => 389, 205 => 389, 206 => 389, 207 => 389,
208 => 722, 209 => 722, 210 => 778, 211 => 778, 212 => 778, 213 => 778, 214 => 778, 215 => 570,
216 => 778, 217 => 722, 218 => 722, 219 => 722, 220 => 722, 221 => 722, 222 => 611, 223 => 556,
224 => 500, 225 => 500, 226 => 500, 227 => 500, 228 => 500, 229 => 500, 230 => 722, 231 => 444,
232 => 444, 233 => 444, 234 => 444, 235 => 444, 236 => 278, 237 => 278, 238 => 278, 239 => 278,
240 => 500, 241 => 556, 242 => 500, 243 => 500, 244 => 500, 245 => 500, 246 => 500, 247 => 570,
248 => 500, 249 => 556, 250 => 556, 251 => 556, 252 => 556, 253 => 500, 254 => 556, 255 => 500,
) ;
PK JvKM
FontMetrics/helveticai.fmnu W+A 278, 1 => 278, 2 => 278, 3 => 278, 4 => 278, 5 => 278, 6 => 278, 7 => 278,
8 => 278, 9 => 278, 10 => 278, 11 => 278, 12 => 278, 13 => 278, 14 => 278, 15 => 278,
16 => 278, 17 => 278, 18 => 278, 19 => 278, 20 => 278, 21 => 278, 22 => 278, 23 => 278,
24 => 278, 25 => 278, 26 => 278, 27 => 278, 28 => 278, 29 => 278, 30 => 278, 31 => 278,
32 => 278, 33 => 278, 34 => 355, 35 => 556, 36 => 556, 37 => 889, 38 => 667, 39 => 191,
40 => 333, 41 => 333, 42 => 389, 43 => 584, 44 => 278, 45 => 333, 46 => 278, 47 => 278,
48 => 556, 49 => 556, 50 => 556, 51 => 556, 52 => 556, 53 => 556, 54 => 556, 55 => 556,
56 => 556, 57 => 556, 58 => 278, 59 => 278, 60 => 584, 61 => 584, 62 => 584, 63 => 556,
64 => 1015, 65 => 667, 66 => 667, 67 => 722, 68 => 722, 69 => 667, 70 => 611, 71 => 778,
72 => 722, 73 => 278, 74 => 500, 75 => 667, 76 => 556, 77 => 833, 78 => 722, 79 => 778,
80 => 667, 81 => 778, 82 => 722, 83 => 667, 84 => 611, 85 => 722, 86 => 667, 87 => 944,
88 => 667, 89 => 667, 90 => 611, 91 => 278, 92 => 278, 93 => 278, 94 => 469, 95 => 556,
96 => 333, 97 => 556, 98 => 556, 99 => 500, 100 => 556, 101 => 556, 102 => 278, 103 => 556,
104 => 556, 105 => 222, 106 => 222, 107 => 500, 108 => 222, 109 => 833, 110 => 556, 111 => 556,
112 => 556, 113 => 556, 114 => 333, 115 => 500, 116 => 278, 117 => 556, 118 => 500, 119 => 722,
120 => 500, 121 => 500, 122 => 500, 123 => 334, 124 => 260, 125 => 334, 126 => 584, 127 => 350,
128 => 556, 129 => 350, 130 => 222, 131 => 556, 132 => 333, 133 => 1000, 134 => 556, 135 => 556,
136 => 333, 137 => 1000, 138 => 667, 139 => 333, 140 => 1000, 141 => 350, 142 => 611, 143 => 350,
144 => 350, 145 => 222, 146 => 222, 147 => 333, 148 => 333, 149 => 350, 150 => 556, 151 => 1000,
152 => 333, 153 => 1000, 154 => 500, 155 => 333, 156 => 944, 157 => 350, 158 => 500, 159 => 667,
160 => 278, 161 => 333, 162 => 556, 163 => 556, 164 => 556, 165 => 556, 166 => 260, 167 => 556,
168 => 333, 169 => 737, 170 => 370, 171 => 556, 172 => 584, 173 => 333, 174 => 737, 175 => 333,
176 => 400, 177 => 584, 178 => 333, 179 => 333, 180 => 333, 181 => 556, 182 => 537, 183 => 278,
184 => 333, 185 => 333, 186 => 365, 187 => 556, 188 => 834, 189 => 834, 190 => 834, 191 => 611,
192 => 667, 193 => 667, 194 => 667, 195 => 667, 196 => 667, 197 => 667, 198 => 1000, 199 => 722,
200 => 667, 201 => 667, 202 => 667, 203 => 667, 204 => 278, 205 => 278, 206 => 278, 207 => 278,
208 => 722, 209 => 722, 210 => 778, 211 => 778, 212 => 778, 213 => 778, 214 => 778, 215 => 584,
216 => 778, 217 => 722, 218 => 722, 219 => 722, 220 => 722, 221 => 667, 222 => 667, 223 => 611,
224 => 556, 225 => 556, 226 => 556, 227 => 556, 228 => 556, 229 => 556, 230 => 889, 231 => 500,
232 => 556, 233 => 556, 234 => 556, 235 => 556, 236 => 278, 237 => 278, 238 => 278, 239 => 278,
240 => 556, 241 => 556, 242 => 556, 243 => 556, 244 => 556, 245 => 556, 246 => 556, 247 => 584,
248 => 611, 249 => 556, 250 => 556, 251 => 556, 252 => 556, 253 => 500, 254 => 556, 255 => 500,
) ;
PK JvKi
FontMetrics/courieri.fmnu W+A 600, 1 => 600, 2 => 600, 3 => 600, 4 => 600, 5 => 600, 6 => 600, 7 => 600,
8 => 600, 9 => 600, 10 => 600, 11 => 600, 12 => 600, 13 => 600, 14 => 600, 15 => 600,
16 => 600, 17 => 600, 18 => 600, 19 => 600, 20 => 600, 21 => 600, 22 => 600, 23 => 600,
24 => 600, 25 => 600, 26 => 600, 27 => 600, 28 => 600, 29 => 600, 30 => 600, 31 => 600,
32 => 600, 33 => 600, 34 => 600, 35 => 600, 36 => 600, 37 => 600, 38 => 600, 39 => 600,
40 => 600, 41 => 600, 42 => 600, 43 => 600, 44 => 600, 45 => 600, 46 => 600, 47 => 600,
48 => 600, 49 => 600, 50 => 600, 51 => 600, 52 => 600, 53 => 600, 54 => 600, 55 => 600,
56 => 600, 57 => 600, 58 => 600, 59 => 600, 60 => 600, 61 => 600, 62 => 600, 63 => 600,
64 => 600, 65 => 600, 66 => 600, 67 => 600, 68 => 600, 69 => 600, 70 => 600, 71 => 600,
72 => 600, 73 => 600, 74 => 600, 75 => 600, 76 => 600, 77 => 600, 78 => 600, 79 => 600,
80 => 600, 81 => 600, 82 => 600, 83 => 600, 84 => 600, 85 => 600, 86 => 600, 87 => 600,
88 => 600, 89 => 600, 90 => 600, 91 => 600, 92 => 600, 93 => 600, 94 => 600, 95 => 600,
96 => 600, 97 => 600, 98 => 600, 99 => 600, 100 => 600, 101 => 600, 102 => 600, 103 => 600,
104 => 600, 105 => 600, 106 => 600, 107 => 600, 108 => 600, 109 => 600, 110 => 600, 111 => 600,
112 => 600, 113 => 600, 114 => 600, 115 => 600, 116 => 600, 117 => 600, 118 => 600, 119 => 600,
120 => 600, 121 => 600, 122 => 600, 123 => 600, 124 => 600, 125 => 600, 126 => 600, 127 => 600,
128 => 600, 129 => 600, 130 => 600, 131 => 600, 132 => 600, 133 => 600, 134 => 600, 135 => 600,
136 => 600, 137 => 600, 138 => 600, 139 => 600, 140 => 600, 141 => 600, 142 => 600, 143 => 600,
144 => 600, 145 => 600, 146 => 600, 147 => 600, 148 => 600, 149 => 600, 150 => 600, 151 => 600,
152 => 600, 153 => 600, 154 => 600, 155 => 600, 156 => 600, 157 => 600, 158 => 600, 159 => 600,
160 => 600, 161 => 600, 162 => 600, 163 => 600, 164 => 600, 165 => 600, 166 => 600, 167 => 600,
168 => 600, 169 => 600, 170 => 600, 171 => 600, 172 => 600, 173 => 600, 174 => 600, 175 => 600,
176 => 600, 177 => 600, 178 => 600, 179 => 600, 180 => 600, 181 => 600, 182 => 600, 183 => 600,
184 => 600, 185 => 600, 186 => 600, 187 => 600, 188 => 600, 189 => 600, 190 => 600, 191 => 600,
192 => 600, 193 => 600, 194 => 600, 195 => 600, 196 => 600, 197 => 600, 198 => 600, 199 => 600,
200 => 600, 201 => 600, 202 => 600, 203 => 600, 204 => 600, 205 => 600, 206 => 600, 207 => 600,
208 => 600, 209 => 600, 210 => 600, 211 => 600, 212 => 600, 213 => 600, 214 => 600, 215 => 600,
216 => 600, 217 => 600, 218 => 600, 219 => 600, 220 => 600, 221 => 600, 222 => 600, 223 => 600,
224 => 600, 225 => 600, 226 => 600, 227 => 600, 228 => 600, 229 => 600, 230 => 600, 231 => 600,
232 => 600, 233 => 600, 234 => 600, 235 => 600, 236 => 600, 237 => 600, 238 => 600, 239 => 600,
240 => 600, 241 => 600, 242 => 600, 243 => 600, 244 => 600, 245 => 600, 246 => 600, 247 => 600,
248 => 600, 249 => 600, 250 => 600, 251 => 600, 252 => 600, 253 => 600, 254 => 600, 255 => 600,
) ;
PK JvK^Dr
FontMetrics/helveticabi.fmnu W+A 278, 1 => 278, 2 => 278, 3 => 278, 4 => 278, 5 => 278, 6 => 278, 7 => 278,
8 => 278, 9 => 278, 10 => 278, 11 => 278, 12 => 278, 13 => 278, 14 => 278, 15 => 278,
16 => 278, 17 => 278, 18 => 278, 19 => 278, 20 => 278, 21 => 278, 22 => 278, 23 => 278,
24 => 278, 25 => 278, 26 => 278, 27 => 278, 28 => 278, 29 => 278, 30 => 278, 31 => 278,
32 => 278, 33 => 333, 34 => 474, 35 => 556, 36 => 556, 37 => 889, 38 => 722, 39 => 238,
40 => 333, 41 => 333, 42 => 389, 43 => 584, 44 => 278, 45 => 333, 46 => 278, 47 => 278,
48 => 556, 49 => 556, 50 => 556, 51 => 556, 52 => 556, 53 => 556, 54 => 556, 55 => 556,
56 => 556, 57 => 556, 58 => 333, 59 => 333, 60 => 584, 61 => 584, 62 => 584, 63 => 611,
64 => 975, 65 => 722, 66 => 722, 67 => 722, 68 => 722, 69 => 667, 70 => 611, 71 => 778,
72 => 722, 73 => 278, 74 => 556, 75 => 722, 76 => 611, 77 => 833, 78 => 722, 79 => 778,
80 => 667, 81 => 778, 82 => 722, 83 => 667, 84 => 611, 85 => 722, 86 => 667, 87 => 944,
88 => 667, 89 => 667, 90 => 611, 91 => 333, 92 => 278, 93 => 333, 94 => 584, 95 => 556,
96 => 333, 97 => 556, 98 => 611, 99 => 556, 100 => 611, 101 => 556, 102 => 333, 103 => 611,
104 => 611, 105 => 278, 106 => 278, 107 => 556, 108 => 278, 109 => 889, 110 => 611, 111 => 611,
112 => 611, 113 => 611, 114 => 389, 115 => 556, 116 => 333, 117 => 611, 118 => 556, 119 => 778,
120 => 556, 121 => 556, 122 => 500, 123 => 389, 124 => 280, 125 => 389, 126 => 584, 127 => 350,
128 => 556, 129 => 350, 130 => 278, 131 => 556, 132 => 500, 133 => 1000, 134 => 556, 135 => 556,
136 => 333, 137 => 1000, 138 => 667, 139 => 333, 140 => 1000, 141 => 350, 142 => 611, 143 => 350,
144 => 350, 145 => 278, 146 => 278, 147 => 500, 148 => 500, 149 => 350, 150 => 556, 151 => 1000,
152 => 333, 153 => 1000, 154 => 556, 155 => 333, 156 => 944, 157 => 350, 158 => 500, 159 => 667,
160 => 278, 161 => 333, 162 => 556, 163 => 556, 164 => 556, 165 => 556, 166 => 280, 167 => 556,
168 => 333, 169 => 737, 170 => 370, 171 => 556, 172 => 584, 173 => 333, 174 => 737, 175 => 333,
176 => 400, 177 => 584, 178 => 333, 179 => 333, 180 => 333, 181 => 611, 182 => 556, 183 => 278,
184 => 333, 185 => 333, 186 => 365, 187 => 556, 188 => 834, 189 => 834, 190 => 834, 191 => 611,
192 => 722, 193 => 722, 194 => 722, 195 => 722, 196 => 722, 197 => 722, 198 => 1000, 199 => 722,
200 => 667, 201 => 667, 202 => 667, 203 => 667, 204 => 278, 205 => 278, 206 => 278, 207 => 278,
208 => 722, 209 => 722, 210 => 778, 211 => 778, 212 => 778, 213 => 778, 214 => 778, 215 => 584,
216 => 778, 217 => 722, 218 => 722, 219 => 722, 220 => 722, 221 => 667, 222 => 667, 223 => 611,
224 => 556, 225 => 556, 226 => 556, 227 => 556, 228 => 556, 229 => 556, 230 => 889, 231 => 556,
232 => 556, 233 => 556, 234 => 556, 235 => 556, 236 => 278, 237 => 278, 238 => 278, 239 => 278,
240 => 611, 241 => 611, 242 => 611, 243 => 611, 244 => 611, 245 => 611, 246 => 611, 247 => 584,
248 => 611, 249 => 611, 250 => 611, 251 => 611, 252 => 611, 253 => 556, 254 => 611, 255 => 556,
) ;
PK JvK
FontMetrics/symbol.fmnu W+A 587, 1 => 587, 2 => 587, 3 => 587, 4 => 587, 5 => 587, 6 => 587, 7 => 587,
8 => 587, 9 => 587, 10 => 587, 11 => 587, 12 => 587, 13 => 587, 14 => 587, 15 => 587,
16 => 587, 17 => 587, 18 => 587, 19 => 587, 20 => 587, 21 => 587, 22 => 587, 23 => 587,
24 => 587, 25 => 587, 26 => 587, 27 => 587, 28 => 587, 29 => 587, 30 => 587, 31 => 587,
32 => 250, 33 => 333, 34 => 713, 35 => 500, 36 => 549, 37 => 833, 38 => 778, 39 => 439,
40 => 333, 41 => 333, 42 => 500, 43 => 549, 44 => 250, 45 => 549, 46 => 250, 47 => 278,
48 => 500, 49 => 500, 50 => 500, 51 => 500, 52 => 500, 53 => 500, 54 => 500, 55 => 500,
56 => 500, 57 => 500, 58 => 278, 59 => 278, 60 => 549, 61 => 549, 62 => 549, 63 => 444,
64 => 549, 65 => 722, 66 => 667, 67 => 722, 68 => 612, 69 => 611, 70 => 763, 71 => 603,
72 => 722, 73 => 333, 74 => 631, 75 => 722, 76 => 686, 77 => 889, 78 => 722, 79 => 722,
80 => 768, 81 => 741, 82 => 556, 83 => 592, 84 => 611, 85 => 690, 86 => 439, 87 => 768,
88 => 645, 89 => 795, 90 => 611, 91 => 333, 92 => 863, 93 => 333, 94 => 658, 95 => 500,
96 => 500, 97 => 631, 98 => 549, 99 => 549, 100 => 494, 101 => 439, 102 => 521, 103 => 411,
104 => 603, 105 => 329, 106 => 603, 107 => 549, 108 => 549, 109 => 576, 110 => 521, 111 => 549,
112 => 549, 113 => 521, 114 => 549, 115 => 603, 116 => 439, 117 => 576, 118 => 713, 119 => 686,
120 => 493, 121 => 686, 122 => 494, 123 => 480, 124 => 200, 125 => 480, 126 => 549, 127 => 587,
128 => 587, 129 => 587, 130 => 587, 131 => 587, 132 => 587, 133 => 587, 134 => 587, 135 => 587,
136 => 587, 137 => 587, 138 => 587, 139 => 587, 140 => 587, 141 => 587, 142 => 587, 143 => 587,
144 => 587, 145 => 587, 146 => 587, 147 => 587, 148 => 587, 149 => 587, 150 => 587, 151 => 587,
152 => 587, 153 => 587, 154 => 587, 155 => 587, 156 => 587, 157 => 587, 158 => 587, 159 => 587,
160 => 750, 161 => 620, 162 => 247, 163 => 549, 164 => 167, 165 => 713, 166 => 500, 167 => 753,
168 => 753, 169 => 753, 170 => 753, 171 => 1042, 172 => 987, 173 => 603, 174 => 987, 175 => 603,
176 => 400, 177 => 549, 178 => 411, 179 => 549, 180 => 549, 181 => 713, 182 => 494, 183 => 460,
184 => 549, 185 => 549, 186 => 549, 187 => 549, 188 => 1000, 189 => 603, 190 => 1000, 191 => 658,
192 => 823, 193 => 686, 194 => 795, 195 => 987, 196 => 768, 197 => 768, 198 => 823, 199 => 768,
200 => 768, 201 => 713, 202 => 713, 203 => 713, 204 => 713, 205 => 713, 206 => 713, 207 => 713,
208 => 768, 209 => 713, 210 => 790, 211 => 790, 212 => 890, 213 => 823, 214 => 549, 215 => 250,
216 => 713, 217 => 603, 218 => 603, 219 => 1042, 220 => 987, 221 => 603, 222 => 987, 223 => 603,
224 => 494, 225 => 329, 226 => 790, 227 => 790, 228 => 786, 229 => 713, 230 => 384, 231 => 384,
232 => 384, 233 => 384, 234 => 384, 235 => 384, 236 => 494, 237 => 494, 238 => 494, 239 => 494,
240 => 587, 241 => 329, 242 => 274, 243 => 686, 244 => 686, 245 => 686, 246 => 384, 247 => 384,
248 => 384, 249 => 384, 250 => 384, 251 => 384, 252 => 494, 253 => 494, 254 => 494, 255 => 587,
) ;
PK JvKI
FontMetrics/courier.fmnu W+A 600, 1 => 600, 2 => 600, 3 => 600, 4 => 600, 5 => 600, 6 => 600, 7 => 600,
8 => 600, 9 => 600, 10 => 600, 11 => 600, 12 => 600, 13 => 600, 14 => 600, 15 => 600,
16 => 600, 17 => 600, 18 => 600, 19 => 600, 20 => 600, 21 => 600, 22 => 600, 23 => 600,
24 => 600, 25 => 600, 26 => 600, 27 => 600, 28 => 600, 29 => 600, 30 => 600, 31 => 600,
32 => 600, 33 => 600, 34 => 600, 35 => 600, 36 => 600, 37 => 600, 38 => 600, 39 => 600,
40 => 600, 41 => 600, 42 => 600, 43 => 600, 44 => 600, 45 => 600, 46 => 600, 47 => 600,
48 => 600, 49 => 600, 50 => 600, 51 => 600, 52 => 600, 53 => 600, 54 => 600, 55 => 600,
56 => 600, 57 => 600, 58 => 600, 59 => 600, 60 => 600, 61 => 600, 62 => 600, 63 => 600,
64 => 600, 65 => 600, 66 => 600, 67 => 600, 68 => 600, 69 => 600, 70 => 600, 71 => 600,
72 => 600, 73 => 600, 74 => 600, 75 => 600, 76 => 600, 77 => 600, 78 => 600, 79 => 600,
80 => 600, 81 => 600, 82 => 600, 83 => 600, 84 => 600, 85 => 600, 86 => 600, 87 => 600,
88 => 600, 89 => 600, 90 => 600, 91 => 600, 92 => 600, 93 => 600, 94 => 600, 95 => 600,
96 => 600, 97 => 600, 98 => 600, 99 => 600, 100 => 600, 101 => 600, 102 => 600, 103 => 600,
104 => 600, 105 => 600, 106 => 600, 107 => 600, 108 => 600, 109 => 600, 110 => 600, 111 => 600,
112 => 600, 113 => 600, 114 => 600, 115 => 600, 116 => 600, 117 => 600, 118 => 600, 119 => 600,
120 => 600, 121 => 600, 122 => 600, 123 => 600, 124 => 600, 125 => 600, 126 => 600, 127 => 600,
128 => 600, 129 => 600, 130 => 600, 131 => 600, 132 => 600, 133 => 600, 134 => 600, 135 => 600,
136 => 600, 137 => 600, 138 => 600, 139 => 600, 140 => 600, 141 => 600, 142 => 600, 143 => 600,
144 => 600, 145 => 600, 146 => 600, 147 => 600, 148 => 600, 149 => 600, 150 => 600, 151 => 600,
152 => 600, 153 => 600, 154 => 600, 155 => 600, 156 => 600, 157 => 600, 158 => 600, 159 => 600,
160 => 600, 161 => 600, 162 => 600, 163 => 600, 164 => 600, 165 => 600, 166 => 600, 167 => 600,
168 => 600, 169 => 600, 170 => 600, 171 => 600, 172 => 600, 173 => 600, 174 => 600, 175 => 600,
176 => 600, 177 => 600, 178 => 600, 179 => 600, 180 => 600, 181 => 600, 182 => 600, 183 => 600,
184 => 600, 185 => 600, 186 => 600, 187 => 600, 188 => 600, 189 => 600, 190 => 600, 191 => 600,
192 => 600, 193 => 600, 194 => 600, 195 => 600, 196 => 600, 197 => 600, 198 => 600, 199 => 600,
200 => 600, 201 => 600, 202 => 600, 203 => 600, 204 => 600, 205 => 600, 206 => 600, 207 => 600,
208 => 600, 209 => 600, 210 => 600, 211 => 600, 212 => 600, 213 => 600, 214 => 600, 215 => 600,
216 => 600, 217 => 600, 218 => 600, 219 => 600, 220 => 600, 221 => 600, 222 => 600, 223 => 600,
224 => 600, 225 => 600, 226 => 600, 227 => 600, 228 => 600, 229 => 600, 230 => 600, 231 => 600,
232 => 600, 233 => 600, 234 => 600, 235 => 600, 236 => 600, 237 => 600, 238 => 600, 239 => 600,
240 => 600, 241 => 600, 242 => 600, 243 => 600, 244 => 600, 245 => 600, 246 => 600, 247 => 600,
248 => 600, 249 => 600, 250 => 600, 251 => 600, 252 => 600, 253 => 600, 254 => 600, 255 => 600,
) ;
PK JvK$
FontMetrics/timesbi.fmnu W+A 250, 1 => 250, 2 => 250, 3 => 250, 4 => 250, 5 => 250, 6 => 250, 7 => 250,
8 => 250, 9 => 250, 10 => 250, 11 => 250, 12 => 250, 13 => 250, 14 => 250, 15 => 250,
16 => 250, 17 => 250, 18 => 250, 19 => 250, 20 => 250, 21 => 250, 22 => 250, 23 => 250,
24 => 250, 25 => 250, 26 => 250, 27 => 250, 28 => 250, 29 => 250, 30 => 250, 31 => 250,
32 => 250, 33 => 389, 34 => 555, 35 => 500, 36 => 500, 37 => 833, 38 => 778, 39 => 278,
40 => 333, 41 => 333, 42 => 500, 43 => 570, 44 => 250, 45 => 333, 46 => 250, 47 => 278,
48 => 500, 49 => 500, 50 => 500, 51 => 500, 52 => 500, 53 => 500, 54 => 500, 55 => 500,
56 => 500, 57 => 500, 58 => 333, 59 => 333, 60 => 570, 61 => 570, 62 => 570, 63 => 500,
64 => 832, 65 => 667, 66 => 667, 67 => 667, 68 => 722, 69 => 667, 70 => 667, 71 => 722,
72 => 778, 73 => 389, 74 => 500, 75 => 667, 76 => 611, 77 => 889, 78 => 722, 79 => 722,
80 => 611, 81 => 722, 82 => 667, 83 => 556, 84 => 611, 85 => 722, 86 => 667, 87 => 889,
88 => 667, 89 => 611, 90 => 611, 91 => 333, 92 => 278, 93 => 333, 94 => 570, 95 => 500,
96 => 333, 97 => 500, 98 => 500, 99 => 444, 100 => 500, 101 => 444, 102 => 333, 103 => 500,
104 => 556, 105 => 278, 106 => 278, 107 => 500, 108 => 278, 109 => 778, 110 => 556, 111 => 500,
112 => 500, 113 => 500, 114 => 389, 115 => 389, 116 => 278, 117 => 556, 118 => 444, 119 => 667,
120 => 500, 121 => 444, 122 => 389, 123 => 348, 124 => 220, 125 => 348, 126 => 570, 127 => 350,
128 => 500, 129 => 350, 130 => 333, 131 => 500, 132 => 500, 133 => 1000, 134 => 500, 135 => 500,
136 => 333, 137 => 1000, 138 => 556, 139 => 333, 140 => 944, 141 => 350, 142 => 611, 143 => 350,
144 => 350, 145 => 333, 146 => 333, 147 => 500, 148 => 500, 149 => 350, 150 => 500, 151 => 1000,
152 => 333, 153 => 1000, 154 => 389, 155 => 333, 156 => 722, 157 => 350, 158 => 389, 159 => 611,
160 => 250, 161 => 389, 162 => 500, 163 => 500, 164 => 500, 165 => 500, 166 => 220, 167 => 500,
168 => 333, 169 => 747, 170 => 266, 171 => 500, 172 => 606, 173 => 333, 174 => 747, 175 => 333,
176 => 400, 177 => 570, 178 => 300, 179 => 300, 180 => 333, 181 => 576, 182 => 500, 183 => 250,
184 => 333, 185 => 300, 186 => 300, 187 => 500, 188 => 750, 189 => 750, 190 => 750, 191 => 500,
192 => 667, 193 => 667, 194 => 667, 195 => 667, 196 => 667, 197 => 667, 198 => 944, 199 => 667,
200 => 667, 201 => 667, 202 => 667, 203 => 667, 204 => 389, 205 => 389, 206 => 389, 207 => 389,
208 => 722, 209 => 722, 210 => 722, 211 => 722, 212 => 722, 213 => 722, 214 => 722, 215 => 570,
216 => 722, 217 => 722, 218 => 722, 219 => 722, 220 => 722, 221 => 611, 222 => 611, 223 => 500,
224 => 500, 225 => 500, 226 => 500, 227 => 500, 228 => 500, 229 => 500, 230 => 722, 231 => 444,
232 => 444, 233 => 444, 234 => 444, 235 => 444, 236 => 278, 237 => 278, 238 => 278, 239 => 278,
240 => 500, 241 => 556, 242 => 500, 243 => 500, 244 => 500, 245 => 500, 246 => 500, 247 => 570,
248 => 500, 249 => 556, 250 => 556, 251 => 556, 252 => 556, 253 => 444, 254 => 500, 255 => 444,
) ;
PK JvKlgF
FontMetrics/courierbi.fmnu W+A 600, 1 => 600, 2 => 600, 3 => 600, 4 => 600, 5 => 600, 6 => 600, 7 => 600,
8 => 600, 9 => 600, 10 => 600, 11 => 600, 12 => 600, 13 => 600, 14 => 600, 15 => 600,
16 => 600, 17 => 600, 18 => 600, 19 => 600, 20 => 600, 21 => 600, 22 => 600, 23 => 600,
24 => 600, 25 => 600, 26 => 600, 27 => 600, 28 => 600, 29 => 600, 30 => 600, 31 => 600,
32 => 600, 33 => 600, 34 => 600, 35 => 600, 36 => 600, 37 => 600, 38 => 600, 39 => 600,
40 => 600, 41 => 600, 42 => 600, 43 => 600, 44 => 600, 45 => 600, 46 => 600, 47 => 600,
48 => 600, 49 => 600, 50 => 600, 51 => 600, 52 => 600, 53 => 600, 54 => 600, 55 => 600,
56 => 600, 57 => 600, 58 => 600, 59 => 600, 60 => 600, 61 => 600, 62 => 600, 63 => 600,
64 => 600, 65 => 600, 66 => 600, 67 => 600, 68 => 600, 69 => 600, 70 => 600, 71 => 600,
72 => 600, 73 => 600, 74 => 600, 75 => 600, 76 => 600, 77 => 600, 78 => 600, 79 => 600,
80 => 600, 81 => 600, 82 => 600, 83 => 600, 84 => 600, 85 => 600, 86 => 600, 87 => 600,
88 => 600, 89 => 600, 90 => 600, 91 => 600, 92 => 600, 93 => 600, 94 => 600, 95 => 600,
96 => 600, 97 => 600, 98 => 600, 99 => 600, 100 => 600, 101 => 600, 102 => 600, 103 => 600,
104 => 600, 105 => 600, 106 => 600, 107 => 600, 108 => 600, 109 => 600, 110 => 600, 111 => 600,
112 => 600, 113 => 600, 114 => 600, 115 => 600, 116 => 600, 117 => 600, 118 => 600, 119 => 600,
120 => 600, 121 => 600, 122 => 600, 123 => 600, 124 => 600, 125 => 600, 126 => 600, 127 => 600,
128 => 600, 129 => 600, 130 => 600, 131 => 600, 132 => 600, 133 => 600, 134 => 600, 135 => 600,
136 => 600, 137 => 600, 138 => 600, 139 => 600, 140 => 600, 141 => 600, 142 => 600, 143 => 600,
144 => 600, 145 => 600, 146 => 600, 147 => 600, 148 => 600, 149 => 600, 150 => 600, 151 => 600,
152 => 600, 153 => 600, 154 => 600, 155 => 600, 156 => 600, 157 => 600, 158 => 600, 159 => 600,
160 => 600, 161 => 600, 162 => 600, 163 => 600, 164 => 600, 165 => 600, 166 => 600, 167 => 600,
168 => 600, 169 => 600, 170 => 600, 171 => 600, 172 => 600, 173 => 600, 174 => 600, 175 => 600,
176 => 600, 177 => 600, 178 => 600, 179 => 600, 180 => 600, 181 => 600, 182 => 600, 183 => 600,
184 => 600, 185 => 600, 186 => 600, 187 => 600, 188 => 600, 189 => 600, 190 => 600, 191 => 600,
192 => 600, 193 => 600, 194 => 600, 195 => 600, 196 => 600, 197 => 600, 198 => 600, 199 => 600,
200 => 600, 201 => 600, 202 => 600, 203 => 600, 204 => 600, 205 => 600, 206 => 600, 207 => 600,
208 => 600, 209 => 600, 210 => 600, 211 => 600, 212 => 600, 213 => 600, 214 => 600, 215 => 600,
216 => 600, 217 => 600, 218 => 600, 219 => 600, 220 => 600, 221 => 600, 222 => 600, 223 => 600,
224 => 600, 225 => 600, 226 => 600, 227 => 600, 228 => 600, 229 => 600, 230 => 600, 231 => 600,
232 => 600, 233 => 600, 234 => 600, 235 => 600, 236 => 600, 237 => 600, 238 => 600, 239 => 600,
240 => 600, 241 => 600, 242 => 600, 243 => 600, 244 => 600, 245 => 600, 246 => 600, 247 => 600,
248 => 600, 249 => 600, 250 => 600, 251 => 600, 252 => 600, 253 => 600, 254 => 600, 255 => 600,
) ;
PK JvKlMN
FontMetrics/times.fmnu W+A 250, 1 => 250, 2 => 250, 3 => 250, 4 => 250, 5 => 250, 6 => 250, 7 => 250,
8 => 250, 9 => 250, 10 => 250, 11 => 250, 12 => 250, 13 => 250, 14 => 250, 15 => 250,
16 => 250, 17 => 250, 18 => 250, 19 => 250, 20 => 250, 21 => 250, 22 => 250, 23 => 250,
24 => 250, 25 => 250, 26 => 250, 27 => 250, 28 => 250, 29 => 250, 30 => 250, 31 => 250,
32 => 250, 33 => 333, 34 => 408, 35 => 500, 36 => 500, 37 => 833, 38 => 778, 39 => 180,
40 => 333, 41 => 333, 42 => 500, 43 => 564, 44 => 250, 45 => 333, 46 => 250, 47 => 278,
48 => 500, 49 => 500, 50 => 500, 51 => 500, 52 => 500, 53 => 500, 54 => 500, 55 => 500,
56 => 500, 57 => 500, 58 => 278, 59 => 278, 60 => 564, 61 => 564, 62 => 564, 63 => 444,
64 => 921, 65 => 722, 66 => 667, 67 => 667, 68 => 722, 69 => 611, 70 => 556, 71 => 722,
72 => 722, 73 => 333, 74 => 389, 75 => 722, 76 => 611, 77 => 889, 78 => 722, 79 => 722,
80 => 556, 81 => 722, 82 => 667, 83 => 556, 84 => 611, 85 => 722, 86 => 722, 87 => 944,
88 => 722, 89 => 722, 90 => 611, 91 => 333, 92 => 278, 93 => 333, 94 => 469, 95 => 500,
96 => 333, 97 => 444, 98 => 500, 99 => 444, 100 => 500, 101 => 444, 102 => 333, 103 => 500,
104 => 500, 105 => 278, 106 => 278, 107 => 500, 108 => 278, 109 => 778, 110 => 500, 111 => 500,
112 => 500, 113 => 500, 114 => 333, 115 => 389, 116 => 278, 117 => 500, 118 => 500, 119 => 722,
120 => 500, 121 => 500, 122 => 444, 123 => 480, 124 => 200, 125 => 480, 126 => 541, 127 => 350,
128 => 500, 129 => 350, 130 => 333, 131 => 500, 132 => 444, 133 => 1000, 134 => 500, 135 => 500,
136 => 333, 137 => 1000, 138 => 556, 139 => 333, 140 => 889, 141 => 350, 142 => 611, 143 => 350,
144 => 350, 145 => 333, 146 => 333, 147 => 444, 148 => 444, 149 => 350, 150 => 500, 151 => 1000,
152 => 333, 153 => 980, 154 => 389, 155 => 333, 156 => 722, 157 => 350, 158 => 444, 159 => 722,
160 => 250, 161 => 333, 162 => 500, 163 => 500, 164 => 500, 165 => 500, 166 => 200, 167 => 500,
168 => 333, 169 => 760, 170 => 276, 171 => 500, 172 => 564, 173 => 333, 174 => 760, 175 => 333,
176 => 400, 177 => 564, 178 => 300, 179 => 300, 180 => 333, 181 => 500, 182 => 453, 183 => 250,
184 => 333, 185 => 300, 186 => 310, 187 => 500, 188 => 750, 189 => 750, 190 => 750, 191 => 444,
192 => 722, 193 => 722, 194 => 722, 195 => 722, 196 => 722, 197 => 722, 198 => 889, 199 => 667,
200 => 611, 201 => 611, 202 => 611, 203 => 611, 204 => 333, 205 => 333, 206 => 333, 207 => 333,
208 => 722, 209 => 722, 210 => 722, 211 => 722, 212 => 722, 213 => 722, 214 => 722, 215 => 564,
216 => 722, 217 => 722, 218 => 722, 219 => 722, 220 => 722, 221 => 722, 222 => 556, 223 => 500,
224 => 444, 225 => 444, 226 => 444, 227 => 444, 228 => 444, 229 => 444, 230 => 667, 231 => 444,
232 => 444, 233 => 444, 234 => 444, 235 => 444, 236 => 278, 237 => 278, 238 => 278, 239 => 278,
240 => 500, 241 => 500, 242 => 500, 243 => 500, 244 => 500, 245 => 500, 246 => 500, 247 => 564,
248 => 500, 249 => 500, 250 => 500, 251 => 500, 252 => 500, 253 => 500, 254 => 500, 255 => 500,
) ;
PK JvK˼ Maps/unicode-to-ansi.mapnu W+A '"',
0x0085 => '...',
0x0092 => '"',
0x0094 => '"',
0x0096 => '-',
// End Polish
0x00A0 => ' ', // Non-breakable space
0x00AB => '"', // Left pointing double angle quotation mark
0x00AD => '', // Break Opportunity After: generally provide a line break opportunity after the character
0x00C6 => 'AE', // AE with ligature (Æ)
0x00E6 => 'ae', // ae with ligature (æ)
0x1680 => ' ', // OGHAM space mark
0x0152 => 'OE', // OE with ligature (Œ)
0x0153 => 'oe', // oe with ligature (œ)
0x1D6B => 'ue', // ue with ligature
0x2000 => ' ', // EN quad
0x2001 => ' ', // EM quad
0x2002 => ' ', // EN space
0x2003 => ' ', // EM space
0x2004 => ' ', // 3-per-EM space
0x2005 => ' ', // 4-per-EM space
0x2006 => ' ', // 6-per-EM space
0x2007 => ' ', // Figure space
0x2008 => ' ' , // Punctuation space
0x2009 => ' ', // Thin s1pace
0x200A => ' ', // Hair space
0x200B => ' ', // Zero-width space
0x200C => ' ', // Zero-width non-joiner
0x200D => '', // Zero-width joiner
0x2010 => '-', // Narrow hyphen
0x2011 => '-', // Non-breaking hyphen
0x2012 => '-', // Figure dash (has the same width as digits)
0x2013 => '-', // EN dash (used to indicate range of values)
0x2014 => ' - ', // EM dash (used to make a break in a flow of sentences)
0x2015 => '- ', // Horizontal bar, used to introduce quoted text
0x2018 => "'", // German right single quote
0x2019 => "'", // Secondary level quotation
0x201A => "'", // German left single quote
0x201B => "'", // Reversed quote
0x201C => '"', // Left double quotation mark
0x201D => '"', // Double quote-apostrophe
0x201E => '"', // Lower double quote-apostrophe
0x2026 => '...', // Ellipsis
0x2028 => "\n", // Line separator
0x2029 => "\n", // Paragraph separator
0x202F => ' ', // Narrow non-break space
0x2039 => "'", // Single left pointing angle quotation mark
0x203A => "'", // Single right pointing angle quotation mark
0x2053 => '~', // Large tilde
0x205F => ' ', // Medium mathematical space
0x2060 => '', // Word joiner
0x207B => '-', // Superscript minus
0x208B => '-', // Subscript minus
0x2160 => 'I', // Roman numeral : I
0x2161 => 'II', // Roman numeral : II
0x2162 => 'III', // Roman numeral : III
0x2163 => 'IV', // Roman numeral : IV
0x2164 => 'V', // Roman numeral : V
0x2165 => 'VI', // Roman numeral : VI
0x2166 => 'VII', // Roman numeral : VII
0x2167 => 'VIII', // Roman numeral : VIII
0x2168 => 'IX', // Roman numeral : IX
0x2169 => 'X', // Roman numeral : X
0x216A => 'XI', // Roman numeral : XI
0x216B => 'XII', // Roman numeral : XII
0x216C => 'L', // Roman numeral : L
0x216D => 'C', // Roman numeral : C
0x216E => 'D', // Roman numeral : D
0x216F => 'M', // Roman numeral : M
0x2170 => 'i', // Roman numeral : i
0x2171 => 'ii', // Roman numeral : ii
0x2172 => 'iii', // Roman numeral : iii
0x2173 => 'iv', // Roman numeral : iv
0x2174 => 'v', // Roman numeral : v
0x2175 => 'vi', // Roman numeral : vi
0x2176 => 'vii', // Roman numeral : vii
0x2177 => 'viii', // Roman numeral : viii
0x2178 => 'ix', // Roman numeral : ix
0x2179 => 'x', // Roman numeral : x
0x217A => 'xi', // Roman numeral : xi
0x217B => 'xii', // Roman numeral : xii
0x217C => 'l', // Roman numeral : l
0x217D => 'c', // Roman numeral : c
0x217E => 'd', // Roman numeral : d
0x217F => 'm', // Roman numeral : m
0x2212 => '-', // Minus sign (arithmetic operator)
0x2758 => '|', // Light vertical bar
0x2759 => '|', // Medium vertical bar
0x2E3A => '-', // Two-EM dash
0x2E3B => '-', // Three-EM dash
0x3000 => ' ', // Ideographic space
0x301D => '"', // Reversed double prime quotation mark
0x301E => '"', // Double prime quotation map,
0x301F => '"', // Low double prime quotation mark
0xA728 => 'TZ', // TZ with ligature
0xA729 => 'tz', // tz with ligature
0xA732 => 'AA', // AA with ligature
0xA733 => 'aa', // aa with ligature
0xA734 => 'AO', // AO with ligature
0xA735 => 'ao', // ao with ligature
0xA736 => 'AU', // AU with ligature
0xA737 => 'au', // au with ligature
0xA738 => 'AV', // AV with ligature
0xA739 => 'av', // av with ligature
0xA73A => 'AV', // AV with ligature and bar
0xA73B => 'av', // av with ligature and bar
0xA73C => 'AY', // AY with ligature
0xA73D => 'ay', // ay with ligature
0xA74E => 'OO', // OO with ligature
0xA74F => 'oo', // oo with ligature
0xA760 => 'VY', // VY with ligature
0xA761 => 'vy', // vy with ligature
0xFB00 => 'ff', // ff with ligature
0xFB01 => 'fi', // fi with ligature
0xFB02 => 'fl', // fl with ligature
0xFB03 => 'ffi', // ffi with ligature
0xFB04 => 'ffl', // ffl with ligature
0xFB05 => 'ft', // ft with ligature
0xFB06 => 'st', // st with ligature
0xFF08 => '(',
0xFF09 => ')',
0xFE31 => '|', // Vertical em dash
0xFE32 => '|', // Vertical en dash
0xFE58 => '-', // Small em dash
0xFE63 => '-', // Small ASCII hyphen
0xFF02 => '"', // Full width quotation mark
0xFF07 => "'", // Full width apostrophe
0xFF0D => '-', // Full-width hyphen variant of ascii hyphen
0xFEFF => ' ', // Zero-width non-breaking space
) ;
PK JvKF*O Maps/adobe-charsets.mapnu W+A array ( 0101, 0101, 0101, 0101 ),
'AE' => array ( 0341, 0256, 0306, 0306 ),
'Aacute' => array ( 0, 0347, 0301, 0301 ),
'Acircumflex' => array ( 0, 0345, 0302, 0302 ),
'Adieresis' => array ( 0, 0200, 0304, 0304 ),
'Agrave' => array ( 0, 0313, 0300, 0300 ),
'Aring' => array ( 0, 0201, 0305, 0305 ),
'Atilde' => array ( 0, 0314, 0303, 0303 ),
'B' => array ( 0102, 0102, 0102, 0102 ),
'C' => array ( 0103, 0103, 0103, 0103 ),
'Ccedilla' => array ( 0, 0202, 0307, 0307 ),
'D' => array ( 0104, 0104, 0104, 0104 ),
'E' => array ( 0105, 0105, 0105, 0105 ),
'Eacute' => array ( 0, 0203, 0311, 0311 ),
'Ecircumflex' => array ( 0, 0346, 0312, 0312 ),
'Edieresis' => array ( 0, 0350, 0313, 0313 ),
'Egrave' => array ( 0, 0351, 0310, 0310 ),
'Eth' => array ( 0, 0, 0320, 0320 ),
'Euro' => array ( 0, 0, 0200, 0240 ),
'F' => array ( 0106, 0106, 0106, 0106 ),
'G' => array ( 0107, 0107, 0107, 0107 ),
'H' => array ( 0110, 0110, 0110, 0110 ),
'I' => array ( 0111, 0111, 0111, 0111 ),
'Iacute' => array ( 0, 0352, 0315, 0315 ),
'Icircumflex' => array ( 0, 0353, 0316, 0316 ),
'Idieresis' => array ( 0, 0354, 0317, 0317 ),
'Igrave' => array ( 0, 0355, 0314, 0314 ),
'J' => array ( 0112, 0112, 0112, 0112 ),
'K' => array ( 0113, 0113, 0113, 0113 ),
'L' => array ( 0114, 0114, 0114, 0114 ),
'Lslash' => array ( 0x0141, 0x0141, 0x0141, 0x0141 ),
'M' => array ( 0115, 0115, 0115, 0115 ),
'N' => array ( 0116, 0116, 0116, 0116 ),
'Ntilde' => array ( 0, 0204, 0321, 0321 ),
'O' => array ( 0117, 0117, 0117, 0117 ),
'OE' => array ( 0352, 0316, 0214, 0226 ),
'Oacute' => array ( 0, 0356, 0323, 0323 ),
'Ocircumflex' => array ( 0, 0357, 0324, 0324 ),
'Odieresis' => array ( 0, 0205, 0326, 0326 ),
'Ograve' => array ( 0, 0361, 0322, 0322 ),
'Oslash' => array ( 0351, 0257, 0330, 0330 ),
'Otilde' => array ( 0, 0315, 0325, 0325 ),
'P' => array ( 0120, 0120, 0120, 0120 ),
'Q' => array ( 0121, 0121, 0121, 0121 ),
'R' => array ( 0122, 0122, 0122, 0122 ),
'S' => array ( 0123, 0123, 0123, 0123 ),
'Scaron' => array ( 0, 0, 0212, 0227 ),
'T' => array ( 0124, 0124, 0124, 0124 ),
'Thorn' => array ( 0, 0, 0336, 0336 ),
'U' => array ( 0125, 0125, 0125, 0125 ),
'Uacute' => array ( 0, 0362, 0332, 0332 ),
'Ucircumflex' => array ( 0, 0363, 0333, 0333 ),
'Udieresis' => array ( 0, 0206, 0334, 0334 ),
'Ugrave' => array ( 0, 0364, 0331, 0331 ),
'V' => array ( 0126, 0126, 0126, 0126 ),
'W' => array ( 0127, 0127, 0127, 0127 ),
'X' => array ( 0130, 0130, 0130, 0130 ),
'Y' => array ( 0131, 0131, 0131, 0131 ),
'Yacute' => array ( 0, 0, 0335, 0335 ),
'Ydieresis' => array ( 0, 0331, 0237, 0230 ),
'Z' => array ( 0132, 0132, 0132, 0132 ),
'Zcaron' => array ( 0, 0, 0216, 0231 ),
'a' => array ( 0141, 0141, 0141, 0141 ),
'aacute' => array ( 0, 0207, 0341, 0341 ),
'acircumflex' => array ( 0, 0211, 0342, 0342 ),
'acute' => array ( 0302, 0253, 0264, 0264 ),
'adieresis' => array ( 0, 0212, 0344, 0344 ),
'ae' => array ( 0361, 0276, 0346, 0346 ),
'agrave' => array ( 0, 0210, 0340, 0340 ),
'ampersand' => array ( 0046, 0046, 0046, 0046 ),
'aring' => array ( 0, 0214, 0345, 0345 ),
'asciicircum' => array ( 0136, 0136, 0136, 0136 ),
'asciitilde' => array ( 0176, 0176, 0176, 0176 ),
'asterisk' => array ( 0052, 0052, 0052, 0052 ),
'at' => array ( 0100, 0100, 0100, 0100 ),
'atilde' => array ( 0, 0213, 0343, 0343 ),
'b' => array ( 0142, 0142, 0142, 0142 ),
'backslash' => array ( 0134, 0134, 0134, 0134 ),
'bar' => array ( 0174, 0174, 0174, 0174 ),
'braceleft' => array ( 0173, 0173, 0173, 0173 ),
'braceright' => array ( 0175, 0175, 0175, 0175 ),
'bracketleft' => array ( 0133, 0133, 0133, 0133 ),
'bracketright' => array ( 0135, 0135, 0135, 0135 ),
'breve' => array ( 0306, 0371, 0, 0030 ),
'brokenbar' => array ( 0, 0, 0246, 0246 ),
'bullet' => array ( 0267, 0245, 0225, 0200 ),
'c' => array ( 0143, 0143, 0143, 0143 ),
'caron' => array ( 0317, 0377, 0, 0031 ),
'ccedilla' => array ( 0, 0215, 0347, 0347 ),
'cedilla' => array ( 0313, 0374, 0270, 0270 ),
'cent' => array ( 0242, 0242, 0242, 0242 ),
'circumflex' => array ( 0303, 0366, 0210, 0032 ),
'colon' => array ( 0072, 0072, 0072, 0072 ),
'comma' => array ( 0054, 0054, 0054, 0054 ),
'copyright' => array ( 0, 0251, 0251, 0251 ),
'currency' => array ( 0250, 0333, 0244, 0244 ),
'd' => array ( 0144, 0144, 0144, 0144 ),
'dagger' => array ( 0262, 0240, 0206, 0201 ),
'daggerdbl' => array ( 0263, 0340, 0207, 0202 ),
'degree' => array ( 0, 0241, 0260, 0260 ),
'dieresis' => array ( 0310, 0254, 0250, 0250 ),
'divide' => array ( 0, 0326, 0367, 0367 ),
'dollar' => array ( 0044, 0044, 0044, 0044 ),
'dotaccent' => array ( 0307, 0372, 0, 0033 ),
'dotlessi' => array ( 0365, 0365, 0x131, 0232 ),
'e' => array ( 0145, 0145, 0145, 0145 ),
'eacute' => array ( 0, 0216, 0351, 0351 ),
'ecircumflex' => array ( 0, 0220, 0352, 0352 ),
'edieresis' => array ( 0, 0221, 0353, 0353 ),
'egrave' => array ( 0, 0217, 0350, 0350 ),
'eight' => array ( 0070, 0070, 0070, 0070 ),
'elipsis' => array ( 0x2026, 0x2026, 0x2026, 0x2026 ),
'ellipsis' => array ( 0x2026, 0x2026, 0x2026, 0x2026 ),
'emdash' => array ( 0x2D, 0x2D, 0x2D, 0x2D ),
'endash' => array ( 0x2D, 0x2D, 0x2D, 0x2D ),
'equal' => array ( 0075, 0075, 0075, 0075 ),
'eth' => array ( 0, 0, 0360, 0360 ),
'exclam' => array ( 0041, 0041, 0041, 0041 ),
'exclamdown' => array ( 0241, 0301, 0241, 0241 ),
'f' => array ( 0146, 0146, 0146, 0146 ),
'fi' => array ( 0xFB01, 0xFB01, 0xFB01, 0xFB01 ),
'five' => array ( 0065, 0065, 0065, 0065 ),
'ff' => array ( 0xFB00, 0xFB00, 0xFB00, 0xFB00 ),
'fl' => array ( 0xFB02, 0xFB02, 0xFB02, 0xFB02 ),
'ffi' => array ( 0xFB03, 0xFB03, 0xFB03, 0xFB03 ),
'ffl' => array ( 0xFB04, 0xFB04, 0xFB04, 0xFB04 ),
'florin' => array ( 0246, 0304, 0203, 0206 ),
'four' => array ( 0064, 0064, 0064, 0064 ),
'fraction' => array ( 0244, 0332, 0, 0207 ),
'g' => array ( 0147, 0147, 0147, 0147 ),
'germandbls' => array ( 0373, 0247, 0337, 0337 ),
'grave' => array ( 0301, 0140, 0140, 0140 ),
'greater' => array ( 0076, 0076, 0076, 0076 ),
'guillemotleft' => array ( 0253, 0307, 0253, 0253 ),
'guillemotright' => array ( 0273, 0310, 0273, 0273 ),
'guilsinglleft' => array ( 0254, 0334, 0213, 0210 ),
'guilsinglright' => array ( 0255, 0335, 0233, 0211 ),
'h' => array ( 0150, 0150, 0150, 0150 ),
'hungarumlaut' => array ( 0315, 0375, 0, 0034 ),
'hyphen' => array ( 0x2D, 0x2D, 0x2D, 0x2D ),
'i' => array ( 0151, 0151, 0151, 0151 ),
'iacute' => array ( 0, 0222, 0355, 0355 ),
'icircumflex' => array ( 0, 0224, 0356, 0356 ),
'idieresis' => array ( 0, 0225, 0357, 0357 ),
'igrave' => array ( 0, 0223, 0354, 0354 ),
'j' => array ( 0152, 0152, 0152, 0152 ),
'k' => array ( 0153, 0153, 0153, 0153 ),
'l' => array ( 0154, 0154, 0154, 0154 ),
'less' => array ( 0074, 0074, 0074, 0074 ),
'logicalnot' => array ( 0, 0302, 0254, 0254 ),
'lslash' => array ( 0x0142, 0x0142, 0x0142, 0x0142 ),
'm' => array ( 0155, 0155, 0155, 0155 ),
'macron' => array ( 0305, 0370, 0257, 0257 ),
'minus' => array ( 0x2D, 0x2D, 0x2D, 0x2D ),
'mu' => array ( 0, 0265, 0265, 0265 ),
'multiply' => array ( 0, 0, 0327, 0327 ),
'n' => array ( 0156, 0156, 0156, 0156 ),
'nine' => array ( 0071, 0071, 0071, 0071 ),
'ntilde' => array ( 0, 0226, 0361, 0361 ),
'numbersign' => array ( 0043, 0043, 0043, 0043 ),
'o' => array ( 0157, 0157, 0157, 0157 ),
'oacute' => array ( 0, 0227, 0363, 0363 ),
'ocircumflex' => array ( 0, 0231, 0364, 0364 ),
'odieresis' => array ( 0, 0232, 0366, 0366 ),
'oe' => array ( 0372, 0317, 0234, 0234 ),
'ogonek' => array ( 0x2DB, 0x2DB, 0x2DB, 0x2DB ),
'ograve' => array ( 0, 0230, 0362, 0362 ),
'one' => array ( 0061, 0061, 0061, 0061 ),
'onehalf' => array ( 0, 0, 0275, 0275 ),
'onequarter' => array ( 0, 0, 0274, 0274 ),
'ordfeminine' => array ( 0343, 0273, 0252, 0252 ),
'ordmasculine' => array ( 0353, 0274, 0272, 0272 ),
'oslash' => array ( 0371, 0277, 0370, 0370 ),
'otilde' => array ( 0, 0233, 0365, 0365 ),
'p' => array ( 0160, 0160, 0160, 0160 ),
'paragraph' => array ( 0266, 0246, 0266, 0266 ),
'parenleft' => array ( 0050, 0050, 0050, 0050 ),
'parenright' => array ( 0051, 0051, 0051, 0051 ),
'percent' => array ( 0045, 0045, 0045, 0045 ),
'period' => array ( 0056, 0056, 0056, 0056 ),
'periodcentered' => array ( 0264, 0341, 0267, 0267 ),
'perthousand' => array ( 0275, 0344, 0211, 0213 ),
'plus' => array ( 0053, 0053, 0053, 0053 ),
'plusminus' => array ( 0, 0261, 0261, 0261 ),
'q' => array ( 0161, 0161, 0161, 0161 ),
'question' => array ( 0077, 0077, 0077, 0077 ),
'questiondown' => array ( 0277, 0300, 0277, 0277 ),
'quotedbl' => array ( 0x22, 0x22, 0x22, 0x22 ),
'quotedblbase' => array ( 0x22, 0x22, 0x22, 0x22 ),
'quotedblleft' => array ( 0x22, 0x22, 0x22, 0x22 ),
'quotedblright' => array ( 0x22, 0x22, 0x22, 0x22 ),
'quoteleft' => array ( 0x27, 0x27, 0x27, 0x27 ),
'quoteright' => array ( 0x22, 0x22, 0x22, 0x22 ),
'quotesinglbase' => array ( 0x22, 0x22, 0x22, 0x22 ),
'quotesingle' => array ( 0x22, 0x22, 0x22, 0x22 ),
'r' => array ( 0162, 0162, 0162, 0162 ),
'registered' => array ( 0, 0250, 0256, 0256 ),
'ring' => array ( 0312, 0373, 0xB0, 0036 ),
's' => array ( 0163, 0163, 0163, 0163 ),
'scaron' => array ( 0, 0, 0232, 0235 ),
'section' => array ( 0247, 0244, 0247, 0247 ),
'semicolon' => array ( 0073, 0073, 0073, 0073 ),
'seven' => array ( 0067, 0067, 0067, 0067 ),
'six' => array ( 0066, 0066, 0066, 0066 ),
'slash' => array ( 0057, 0057, 0057, 0057 ),
'space' => array ( 0040, 0040, 0040, 0040 ),
'sterling' => array ( 0243, 0243, 0243, 0243 ),
't' => array ( 0164, 0164, 0164, 0164 ),
'thorn' => array ( 0, 0, 0376, 0376 ),
'three' => array ( 0063, 0063, 0063, 0063 ),
'threequarters' => array ( 0, 0, 0276, 0276 ),
'tilde' => array ( 0304, 0367, 0230, 0037 ),
'trademark' => array ( 0, 0252, 0231, 0222 ),
'two' => array ( 0062, 0062, 0062, 0062 ),
'u' => array ( 0165, 0165, 0165, 0165 ),
'uacute' => array ( 0, 0234, 0372, 0372 ),
'ucircumflex' => array ( 0, 0236, 0373, 0373 ),
'udieresis' => array ( 0, 0237, 0374, 0374 ),
'ugrave' => array ( 0, 0235, 0371, 0371 ),
'underscore' => array ( 0137, 0137, 0137, 0137 ),
'v' => array ( 0166, 0166, 0166, 0166 ),
'w' => array ( 0167, 0167, 0167, 0167 ),
'x' => array ( 0170, 0170, 0170, 0170 ),
'y' => array ( 0171, 0171, 0171, 0171 ),
'yacute' => array ( 0, 0, 0375, 0375 ),
'ydieresis' => array ( 0, 0330, 0377, 0377 ),
'yen' => array ( 0245, 0264, 0245, 0245 ),
'z' => array ( 0172, 0172, 0172, 0172 ),
'zcaron' => array ( 0, 0, 0236, 0236 ),
'zero' => array ( 0060, 0060, 0060, 0060 ),
// Additions which are not described in the PDF specifications - much more foreign characters are available !
// (see https://mupdf.com/docs/browse/source/pdf/pdf-glyphlist.h.html)
// The following also gives some glyph names :
// http://www.tipometar.org/pojmovnik/Hint/img/Using%20Fontographer.pdf
// This table is currently far from being complete
'Abreve' => array ( 0x0102, 0x0102, 0x0102, 0x0102 ),
'abreve' => array ( 0x0103, 0x0103, 0x0103, 0x0103 ),
'Abreveacute' => array ( 0x1EAE, 0x1EAE, 0x1EAE, 0x1EAE ),
'abreveacute' => array ( 0x1EAF, 0x1EAF, 0x1EAF, 0x1EAF ),
'Abrevedotbelow' => array ( 0x1EB6, 0x1EB6, 0x1EB6, 0x1EB6 ),
'abrevedotbelow' => array ( 0x1EB7, 0x1EB7, 0x1EB7, 0x1EB7 ),
'Abrevegrave' => array ( 0x1EB0, 0x1EB0, 0x1EB0, 0x1EB0 ),
'abrevegrave' => array ( 0x1EB1, 0x1EB1, 0x1EB1, 0x1EB1 ),
'Abrevehookabove' => array ( 0x1EB2, 0x1EB2, 0x1EB2, 0x1EB2 ),
'abrevehookabove' => array ( 0x1EB3, 0x1EB3, 0x1EB3, 0x1EB3 ),
'Abrevetilde' => array ( 0x1EB4, 0x1EB4, 0x1EB4, 0x1EB4 ),
'abrevetilde' => array ( 0x1EB5, 0x1EB5, 0x1EB5, 0x1EB5 ),
'Acaron' => array ( 0x01CD, 0x01CD, 0x01CD, 0x01CD ),
'acaron' => array ( 0x01CE, 0x01CE, 0x01CE, 0x01CE ),
'Acircumflexacute' => array ( 0x1EA4, 0x1EA4, 0x1EA4, 0x1EA4 ),
'acircumflexacute' => array ( 0x1EA5, 0x1EA5, 0x1EA5, 0x1EA5 ),
'Acircumflexdotbelow' => array ( 0x1EAC, 0x1EAC, 0x1EAC, 0x1EAC ),
'acircumflexdotbelow' => array ( 0x1EAD, 0x1EAD, 0x1EAD, 0x1EAD ),
'Acircumflexgrave' => array ( 0x1EA6, 0x1EA6, 0x1EA6, 0x1EA6 ),
'acircumflexgrave' => array ( 0x1EA7, 0x1EA7, 0x1EA7, 0x1EA7 ),
'Acircumflexhookabove' => array ( 0x1EA8, 0x1EA8, 0x1EA8, 0x1EA8 ),
'acircumflexhookabove' => array ( 0x1EA9, 0x1EA9, 0x1EA9, 0x1EA9 ),
'Acircumflextilde' => array ( 0x1EAA, 0x1EAA, 0x1EAA, 0x1EAA ),
'acircumflextilde' => array ( 0x1EAB, 0x1EAB, 0x1EAB, 0x1EAB ),
'acutecomb' => array ( 0x0301, 0x0301, 0x0301, 0x0301 ),
'Adot' => array ( 0x0226, 0x0226, 0x0226, 0x0226 ),
'adot' => array ( 0x0227, 0x0227, 0x0227, 0x0227 ),
'Adotbelow' => array ( 0x1EA0, 0x1EA0, 0x1EA0, 0x1EA0 ),
'adotbelow' => array ( 0x1EA1, 0x1EA1, 0x1EA1, 0x1EA1 ),
'AEacute' => array ( 0x01FC, 0x01FC, 0x01FC, 0x01FC ),
'aeacute' => array ( 0x01FD, 0x01FD, 0x01FD, 0x01FD ),
'Adieresis' => array ( 0x00C4, 0x00C4, 0x00C4, 0x00C4 ),
'adieresis' => array ( 0x00E4, 0x00E4, 0x00E4, 0x00E4 ),
'Ahookabove' => array ( 0x1EA2, 0x1EA2, 0x1EA2, 0x1EA2 ),
'ahookabove' => array ( 0x1EA3, 0x1EA3, 0x1EA3, 0x1EA3 ),
'Amacron' => array ( 0x0100, 0x0100, 0x0100, 0x0100 ),
'amacron' => array ( 0x0101, 0x0101, 0x0101, 0x0101 ),
'Aogonek' => array ( 0x0104, 0x0104, 0x0104, 0x0104 ),
'aogonek' => array ( 0x0105, 0x0105, 0x0105, 0x0105 ),
'Aring' => array ( 0x00C5, 0x00C5, 0x00C5, 0x00C5 ),
'aring' => array ( 0x00E5, 0x00E5, 0x00E5, 0x00E5 ),
'Aringacute' => array ( 0x01FA, 0x01FA, 0x01FA, 0x01FA ),
'aringacute' => array ( 0x01FB, 0x01FB, 0x01FB, 0x01FB ),
'Atilde' => array ( 0x00C3, 0x00C3, 0x00C3, 0x00C3 ),
'atilde' => array ( 0x00E3, 0x00E3, 0x00E3, 0x00E3 ),
'Cacute' => array ( 0x0106, 0x0106, 0x0106, 0x0106 ),
'cacute' => array ( 0x0107, 0x0107, 0x0107, 0x0107 ),
'Ccaron' => array ( 0x010C, 0x010C, 0x010C, 0x010C ),
'ccaron' => array ( 0x010D, 0x010D, 0x010D, 0x010D ),
'Ccircumflex' => array ( 0x0108, 0x0108, 0x0108, 0x0108 ),
'ccircumflex' => array ( 0x0109, 0x0109, 0x0109, 0x0109 ),
'Cdot' => array ( 0x010A, 0x010A, 0x010A, 0x010A ),
'cdot' => array ( 0x010B, 0x010B, 0x010B, 0x010B ),
'Cdotaccent' => array ( 0x010A, 0x010A, 0x010A, 0x010A ),
'cdotaccent' => array ( 0x010B, 0x010B, 0x010B, 0x010B ),
'Dcaron' => array ( 0x010E, 0x010E, 0x010E, 0x010E ),
'dcaron' => array ( 0x010F, 0x010F, 0x010F, 0x010F ),
'Dcedilla' => array ( 0x1E10, 0x1E10, 0x1E10, 0x1E10 ),
'dcedilla' => array ( 0x1E11, 0x1E11, 0x1E11, 0x1E11 ),
'Dcroat' => array ( 0x0110, 0x0110, 0x0110, 0x0110 ),
'dcroat' => array ( 0x0111, 0x0111, 0x0111, 0x0111 ),
'Dmacron' => array ( 0x0110, 0x0110, 0x0110, 0x0110 ),
'dmacron' => array ( 0x0111, 0x0111, 0x0111, 0x0111 ),
'dotbelowcomb' => array ( 0x0323, 0x0323, 0x0323, 0x0323 ),
'Dslash' => array ( 0x0110, 0x0110, 0x0110, 0x0110 ),
'dslash' => array ( 0x0111, 0x0111, 0x0111, 0x0111 ),
'Ebreve' => array ( 0x0114, 0x0114, 0x0114, 0x0114 ),
'ebreve' => array ( 0x0115, 0x0115, 0x0115, 0x0115 ),
'Ecaron' => array ( 0x011A, 0x011A, 0x011A, 0x011A ),
'ecaron' => array ( 0x011B, 0x011B, 0x011B, 0x011B ),
'Ecedilla' => array ( 0x0228, 0x0228, 0x0228, 0x0228 ),
'ecedilla' => array ( 0x0229, 0x0229, 0x0229, 0x0229 ),
'Ecircumflexacute' => array ( 0x1EBE, 0x1EBE, 0x1EBE, 0x1EBE ),
'ecircumflexacute' => array ( 0x1EBF, 0x1EBF, 0x1EBF, 0x1EBF ),
'Ecircumflexdotbelow' => array ( 0x1EC6, 0x1EC6, 0x1EC6, 0x1EC6 ),
'ecircumflexdotbelow' => array ( 0x1EC7, 0x1EC7, 0x1EC7, 0x1EC7 ),
'Ecircumflexgrave' => array ( 0x1EC0, 0x1EC0, 0x1EC0, 0x1EC0 ),
'ecircumflexgrave' => array ( 0x1EC1, 0x1EC1, 0x1EC1, 0x1EC1 ),
'Ecircumflexhookabove' => array ( 0x1EC2, 0x1EC2, 0x1EC2, 0x1EC2 ),
'ecircumflexhookabove' => array ( 0x1EC3, 0x1EC3, 0x1EC3, 0x1EC3 ),
'Ecircumflextilde' => array ( 0x1EC4, 0x1EC4, 0x1EC4, 0x1EC4 ),
'ecircumflextilde' => array ( 0x1EC5, 0x1EC5, 0x1EC5, 0x1EC5 ),
'Edieresis' => array ( 0x00CB, 0x00CB, 0x00CB, 0x00CB ),
'edieresis' => array ( 0x00EB, 0x00EB, 0x00EB, 0x00EB ),
'Edot' => array ( 0x0116, 0x0116, 0x0116, 0x0116 ),
'edot' => array ( 0x0117, 0x0117, 0x0117, 0x0117 ),
'Edotaccent' => array ( 0x0116, 0x0116, 0x0116, 0x0116 ),
'edotaccent' => array ( 0x0117, 0x0117, 0x0117, 0x0117 ),
'Edotbelow' => array ( 0x1EB8, 0x1EB8, 0x1EB8, 0x1EB8 ),
'edotbelow' => array ( 0x1EB9, 0x1EB9, 0x1EB9, 0x1EB9 ),
'Ehookabove' => array ( 0x1EBA, 0x1EBA, 0x1EBA, 0x1EBA ),
'ehookabove' => array ( 0x1EBB, 0x1EBB, 0x1EBB, 0x1EBB ),
'Emacron' => array ( 0x0112, 0x0112, 0x0112, 0x0112 ),
'emacron' => array ( 0x0113, 0x0113, 0x0113, 0x0113 ),
'Eng' => array ( 0x014A, 0x014A, 0x014A, 0x014A ),
'eng' => array ( 0x014B, 0x014B, 0x014B, 0x014B ),
'Eogonek' => array ( 0x0118, 0x0118, 0x0118, 0x0118 ),
'eogonek' => array ( 0x0119, 0x0119, 0x0119, 0x0119 ),
'Ering' => array ( 0x016E, 0x016E, 0x016E, 0x016E ),
'ering' => array ( 0x016F, 0x016F, 0x016F, 0x016F ),
'Etilde' => array ( 0x1EBC, 0x1EBC, 0x1EBC, 0x1EBC ),
'etilde' => array ( 0x1EBD, 0x1EBD, 0x1EBD, 0x1EBD ),
'Gacute' => array ( 0x01F4, 0x01F4, 0x01F4, 0x01F4 ),
'gacute' => array ( 0x01F5, 0x01F5, 0x01F5, 0x01F5 ),
'Gbreve' => array ( 0x011E, 0x011E, 0x011E, 0x011E ),
'gbreve' => array ( 0x011F, 0x011F, 0x011F, 0x011F ),
'Gcaron' => array ( 0x01E6, 0x01E6, 0x01E6, 0x01E6 ),
'gcaron' => array ( 0x01E7, 0x01E7, 0x01E7, 0x01E7 ),
'Gcedilla' => array ( 0x0122, 0x0122, 0x0122, 0x0122 ),
'gcedilla' => array ( 0x0123, 0x0123, 0x0123, 0x0123 ),
'Gcommaaccent' => array ( 0x0122, 0x0122, 0x0122, 0x0122 ),
'gcommaaccent' => array ( 0x0123, 0x0123, 0x0123, 0x0123 ),
'Gcircumflex' => array ( 0x011C, 0x011C, 0x011C, 0x011C ),
'gcircumflex' => array ( 0x011D, 0x011D, 0x011D, 0x011D ),
'Gdot' => array ( 0x0120, 0x0120, 0x0120, 0x0120 ),
'gdot' => array ( 0x0121, 0x0121, 0x0121, 0x0121 ),
'Gdotaccent' => array ( 0x0120, 0x0120, 0x0120, 0x0120 ),
'gdotaccent' => array ( 0x0121, 0x0121, 0x0121, 0x0121 ),
'gravecomb' => array ( 0x0300, 0x0300, 0x0300, 0x0300 ),
'Hbar' => array ( 0x0126, 0x0126, 0x0126, 0x0126 ),
'hbar' => array ( 0x0127, 0x0127, 0x0127, 0x0127 ),
'Hcaron' => array ( 0x021E, 0x021E, 0x021E, 0x021E ),
'hcaron' => array ( 0x021F, 0x021F, 0x021F, 0x021F ),
'Hcedilla' => array ( 0x1E28, 0x1E28, 0x1E28, 0x1E28 ),
'hcedilla' => array ( 0x1E29, 0x1E29, 0x1E29, 0x1E29 ),
'Hcircumflex' => array ( 0x0124, 0x0124, 0x0124, 0x0124 ),
'hcircumflex' => array ( 0x0125, 0x0125, 0x0125, 0x0125 ),
'hookabovecomb' => array ( 0x0309, 0x0309, 0x0309, 0x0309 ),
'Ibreve' => array ( 0x012C, 0x012C, 0x012C, 0x012C ),
'ibreve' => array ( 0x012D, 0x012D, 0x012D, 0x012D ),
'Icaron' => array ( 0x01CF, 0x01CF, 0x01CF, 0x01CF ),
'icaron' => array ( 0x01D0, 0x01D0, 0x01D0, 0x01D0 ),
'Idieresis' => array ( 0x00CF, 0x00CF, 0x00CF, 0x00CF ),
'idieresis' => array ( 0x00EF, 0x00EF, 0x00EF, 0x00EF ),
'Idot' => array ( 0x00CD, 0x00CD, 0x00CD, 0x00CD ),
'idot' => array ( 0x00ED, 0x00ED, 0x00ED, 0x00ED ),
'Idotaccent' => array ( 0x00CD, 0x00CD, 0x00CD, 0x00CD ),
'idotaccent' => array ( 0x00ED, 0x00ED, 0x00ED, 0x00ED ),
'Idotbelow' => array ( 0x1ECA, 0x1ECA, 0x1ECA, 0x1ECA ),
'idotbelow' => array ( 0x1ECB, 0x1ECB, 0x1ECB, 0x1ECB ),
'Ihookabove' => array ( 0x1EC8, 0x1EC8, 0x1EC8, 0x1EC8 ),
'ihookabove' => array ( 0x1EC9, 0x1EC9, 0x1EC9, 0x1EC9 ),
'IJ' => array ( 0x0132, 0x0132, 0x0132, 0x0132 ),
'ij' => array ( 0x0133, 0x0133, 0x0133, 0x0133 ),
'Imacron' => array ( 0x012A, 0x012A, 0x012A, 0x012A ),
'imacron' => array ( 0x012B, 0x012B, 0x012B, 0x012B ),
'Iogonek' => array ( 0x012E, 0x012E, 0x012E, 0x012E ),
'iogonek' => array ( 0x012F, 0x012F, 0x012F, 0x012F ),
'Itilde' => array ( 0x0128, 0x0128, 0x0128, 0x0128 ),
'itilde' => array ( 0x0129, 0x0129, 0x0129, 0x0129 ),
'Jcaron' => array ( 0x01F0, 0x01F0, 0x01F0, 0x01F0 ),
'jcaron' => array ( 0x01EF, 0x01EF, 0x01EF, 0x01EF ),
'Jcircumflex' => array ( 0x0134, 0x0134, 0x0134, 0x0134 ),
'jcircumflex' => array ( 0x0135, 0x0135, 0x0135, 0x0135 ),
'Kacute' => array ( 0x1E30, 0x1E30, 0x1E30, 0x1E30 ),
'kacute' => array ( 0x1E31, 0x1E31, 0x1E31, 0x1E31 ),
'kcaron' => array ( 0x01E9, 0x01E9, 0x01E9, 0x01E9 ),
'Kcaron' => array ( 0x01E8, 0x01E8, 0x01E8, 0x01E8 ),
'Kcedilla' => array ( 0x0136, 0x0136, 0x0136, 0x0136 ),
'kcedilla' => array ( 0x0137, 0x0137, 0x0137, 0x0137 ),
'Kcommaaccent' => array ( 0x0136, 0x0136, 0x0136, 0x0136 ),
'kcommaaccent' => array ( 0x0137, 0x0137, 0x0137, 0x0137 ),
'kgreenlandic' => array ( 0x0138, 0x0138, 0x0138, 0x0138 ),
'Lacute' => array ( 0x0139, 0x0139, 0x0139, 0x0139 ),
'lacute' => array ( 0x013A, 0x013A, 0x013A, 0x013A ),
'lcaron' => array ( 0x013E, 0x013E, 0x013E, 0x013E ),
'Lcaron' => array ( 0x013D, 0x013D, 0x013D, 0x013D ),
'Lcedilla' => array ( 0x013B, 0x013B, 0x013B, 0x013B ),
'lcedilla' => array ( 0x013C, 0x013C, 0x013C, 0x013C ),
'Lcommaaccent' => array ( 0x013B, 0x013B, 0x013B, 0x013B ),
'lcommaaccent' => array ( 0x013C, 0x013C, 0x013C, 0x013C ),
'Ldot' => array ( 0x013F, 0x013F, 0x013F, 0x013F ),
'ldot' => array ( 0x0140, 0x0140, 0x0140, 0x0140 ),
'Macute' => array ( 0x1E3E, 0x1E3E, 0x1E3E, 0x1E3E ),
'macute' => array ( 0x1E3F, 0x1E3F, 0x1E3F, 0x1E3F ),
'nacute' => array ( 0x0144, 0x0144, 0x0144, 0x0144 ),
'Nacute' => array ( 0x0143, 0x0143, 0x0143, 0x0143 ),
'napostrophe' => array ( 0x0149, 0x0149, 0x0149, 0x0149 ),
'nbspace' => array ( 0x0020, 0x0020, 0x0020, 0x0020 ),
'Ncaron' => array ( 0x0147, 0x0147, 0x0147, 0x0147 ),
'ncaron' => array ( 0x0148, 0x0148, 0x0148, 0x0148 ),
'Ncedilla' => array ( 0x0145, 0x0145, 0x0145, 0x0145 ),
'ncedilla' => array ( 0x0146, 0x0146, 0x0146, 0x0146 ),
'Ncommaaccent' => array ( 0x0145, 0x0145, 0x0145, 0x0145 ),
'ncommaaccent' => array ( 0x0146, 0x0146, 0x0146, 0x0146 ),
'Ncircumflex' => array ( 0x1E4A, 0x1E4A, 0x1E4A, 0x1E4A ),
'ncircumflex' => array ( 0x1E4B, 0x1E4B, 0x1E4B, 0x1E4B ),
'Ntilde' => array ( 0x00D1, 0x00D1, 0x00D1, 0x00D1 ),
'ntilde' => array ( 0x00F1, 0x00F1, 0x00F1, 0x00F1 ),
'Obreve' => array ( 0x014E, 0x014E, 0x014E, 0x014E ),
'obreve' => array ( 0x014F, 0x014F, 0x014F, 0x014F ),
'Ocaron' => array ( 0x01D1, 0x01D1, 0x01D1, 0x01D1 ),
'ocaron' => array ( 0x01D2, 0x01D2, 0x01D2, 0x01D2 ),
'Ocedilla' => array ( 0x0156, 0x0156, 0x0156, 0x0156 ),
'ocedilla' => array ( 0x0157, 0x0157, 0x0157, 0x0157 ),
'Ocircumflexacute' => array ( 0x1ED0, 0x1ED0, 0x1ED0, 0x1ED0 ),
'ocircumflexacute' => array ( 0x1ED1, 0x1ED1, 0x1ED1, 0x1ED1 ),
'Ocircumflexdotbelow' => array ( 0x1ED8, 0x1ED8, 0x1ED8, 0x1ED8 ),
'ocircumflexdotbelow' => array ( 0x1ED9, 0x1ED9, 0x1ED9, 0x1ED9 ),
'Ocircumflexgrave' => array ( 0x1ED2, 0x1ED2, 0x1ED2, 0x1ED2 ),
'ocircumflexgrave' => array ( 0x1ED3, 0x1ED3, 0x1ED3, 0x1ED3 ),
'Ocircumflexhookabove' => array ( 0x1ED4, 0x1ED4, 0x1ED4, 0x1ED4 ),
'ocircumflexhookabove' => array ( 0x1ED5, 0x1ED5, 0x1ED5, 0x1ED5 ),
'Ocircumflextilde' => array ( 0x1ED6, 0x1ED6, 0x1ED6, 0x1ED6 ),
'ocircumflextilde' => array ( 0x1ED7, 0x1ED7, 0x1ED7, 0x1ED7 ),
'Odieresis' => array ( 0x00D6, 0x00D6, 0x00D6, 0x00D6 ),
'odieresis' => array ( 0x00F6, 0x00F6, 0x00F6, 0x00F6 ),
'Odot' => array ( 0x022E, 0x022E, 0x022E, 0x022E ),
'odot' => array ( 0x022F, 0x022F, 0x022F, 0x022F ),
'Odotbelow' => array ( 0x1ECC, 0x1ECC, 0x1ECC, 0x1ECC ),
'odotbelow' => array ( 0x1ECD, 0x1ECD, 0x1ECD, 0x1ECD ),
'Odblacute' => array ( 0x0150, 0x0150, 0x0150, 0x0150 ),
'odblacute' => array ( 0x0151, 0x0151, 0x0151, 0x0151 ),
'Ohookabove' => array ( 0x1ECE, 0x1ECE, 0x1ECE, 0x1ECE ),
'ohookabove' => array ( 0x1ECF, 0x1ECF, 0x1ECF, 0x1ECF ),
'Ohorn' => array ( 0x01A0, 0x01A0, 0x01A0, 0x01A0 ),
'ohorn' => array ( 0x01A1, 0x01A1, 0x01A1, 0x01A1 ),
'Ohornacute' => array ( 0x1EDA, 0x1EDA, 0x1EDA, 0x1EDA ),
'ohornacute' => array ( 0x1EDB, 0x1EDB, 0x1EDB, 0x1EDB ),
'Ohorndotbelow' => array ( 0x1EE2, 0x1EE2, 0x1EE2, 0x1EE2 ),
'ohorndotbelow' => array ( 0x1EE3, 0x1EE3, 0x1EE3, 0x1EE3 ),
'Ohorngrave' => array ( 0x1EDC, 0x1EDC, 0x1EDC, 0x1EDC ),
'ohorngrave' => array ( 0x1EDD, 0x1EDD, 0x1EDD, 0x1EDD ),
'Ohornhookabove' => array ( 0x1EDE, 0x1EDE, 0x1EDE, 0x1EDE ),
'ohornhookabove' => array ( 0x1EDF, 0x1EDF, 0x1EDF, 0x1EDF ),
'Ohorntilde' => array ( 0x1EE0, 0x1EE0, 0x1EE0, 0x1EE0 ),
'ohorntilde' => array ( 0x1EE1, 0x1EE1, 0x1EE1, 0x1EE1 ),
'Ohungarumlaut' => array ( 0x0150, 0x0150, 0x0150, 0x0150 ),
'ohungarumlaut' => array ( 0x0151, 0x0151, 0x0151, 0x0151 ),
'omacron' => array ( 0x014C, 0x014C, 0x014C, 0x014C ),
'Omacron' => array ( 0x014D, 0x014D, 0x014D, 0x014D ),
'Oogonek' => array ( 0x01EA, 0x01EA, 0x01EA, 0x01EA ),
'oogonek' => array ( 0x01EB, 0x01EB, 0x01EB, 0x01EB ),
'Oslashacute' => array ( 0x01FE, 0x01FE, 0x01FE, 0x01FE ),
'oslashacute' => array ( 0x01FF, 0x01FF, 0x01FF, 0x01FF ),
'Otilde' => array ( 0x00D5, 0x00D5, 0x00D5, 0x00D5 ),
'otilde' => array ( 0x00F5, 0x00F5, 0x00F5, 0x00F5 ),
'overscore' => array ( 0x00AF, 0x00AF, 0x00AF, 0x00AF ),
'Pacute' => array ( 0x1E54, 0x1E54, 0x1E54, 0x1E54 ),
'pacute' => array ( 0x1E55, 0x1E55, 0x1E55, 0x1E55 ),
'Racute' => array ( 0x0154, 0x0154, 0x0154, 0x0154 ),
'racute' => array ( 0x0155, 0x0155, 0x0155, 0x0155 ),
'Rcaron' => array ( 0x0158, 0x0158, 0x0158, 0x0158 ),
'rcaron' => array ( 0x0159, 0x0159, 0x0159, 0x0159 ),
'Rcedilla' => array ( 0x0156, 0x0156, 0x0156, 0x0156 ),
'rcedilla' => array ( 0x0157, 0x0157, 0x0157, 0x0157 ),
'Rcommaaccent' => array ( 0x0156, 0x0156, 0x0156, 0x0156 ),
'rcommaaccent' => array ( 0x0157, 0x0157, 0x0157, 0x0157 ),
'Sacute' => array ( 0x015A, 0x015A, 0x015A, 0x015A ),
'sacute' => array ( 0x015B, 0x015B, 0x015B, 0x015B ),
'Scaron' => array ( 0x0160, 0x0160, 0x0160, 0x0160 ),
'scaron' => array ( 0x0161, 0x0161, 0x0161, 0x0161 ),
'Scedilla' => array ( 0x015E, 0x015E, 0x015E, 0x015E ),
'scedilla' => array ( 0x015F, 0x015F, 0x015F, 0x015F ),
'Scircumflex' => array ( 0x015C, 0x015C, 0x015C, 0x015C ),
'scircumflex' => array ( 0x015D, 0x015D, 0x015D, 0x015D ),
'Scommaaccent' => array ( 0x0218, 0x0218, 0x0218, 0x0218 ),
'scommaaccent' => array ( 0x0219, 0x0219, 0x0219, 0x0219 ),
'Tbar' => array ( 0x1E6E, 0x1E6E, 0x1E6E, 0x1E6E ),
'tbar' => array ( 0x1E6F, 0x1E6F, 0x1E6F, 0x1E6F ),
'Tcaron' => array ( 0x0164, 0x0164, 0x0164, 0x0164 ),
'tcaron' => array ( 0x0165, 0x0165, 0x0165, 0x0165 ),
'Tcedilla' => array ( 0x0162, 0x0162, 0x0162, 0x0162 ),
'tcedilla' => array ( 0x0163, 0x0163, 0x0163, 0x0163 ),
'Tcommaaccent' => array ( 0x0162, 0x0162, 0x0162, 0x0162 ),
'tcommaaccent' => array ( 0x0163, 0x0163, 0x0163, 0x0163 ),
'tildecomb' => array ( 0x0303, 0x0303, 0x0303, 0x0303 ),
'Ubreve' => array ( 0x016C, 0x016C, 0x016C, 0x016C ),
'ubreve' => array ( 0x016D, 0x016D, 0x016D, 0x016D ),
'Ucaron' => array ( 0x01D3, 0x01D3, 0x01D3, 0x01D3 ),
'uCaron' => array ( 0x01D4, 0x01D4, 0x01D4, 0x01D4 ),
'Udblacute' => array ( 0x0170, 0x0170, 0x0170, 0x0170 ),
'udblacute' => array ( 0x0171, 0x0171, 0x0171, 0x0171 ),
'Udieresis' => array ( 0x00DC, 0x00DC, 0x00DC, 0x00DC ),
'udieresis' => array ( 0x00FC, 0x00FC, 0x00FC, 0x00FC ),
'Udotbelow' => array ( 0x1EE4, 0x1EE4, 0x1EE4, 0x1EE4 ),
'udotbelow' => array ( 0x1EE5, 0x1EE5, 0x1EE5, 0x1EE5 ),
'Uhookabove' => array ( 0x1EE6, 0x1EE6, 0x1EE6, 0x1EE6 ),
'uhookabove' => array ( 0x1EE7, 0x1EE7, 0x1EE7, 0x1EE7 ),
'Uhorn' => array ( 0x01AF, 0x01AF, 0x01AF, 0x01AF ),
'uhorn' => array ( 0x01B0, 0x01B0, 0x01B0, 0x01B0 ),
'Uhornacute' => array ( 0x1EE8, 0x1EE8, 0x1EE8, 0x1EE8 ),
'uhornacute' => array ( 0x1EE9, 0x1EE9, 0x1EE9, 0x1EE9 ),
'Uhorndotbelow' => array ( 0x1EF0, 0x1EF0, 0x1EF0, 0x1EF0 ),
'uhorndotbelow' => array ( 0x1EF1, 0x1EF1, 0x1EF1, 0x1EF1 ),
'Uhorngrave' => array ( 0x1EEA, 0x1EEA, 0x1EEA, 0x1EEA ),
'uhorngrave' => array ( 0x1EEB, 0x1EEB, 0x1EEB, 0x1EEB ),
'Uhornhookabove' => array ( 0x1EEC, 0x1EEC, 0x1EEC, 0x1EEC ),
'uhornhookabove' => array ( 0x1EED, 0x1EED, 0x1EED, 0x1EED ),
'Uhorntilde' => array ( 0x1EEE, 0x1EEE, 0x1EEE, 0x1EEE ),
'uhorntilde' => array ( 0x1EEF, 0x1EEF, 0x1EEF, 0x1EEF ),
'Uhungarumlaut' => array ( 0x0170, 0x0170, 0x0170, 0x0170 ),
'uhungarumlaut' => array ( 0x0171, 0x0171, 0x0171, 0x0171 ),
'Umacron' => array ( 0x016A, 0x016A, 0x016A, 0x016A ),
'umacron' => array ( 0x016B, 0x016B, 0x016B, 0x016B ),
'Uogonek' => array ( 0x0172, 0x0172, 0x0172, 0x0172 ),
'uogonek' => array ( 0x0173, 0x0173, 0x0173, 0x0173 ),
'Uring' => array ( 0x016E, 0x016E, 0x016E, 0x016E ),
'uring' => array ( 0x016F, 0x016F, 0x016F, 0x016F ),
'upsilondieresis' => array ( 0x00FF, 0x00FF, 0x00FF, 0x00FF ),
'Upsilondieresis' => array ( 0x0178, 0x0178, 0x0178, 0x0178 ),
'Utilde' => array ( 0x0168, 0x0168, 0x0168, 0x0168 ),
'utilde' => array ( 0x0169, 0x0169, 0x0169, 0x0169 ),
'Wacute' => array ( 0x1E82, 0x1E82, 0x1E82, 0x1E82 ),
'wacute' => array ( 0x1E83, 0x1E83, 0x1E83, 0x1E83 ),
'Wcircumflex' => array ( 0x0174, 0x0174, 0x0174, 0x0174 ),
'wcircumflex' => array ( 0x0175, 0x0175, 0x0175, 0x0175 ),
'Wdieresis' => array ( 0x1E84, 0x1E84, 0x1E84, 0x1E84 ),
'wdieresis' => array ( 0x1E8E, 0x1E8E, 0x1E8E, 0x1E8E ),
'Wgrave' => array ( 0x00C0, 0x00C0, 0x00C0, 0x00C0 ),
'wgrave' => array ( 0x00E0, 0x00E0, 0x00E0, 0x00E0 ),
'Yacute' => array ( 0x00DD, 0x00DD, 0x00DD, 0x00DD ),
'yacute' => array ( 0x00DE, 0x00DE, 0x00DE, 0x00DE ),
'Ycircumflex' => array ( 0x0176, 0x0176, 0x0176, 0x0176 ),
'ycircumflex' => array ( 0x0177, 0x0177, 0x0177, 0x0177 ),
'Ydieresis' => array ( 0x0178, 0x0178, 0x0178, 0x0178 ),
'ydieresis' => array ( 0x00FF, 0x00FF, 0x00FF, 0x00FF ),
'Ydotbelow' => array ( 0x1EF4, 0x1EF4, 0x1EF4, 0x1EF4 ),
'ydotbelow' => array ( 0x1EF5, 0x1EF5, 0x1EF5, 0x1EF5 ),
'Ygrave' => array ( 0x1EF2, 0x1EF2, 0x1EF2, 0x1EF2 ),
'ygrave' => array ( 0x1EF3, 0x1EF3, 0x1EF3, 0x1EF3 ),
'Yhookabove' => array ( 0x1EF6, 0x1EF6, 0x1EF6, 0x1EF6 ),
'yhookabove' => array ( 0x1EF7, 0x1EF7, 0x1EF7, 0x1EF7 ),
'Ytilde' => array ( 0x1EF8, 0x1EF8, 0x1EF8, 0x1EF8 ),
'ytilde' => array ( 0x1EF9, 0x1EF9, 0x1EF9, 0x1EF9 ),
'Zacute' => array ( 0x0179, 0x0179, 0x0179, 0x0179 ),
'zacute' => array ( 0x017A, 0x017A, 0x017A, 0x017A ),
'Zcaron' => array ( 0x017E, 0x017E, 0x017E, 0x017E ),
'zcaron' => array ( 0x017D, 0x017D, 0x017D, 0x017D ),
'Zcircumflex' => array ( 0x1E90, 0x1E90, 0x1E90, 0x1E90 ),
'zcircumflex' => array ( 0x1E91, 0x1E91, 0x1E91, 0x1E91 ),
'zdot' => array ( 0x017C, 0x017C, 0x017C, 0x017C ),
'Zdot' => array ( 0x017B, 0x017B, 0x017B, 0x017B ),
'zdotaccent' => array ( 0x017C, 0x017C, 0x017C, 0x017C ),
'Zdotaccent' => array ( 0x017B, 0x017B, 0x017B, 0x017B ),
// Special symbols
'approxequal' => array ( 0x2248, 0x2248, 0x2248, 0x2248 ),
'arrowleft' => array ( 0x2190, 0x2190, 0x2190, 0x2190 ),
'arrowright' => array ( 0x2192, 0x2192, 0x2192, 0x2192 ),
'block' => array ( 0x2588, 0x2588, 0x2588, 0x2588 ),
'circle' => array ( 0x25CB, 0x25CB, 0x25CB, 0x25CB ),
'club' => array ( 0x2663, 0x2663, 0x2663, 0x2663 ),
'commaaccent' => array ( 0x002C, 0x002C, 0x002C, 0x002C ),
'congruent' => array ( 0x2261, 0x2261, 0x2261, 0x2261 ),
'dkshade' => array ( 0x2593, 0x2593, 0x2593, 0x2593 ),
'dnblock' => array ( 0x2584, 0x2584, 0x2584, 0x2584 ),
'eightsuperior' => array ( 0x2078, 0x2663, 0x2663, 0x2663 ),
'emptyset' => array ( 0x2205, 0x2205, 0x2205, 0x2205 ),
'equivalence' => array ( 0x2261, 0x2261, 0x2261, 0x2261 ),
'estimated' => array ( 0x212E, 0x212E, 0x212E, 0x212E ),
'exclamdbl' => array ( 0x203C, 0x203C, 0x203C, 0x203C ),
'female' => array ( 0x2640, 0x2640, 0x2640, 0x2640 ),
'filledbox' => array ( 0x25A0, 0x25A0, 0x25A0, 0x25A0 ),
'filledrect' => array ( 0x25AC, 0x25AC, 0x25AC, 0x25AC ),
'fiveeighths' => array ( 0x251D, 0x251D, 0x251D, 0x251D ),
'fivesuperior' => array ( 0x2075, 0x2075, 0x2075, 0x2075 ),
'foursuperior' => array ( 0x2074, 0x2074, 0x2074, 0x2074 ),
'four.superior' => array ( 0x2074, 0x2074, 0x2074, 0x2074 ),
'franc' => array ( 0x20A3, 0x20A3, 0x20A3, 0x20A3 ),
'greaterequal' => array ( 0x2265, 0x2265, 0x2265, 0x2265 ),
'heart' => array ( 0x2665, 0x2665, 0x2665, 0x2665 ),
'house' => array ( 0x2302, 0x2302, 0x2302, 0x2302 ),
'increment' => array ( 0x2206, 0x2206, 0x2206, 0x2206 ),
'infinity' => array ( 0x221E, 0x221E, 0x221E, 0x221E ),
'integral' => array ( 0x222B, 0x222B, 0x222B, 0x222B ),
'integralbt' => array ( 0x2321, 0x2321, 0x2321, 0x2321 ),
'integraltp' => array ( 0x2320, 0x2320, 0x2320, 0x2320 ),
'intersection' => array ( 0x2229, 0x2229, 0x2229, 0x2229 ),
'invbullet' => array ( 0x25D8, 0x25D8, 0x25D8, 0x25D8 ),
'invcircle' => array ( 0x25D9, 0x25D9, 0x25D9, 0x25D9 ),
'invsmileface' => array ( 0x263B, 0x263B, 0x263B, 0x263B ),
'lessequal' => array ( 0x2264, 0x2264, 0x2264, 0x2264 ),
'lfblock' => array ( 0x258C, 0x258C, 0x258C, 0x258C ),
'lira' => array ( 0x20A4, 0x20A4, 0x20A4, 0x20A4 ),
'ltshade' => array ( 0x2591, 0x2591, 0x2591, 0x2591 ),
'longs' => array ( 0x017F, 0x017F, 0x017F, 0x017F ),
'male' => array ( 0x2642, 0x2642, 0x2642, 0x2642 ),
'middot' => array ( 0x00B7, 0x00B7, 0x00B7, 0x00B7 ),
'minute' => array ( 0x2032, 0x2032, 0x2032, 0x2032 ),
'musicalnote' => array ( 0x266A, 0x266A, 0x266A, 0x266A ),
'musicalnotedbl' => array ( 0x266B, 0x266B, 0x266B, 0x266B ),
'ninesuperior' => array ( 0x2079, 0x2079, 0x2079, 0x2079 ),
'notequal' => array ( 0x2260, 0x2260, 0x2260, 0x2260 ),
'nsuperior' => array ( 0x207F, 0x207F, 0x207F, 0x207F ),
'Ohm' => array ( 0x2126, 0x2126, 0x2126, 0x2126 ),
'ohm' => array ( 0x03C9, 0x03C9, 0x03C9, 0x03C9 ),
'oneeighth' => array ( 0x215B, 0x215B, 0x215B, 0x215B ),
'onesuperior' => array ( 0x2071, 0x2071, 0x2071, 0x2071 ),
'one.superior' => array ( 0x2071, 0x2071, 0x2071, 0x2071 ),
'onethird' => array ( 0x2153, 0x2153, 0x2153, 0x2153 ),
'orthogonal' => array ( 0x221F, 0x221F, 0x221F, 0x221F ),
'parenleftbt' => array ( 0x0028, 0x0028, 0x0028, 0x0028 ),
'parenleftex' => array ( 0x0028, 0x0028, 0x0028, 0x0028 ),
'parenlefttp' => array ( 0x0028, 0x0028, 0x0028, 0x0028 ),
'parenrightbt' => array ( 0x0029, 0x0029, 0x0029, 0x0029 ),
'parenrightex' => array ( 0x0029, 0x0029, 0x0029, 0x0029 ),
'parenrighttp' => array ( 0x0029, 0x0029, 0x0029, 0x0029 ),
'partialdiff' => array ( 0x2202, 0x2202, 0x2202, 0x2202 ),
'peseta' => array ( 0x20A7, 0x20A7, 0x20A7, 0x20A7 ),
'product' => array ( 0x220F, 0x220F, 0x220F, 0x220F ),
'quotereversed' => array ( 0x201B, 0x201B, 0x201B, 0x201B ),
'radical' => array ( 0x23B7, 0x23B7, 0x23B7, 0x23B7 ),
'radicalex' => array ( 0x203E, 0x203E, 0x203E, 0x203E ),
'revlogicalnot' => array ( 0x2310, 0x2310, 0x2310, 0x2310 ),
'rtblock' => array ( 0x2590, 0x2590, 0x2590, 0x2590 ),
'second' => array ( 0x2033, 0x2033, 0x2033, 0x2033 ),
'seveneighths' => array ( 0x215E, 0x215E, 0x215E, 0x215E ),
'sevensuperior' => array ( 0x2077, 0x2077, 0x2077, 0x2077 ),
'shade' => array ( 0x2592, 0x2592, 0x2592, 0x2592 ),
'similar' => array ( 0x2242, 0x2242, 0x2242, 0x2242 ),
'smileface' => array ( 0x263A, 0x263A, 0x263A, 0x263A ),
'sixsuperior' => array ( 0x2076, 0x2076, 0x2076, 0x2076 ),
'spade' => array ( 0x2660, 0x2660, 0x2660, 0x2660 ),
'summation' => array ( 0x2211, 0x2211, 0x2211, 0x2211 ),
'sun' => array ( 0x263C, 0x263C, 0x263C, 0x263C ),
'threeeighths' => array ( 0x215C, 0x215C, 0x215C, 0x215C ),
'threesuperior' => array ( 0x00B3, 0x00B3, 0x00B3, 0x00B3 ),
'three.superior' => array ( 0x00B3, 0x00B3, 0x00B3, 0x00B3 ),
'triagdn' => array ( 0x25BC, 0x25BC, 0x25BC, 0x25BC ),
'triaglf' => array ( 0x25C4, 0x25C4, 0x25C4, 0x25C4 ),
'triagrt' => array ( 0x25BA, 0x25BA, 0x25BA, 0x25BA ),
'triagup' => array ( 0x25B2, 0x25B2, 0x25B2, 0x25B2 ),
'twosuperior' => array ( 0x00B2, 0x00B2, 0x00B2, 0x00B2 ),
'two.superior' => array ( 0x00B2, 0x00B2, 0x00B2, 0x00B2 ),
'twothirds' => array ( 0x2154, 0x2154, 0x2154, 0x2154 ),
'undercommaaccent' => array ( 0x0326, 0x0326, 0x0326, 0x0326 ),
'underscoredbl' => array ( 0x005F, 0x005F, 0x005F, 0x005F ),
'upblock' => array ( 0x2580, 0x2580, 0x2580, 0x2580 ),
'zerosuperior' => array ( 0x2070, 0x2070, 0x2070, 0x2070 ),
// Greek characters
'Alpha' => array ( 0x0391, 0x0391, 0x0391, 0x0391 ),
'alpha' => array ( 0x03B1, 0x03B1, 0x03B1, 0x03B1 ),
'Alphatonos' => array ( 0x0386, 0x0386, 0x0386, 0x0386 ),
'alphatonos' => array ( 0x03AC, 0x03AC, 0x03AC, 0x03AC ),
'anoteleia' => array ( 0x0387, 0x0387, 0x0387, 0x0387 ),
'Beta' => array ( 0x0392, 0x0392, 0x0392, 0x0392 ),
'beta' => array ( 0x03B2, 0x03B2, 0x03B2, 0x03B2 ),
'Gamma' => array ( 0x0393, 0x0393, 0x0393, 0x0393 ),
'gamma' => array ( 0x03B3, 0x03B3, 0x03B3, 0x03B3 ),
'Delta' => array ( 0x0394, 0x0394, 0x0394, 0x0394 ),
'Deltagreek' => array ( 0x0394, 0x0394, 0x0394, 0x0394 ),
'delta' => array ( 0x03B4, 0x03B4, 0x03B4, 0x03B4 ),
'dieresistonos' => array ( 0x0385, 0x0385, 0x0385, 0x0385 ),
'Epsilon' => array ( 0x0395, 0x0395, 0x0395, 0x0395 ),
'epsilon' => array ( 0x03B5, 0x03B5, 0x03B5, 0x03B5 ),
'Epsilontonos' => array ( 0x0388, 0x0388, 0x0388, 0x0388 ),
'epsilontonos' => array ( 0x03AD, 0x03AD, 0x03AD, 0x03AD ),
'Etatonos' => array ( 0x0389, 0x0389, 0x0389, 0x0389 ),
'etatonos' => array ( 0x03AD, 0x03AD, 0x03AD, 0x03AD ),
'Zeta' => array ( 0x0396, 0x0396, 0x0396, 0x0396 ),
'zeta' => array ( 0x03B6, 0x03B6, 0x03B6, 0x03B6 ),
'Eta' => array ( 0x0397, 0x0397, 0x0397, 0x0397 ),
'eta' => array ( 0x03B7, 0x03B7, 0x03B7, 0x03B7 ),
'Theta' => array ( 0x0398, 0x0398, 0x0398, 0x0398 ),
'theta' => array ( 0x03B8, 0x03B8, 0x03B8, 0x03B8 ),
'Iota' => array ( 0x0399, 0x0399, 0x0399, 0x0399 ),
'Iotadieresis' => array ( 0x03AA, 0x03AA, 0x03AA, 0x03AA ),
'iotadieresis' => array ( 0x03CA, 0x03CA, 0x03CA, 0x03CA ),
'iota' => array ( 0x03B9, 0x03B9, 0x03B9, 0x03B9 ),
'iotadieresistonos' => array ( 0x0390, 0x0390, 0x0390, 0x0390 ),
'Iotatonos' => array ( 0x038A, 0x038A, 0x038A, 0x038A ),
'iotatonos' => array ( 0x03AF, 0x03AF, 0x03AF, 0x03AF ),
'Kappa' => array ( 0x039A, 0x039A, 0x039A, 0x039A ),
'kappa' => array ( 0x03BA, 0x03BA, 0x03BA, 0x03BA ),
'Lambda' => array ( 0x039B, 0x039B, 0x039B, 0x039B ),
'lambda' => array ( 0x03BB, 0x03BB, 0x03BB, 0x03BB ),
'Mu' => array ( 0x039C, 0x039C, 0x039C, 0x039C ),
'mu' => array ( 0x03BC, 0x03BC, 0x03BC, 0x03BC ),
'Mu1' => array ( 0x039C, 0x039C, 0x039C, 0x039C ),
'mu1' => array ( 0x03BC, 0x03BC, 0x03BC, 0x03BC ),
'Nu' => array ( 0x039D, 0x039D, 0x039D, 0x039D ),
'nu' => array ( 0x03BD, 0x03BD, 0x03BD, 0x03BD ),
'Xi' => array ( 0x039E, 0x039E, 0x039E, 0x039E ),
'xi' => array ( 0x03BE, 0x03BE, 0x03BE, 0x03BE ),
'Omicron' => array ( 0x039F, 0x039F, 0x039F, 0x039F ),
'omicron' => array ( 0x03BF, 0x03BF, 0x03BF, 0x03BF ),
'Omicrontonos' => array ( 0x038C, 0x038C, 0x038C, 0x038C ),
'omicrontonos' => array ( 0x03CC, 0x03CC, 0x03CC, 0x03CC ),
'Pi' => array ( 0x03A0, 0x03A0, 0x03A0, 0x03A0 ),
'pi' => array ( 0x03C0, 0x03C0, 0x03C0, 0x03C0 ),
'Rho' => array ( 0x03A1, 0x03A1, 0x03A1, 0x03A1 ),
'rho' => array ( 0x03C1, 0x03C1, 0x03C1, 0x03C1 ),
'Sigma' => array ( 0x03A3, 0x03A3, 0x03A3, 0x03A3 ),
'sigma' => array ( 0x03C3, 0x03C3, 0x03C3, 0x03C3 ),
'Sigma1' => array ( 0x03A2, 0x03A2, 0x03A2, 0x03A2 ),
'sigma1' => array ( 0x03C2, 0x03C2, 0x03C2, 0x03C2 ),
'Tau' => array ( 0x03A4, 0x03A4, 0x03A4, 0x03A4 ),
'tonos' => array ( 0x0384, 0x0384, 0x0384, 0x0384 ),
'tau' => array ( 0x03C4, 0x03C4, 0x03C4, 0x03C4 ),
'Upsilon' => array ( 0x03A5, 0x03A5, 0x03A5, 0x03A5 ),
'upsilon' => array ( 0x03C5, 0x03C5, 0x03C5, 0x03C5 ),
'Upsilondieresis' => array ( 0x03AB, 0x03AB, 0x03AB, 0x03AB ),
'upsilondieresis' => array ( 0x03CB, 0x03CB, 0x03CB, 0x03CB ),
'Upsilontonos' => array ( 0x038E, 0x038E, 0x038E, 0x038E ),
'upsilontonos' => array ( 0x03CD, 0x03CD, 0x03CD, 0x03CD ),
'upsilondieresistonos' => array ( 0x03B0, 0x03B0, 0x03B0, 0x03B0 ),
'Phi' => array ( 0x03A6, 0x03A6, 0x03A6, 0x03A6 ),
'phi' => array ( 0x03C6, 0x03C6, 0x03C6, 0x03C6 ),
'Chi' => array ( 0x03A7, 0x03A7, 0x03A7, 0x03A7 ),
'chi' => array ( 0x03C7, 0x03C7, 0x03C7, 0x03C7 ),
'Psi' => array ( 0x03A8, 0x03A8, 0x03A8, 0x03A8 ),
'psi' => array ( 0x03C8, 0x03C8, 0x03C8, 0x03C8 ),
'Omega' => array ( 0x03A9, 0x03A9, 0x03A9, 0x03A9 ),
'omega' => array ( 0x03C9, 0x03C9, 0x03C9, 0x03C9 ),
'Omegatonos' => array ( 0x038F, 0x038F, 0x038F, 0x038F ),
'omegatonos' => array ( 0x03CE, 0x03CE, 0x03CE, 0x03CE ),
// http://www.tipometar.org/pojmovnik/Hint/img/Using%20Fontographer.pdf
// ftp://ftp.software.ibm.com/software/globalization/gcoc/attachments/CP00437.pdf
// http://jrgraphix.net/r/Unicode/2500-257F
// http://www.alanwood.net/demos/wingdings.html
// Almost everything is in the links ; the table blow needs to be completed, though
'.notdef' => array ( 0x0020, 0x0020, 0x0020, 0x0020 ), // Undefined (?)
'afii00208' => array ( 0x002D, 0x002D, 0x002D, 0x002D ), // Minus
'afii08941' => array ( 0x204A, 0x204A, 0x204A, 0x204A ), // Pound
'afii10017' => array ( 0x0410, 0x0410, 0x0410, 0x0410 ),
'afii10018' => array ( 0x0411, 0x0411, 0x0411, 0x0411 ),
'afii10019' => array ( 0x0412, 0x0412, 0x0412, 0x0412 ),
'afii10020' => array ( 0x0413, 0x0413, 0x0413, 0x0413 ),
'afii10021' => array ( 0x0414, 0x0414, 0x0414, 0x0414 ),
'afii10022' => array ( 0x0415, 0x0415, 0x0415, 0x0415 ),
'afii10023' => array ( 0x0401, 0x0401, 0x0401, 0x0401 ),
'afii10024' => array ( 0x0416, 0x0416, 0x0416, 0x0416 ),
'afii10025' => array ( 0x0417, 0x0417, 0x0417, 0x0417 ),
'afii10026' => array ( 0x0418, 0x0418, 0x0418, 0x0418 ),
'afii10027' => array ( 0x0419, 0x0419, 0x0419, 0x0419 ),
'afii10028' => array ( 0x041a, 0x041a, 0x041a, 0x041a ),
'afii10029' => array ( 0x041b, 0x041b, 0x041b, 0x041b ),
'afii10030' => array ( 0x041c, 0x041c, 0x041c, 0x041c ),
'afii10031' => array ( 0x041d, 0x041d, 0x041d, 0x041d ),
'afii10032' => array ( 0x041e, 0x041e, 0x041e, 0x041e ),
'afii10033' => array ( 0x041f, 0x041f, 0x041f, 0x041f ),
'afii10034' => array ( 0x0420, 0x0420, 0x0420, 0x0420 ),
'afii10035' => array ( 0x0421, 0x0421, 0x0421, 0x0421 ),
'afii10036' => array ( 0x0422, 0x0422, 0x0422, 0x0422 ),
'afii10037' => array ( 0x0423, 0x0423, 0x0423, 0x0423 ),
'afii10038' => array ( 0x0424, 0x0424, 0x0424, 0x0424 ),
'afii10039' => array ( 0x0425, 0x0425, 0x0425, 0x0425 ),
'afii10040' => array ( 0x0426, 0x0426, 0x0426, 0x0426 ),
'afii10041' => array ( 0x0427, 0x0427, 0x0427, 0x0427 ),
'afii10042' => array ( 0x0428, 0x0428, 0x0428, 0x0428 ),
'afii10043' => array ( 0x0429, 0x0429, 0x0429, 0x0429 ),
'afii10044' => array ( 0x042a, 0x042a, 0x042a, 0x042a ),
'afii10045' => array ( 0x042b, 0x042b, 0x042b, 0x042b ),
'afii10046' => array ( 0x042c, 0x042c, 0x042c, 0x042c ),
'afii10047' => array ( 0x042d, 0x042d, 0x042d, 0x042d ),
'afii10048' => array ( 0x042e, 0x042e, 0x042e, 0x042e ),
'afii10049' => array ( 0x042f, 0x042f, 0x042f, 0x042f ),
'afii10050' => array ( 0x0490, 0x0490, 0x0490, 0x0490 ),
'afii10051' => array ( 0x0402, 0x0402, 0x0402, 0x0402 ),
'afii10052' => array ( 0x0403, 0x0403, 0x0403, 0x0403 ),
'afii10053' => array ( 0x0404, 0x0404, 0x0404, 0x0404 ),
'afii10054' => array ( 0x0405, 0x0405, 0x0405, 0x0405 ),
'afii10055' => array ( 0x0406, 0x0406, 0x0406, 0x0406 ),
'afii10056' => array ( 0x0407, 0x0407, 0x0407, 0x0407 ),
'afii10057' => array ( 0x0408, 0x0408, 0x0408, 0x0408 ),
'afii10058' => array ( 0x0409, 0x0409, 0x0409, 0x0409 ),
'afii10059' => array ( 0x040a, 0x040a, 0x040a, 0x040a ),
'afii10060' => array ( 0x040b, 0x040b, 0x040b, 0x040b ),
'afii10061' => array ( 0x040c, 0x040c, 0x040c, 0x040c ),
'afii10062' => array ( 0x040e, 0x040e, 0x040e, 0x040e ),
'afii10065' => array ( 0x0430, 0x0430, 0x0430, 0x0430 ),
'afii10066' => array ( 0x0431, 0x0431, 0x0431, 0x0431 ),
'afii10067' => array ( 0x0432, 0x0432, 0x0432, 0x0432 ),
'afii10068' => array ( 0x0433, 0x0433, 0x0433, 0x0433 ),
'afii10069' => array ( 0x0434, 0x0434, 0x0434, 0x0434 ),
'afii10070' => array ( 0x0435, 0x0435, 0x0435, 0x0435 ),
'afii10071' => array ( 0x0436, 0x0436, 0x0436, 0x0436 ),
'afii10072' => array ( 0x0437, 0x0437, 0x0437, 0x0437 ),
'afii10073' => array ( 0x0438, 0x0438, 0x0438, 0x0438 ),
'afii10074' => array ( 0x0439, 0x0439, 0x0439, 0x0439 ),
'afii10075' => array ( 0x043a, 0x043a, 0x043a, 0x043a ),
'afii10076' => array ( 0x043b, 0x043b, 0x043b, 0x043b ),
'afii10077' => array ( 0x043c, 0x043c, 0x043c, 0x043c ),
'afii10078' => array ( 0x043d, 0x043d, 0x043d, 0x043d ),
'afii10079' => array ( 0x043e, 0x043e, 0x043e, 0x043e ),
'afii10080' => array ( 0x043f, 0x043f, 0x043f, 0x043f ),
'afii10081' => array ( 0x0440, 0x0440, 0x0440, 0x0440 ),
'afii10082' => array ( 0x0441, 0x0441, 0x0441, 0x0441 ),
'afii10083' => array ( 0x0442, 0x0442, 0x0442, 0x0442 ),
'afii10084' => array ( 0x0443, 0x0443, 0x0443, 0x0443 ),
'afii10085' => array ( 0x0444, 0x0444, 0x0444, 0x0444 ),
'afii10086' => array ( 0x0445, 0x0445, 0x0445, 0x0445 ),
'afii10087' => array ( 0x0446, 0x0446, 0x0446, 0x0446 ),
'afii10088' => array ( 0x0447, 0x0447, 0x0447, 0x0447 ),
'afii10089' => array ( 0x0448, 0x0448, 0x0448, 0x0448 ),
'afii10090' => array ( 0x0449, 0x0449, 0x0449, 0x0449 ),
'afii10091' => array ( 0x044a, 0x044a, 0x044a, 0x044a ),
'afii10092' => array ( 0x044b, 0x044b, 0x044b, 0x044b ),
'afii10093' => array ( 0x044c, 0x044c, 0x044c, 0x044c ),
'afii10094' => array ( 0x044d, 0x044d, 0x044d, 0x044d ),
'afii10095' => array ( 0x044e, 0x044e, 0x044e, 0x044e ),
'afii10096' => array ( 0x044f, 0x044f, 0x044f, 0x044f ),
'afii10097' => array ( 0x0450, 0x0450, 0x0450, 0x0450 ),
'afii10098' => array ( 0x0451, 0x0451, 0x0451, 0x0451 ),
'afii10099' => array ( 0x0452, 0x0452, 0x0452, 0x0452 ),
'afii10100' => array ( 0x0453, 0x0453, 0x0453, 0x0453 ),
'afii10101' => array ( 0x0454, 0x0454, 0x0454, 0x0454 ),
'afii10102' => array ( 0x0455, 0x0455, 0x0455, 0x0455 ),
'afii10103' => array ( 0x0456, 0x0456, 0x0456, 0x0456 ),
'afii10104' => array ( 0x0457, 0x0457, 0x0457, 0x0457 ),
'afii10105' => array ( 0x0458, 0x0458, 0x0458, 0x0458 ),
'afii10106' => array ( 0x0459, 0x0459, 0x0459, 0x0459 ),
'afii10107' => array ( 0x045a, 0x045a, 0x045a, 0x045a ),
'afii10108' => array ( 0x045b, 0x045b, 0x045b, 0x045b ),
'afii10109' => array ( 0x045c, 0x045c, 0x045c, 0x045c ),
'afii10110' => array ( 0x045E, 0x045E, 0x045E, 0x045E ),
'afii10145' => array ( 0x040F, 0x040F, 0x040F, 0x040F ),
'afii10193' => array ( 0x045F, 0x045F, 0x045F, 0x045F ),
'afii61248' => array ( 0x2105, 0x2105, 0x2105, 0x2105 ), // English symbol "care of"
'afii61289' => array ( 0x2113, 0x2113, 0x2113, 0x2113 ), // Lower "l de ronde"
'afii61352' => array ( 0x2116, 0x2116, 0x2116, 0x2116 ),
'H18543' => array ( 0x25A0, 0x25A0, 0x25A0, 0x25A0 ), // Black square
'H18533' => array ( 0x25CF, 0x25CF, 0x25CF, 0x25CF ), // Black circle
'H22073' => array ( 0x25A1, 0x25A1, 0x25A1, 0x25A1 ), // White square
'H18551' => array ( 0x25AB, 0x25AB, 0x25AB, 0x25AB ), // White square with double horizontal borders
'SF070000' => array ( 0x2534, 0x2534, 0x2534, 0x2534 ), // Semi-graphic
'SF010000' => array ( 0x250C, 0x250C, 0x250C, 0x250C ),
'SF020000' => array ( 0x2514, 0x2514, 0x2514, 0x2514 ),
'SF030000' => array ( 0x2510, 0x2510, 0x2510, 0x2510 ),
'SF040000' => array ( 0x2518, 0x2518, 0x2518, 0x2518 ),
'SF050000' => array ( 0x253C, 0x253C, 0x253C, 0x253C ),
'SF060000' => array ( 0x252C, 0x252C, 0x252C, 0x252C ),
'SF070000' => array ( 0x2534, 0x2534, 0x2534, 0x2534 ),
'SF080000' => array ( 0x251C, 0x251C, 0x251C, 0x251C ),
'SF090000' => array ( 0x2524, 0x2524, 0x2524, 0x2524 ),
'SF100000' => array ( 0x2501, 0x2501, 0x2501, 0x2501 ),
'SF110000' => array ( 0x2502, 0x2502, 0x2502, 0x2502 ),
'SF190000' => array ( 0x2561, 0x2561, 0x2561, 0x2561 ),
'SF200000' => array ( 0x2562, 0x2562, 0x2562, 0x2562 ),
'SF210000' => array ( 0x2556, 0x2556, 0x2556, 0x2556 ),
'SF220000' => array ( 0x2555, 0x2555, 0x2555, 0x2555 ),
'SF230000' => array ( 0x2563, 0x2563, 0x2563, 0x2563 ),
'SF240000' => array ( 0x2551, 0x2551, 0x2551, 0x2551 ),
'SF250000' => array ( 0x2557, 0x2557, 0x2557, 0x2557 ),
'SF260000' => array ( 0x255D, 0x255D, 0x255D, 0x255D ),
'SF270000' => array ( 0x255C, 0x255C, 0x255C, 0x255C ),
'SF280000' => array ( 0x255B, 0x255B, 0x255B, 0x255B ),
'SF360000' => array ( 0x255E, 0x255E, 0x255E, 0x255E ),
'SF370000' => array ( 0x255F, 0x255F, 0x255F, 0x255F ),
'SF380000' => array ( 0x255F, 0x255F, 0x255F, 0x255F ),
'SF390000' => array ( 0x2554, 0x2554, 0x2554, 0x2554 ),
'SF400000' => array ( 0x2569, 0x2569, 0x2569, 0x2569 ),
'SF410000' => array ( 0x2566, 0x2566, 0x2566, 0x2566 ),
'SF420000' => array ( 0x2560, 0x2560, 0x2560, 0x2560 ),
'SF430000' => array ( 0x2550, 0x2550, 0x2550, 0x2550 ),
'SF440000' => array ( 0x256C, 0x256C, 0x256C, 0x256C ),
'SF450000' => array ( 0x2567, 0x2567, 0x2567, 0x2567 ),
'SF460000' => array ( 0x2568, 0x2568, 0x2568, 0x2568 ),
'SF470000' => array ( 0x2564, 0x2564, 0x2564, 0x2564 ),
'SF480000' => array ( 0x2565, 0x2565, 0x2565, 0x2565 ),
'SF490000' => array ( 0x2559, 0x2559, 0x2559, 0x2559 ),
'SF500000' => array ( 0x2558, 0x2558, 0x2558, 0x2558 ),
'SF510000' => array ( 0x2552, 0x2552, 0x2552, 0x2552 ),
'SF520000' => array ( 0x2553, 0x2553, 0x2553, 0x2553 ),
'SF530000' => array ( 0x256B, 0x256B, 0x256B, 0x256B ),
'SF540000' => array ( 0x256A, 0x256A, 0x256A, 0x256A ),
// Wingdings
'arrowboth' => array ( 0x2194, 0x2194, 0x2194, 0x2194 ),
'arrowdown' => array ( 0x2193, 0x2193, 0x2193, 0x2193 ),
'arrowleft' => array ( 0x2190, 0x2190, 0x2190, 0x2190 ),
'arrowright' => array ( 0x2192, 0x2192, 0x2192, 0x2192 ),
'arrowup' => array ( 0x2191, 0x2191, 0x2191, 0x2191 ),
'arrowupdn' => array ( 0x2195, 0x2195, 0x2195, 0x2195 ),
'arrowupdnbse' => array ( 0x21A8, 0x21A8, 0x21A8, 0x21A8 ),
'barb2left' => array ( 0x1F868, 0x1F868, 0x1F868, 0x1F868 ), // Wide-headed leftwards barb arrow
'barb2right' => array ( 0x1F86A, 0x1F86A, 0x1F86A, 0x1F86A ), // Wide-headed rightwards barb arrow
'barb2up' => array ( 0x1F869, 0x1F869, 0x1F869, 0x1F869 ), // Wide-headed upwards barb arrow
'barb2down' => array ( 0x1F86B, 0x1F86B, 0x1F86B, 0x1F86B ), // Wide-headed downwards barb arrow
'barb2nw' => array ( 0x1F86C, 0x1F86C, 0x1F86C, 0x1F86C ), // Wide-headed north west barb arrow
'barb2ne' => array ( 0x1F86D, 0x1F86D, 0x1F86D, 0x1F86D ), // Wide-headed north east barb arrow
'barb2sw' => array ( 0x1F86F, 0x1F86F, 0x1F86F, 0x1F86F ), // Wide-headed south west barb arrow
'barb2se' => array ( 0x1F86E, 0x1F86E, 0x1F86E, 0x1F86E ), // Wide-headed south east barb arrow
'barb4left' => array ( 0x1F878, 0x1F878, 0x1F878, 0x1F878 ), // Wide-headed leftwards barb arrow
'barb4right' => array ( 0x1F87A, 0x1F87A, 0x1F87A, 0x1F87A ), // Wide-headed rightwards barb arrow
'barb4up' => array ( 0x1F879, 0x1F879, 0x1F879, 0x1F879 ), // Wide-headed upwards barb arrow
'barb4down' => array ( 0x1F87B, 0x1F87B, 0x1F87B, 0x1F87B ), // Wide-headed downwards barb arrow
'barb4nw' => array ( 0x1F87C, 0x1F87C, 0x1F87C, 0x1F87C ), // Wide-headed north west barb arrow
'barb4ne' => array ( 0x1F87D, 0x1F87D, 0x1F87D, 0x1F87D ), // Wide-headed north east barb arrow
'barb4sw' => array ( 0x1F87F, 0x1F87F, 0x1F87F, 0x1F87F ), // Wide-headed south west barb arrow
'barb4se' => array ( 0x1F87E, 0x1F87E, 0x1F87E, 0x1F87E ), // Wide-headed south east barb arrow
'checkbld' => array ( 0x2714, 0x2714, 0x2714, 0x2714 ), // Heavy checkmark
'diamond' => array ( 0x2666, 0x2666, 0x2666, 0x2666 ),
'head2left' => array ( 0x2B98, 0x2B98, 0x2B98, 0x2B98 ),
'head2right' => array ( 0x2B9A, 0x2B9A, 0x2B9A, 0x2B9A ),
'head2up' => array ( 0x2B99, 0x2B99, 0x2B99, 0x2B99 ),
'head2down' => array ( 0x2B9B, 0x2B9B, 0x2B9B, 0x2B9B ),
'lozenge' => array ( 0x2B27, 0x2B27, 0x2B27, 0x2B27 ),
'lozenge4' => array ( 0x2B27, 0x2B27, 0x2B27, 0x2B27 ),
'lozenge6' => array ( 0x29EB, 0x29EB, 0x29EB, 0x29EB ),
'openbullet' => array ( 0x25E6, 0x25E6, 0x25E6, 0x25E6 ),
'square2' => array ( 0x25AA, 0x25AA, 0x25AA, 0x25AA ),
'square4' => array ( 0x25AA, 0x25AA, 0x25AA, 0x25AA ),
'square6' => array ( 0x25A0, 0x25A0, 0x25A0, 0x25A0 ),
'xrhombus' => array ( 0x2756, 0x2756, 0x2756, 0x2756 ),
// "Entities" found in some documents, but their name made it difficult to locate the entity reference
// within the PDF file ; their names are not meaningful enough to extrapolate their Unicode equivalent :
// .null
// [aAoO].superior
// allah
// apple
// arrowhorizex
// bari.dotless
// circumflex.arab
// cyrillic_otmark
// dot.one, dot.twohoriz, dot.threeup, dot.twovert, dot.four
// f02d
// Gxx, which do not seem to function as /gxx
// glyphxxx
// Ldot and ldot (didn't found the Unicode name)
// lillah
// noxxx, where 'xxx' is a Greek letter name
// nonmarkingreturn
// patah.wide
// pi1
// ryial
// smallv
// UIforward
// vdaggerdbl
// wasla
// wavyhamza
// zero.slash
) ;
PK JvKD G G
CREDITS.mdnu W+A # INTRODUCTION #
I wanted to warmly thank a whole bunch of people here that helped me to enhance my **PdfToText** class. Of course, there is still a lot of work to do, but without their help, I could not have achieved anything reliable.
# INSPIRATIONS #
My first thanks go to the following people :
- The people at Adobe who wrote the Pdf File format reference (I used version 1.7 of this reference, available here : [http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf](http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf "http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf")). As for all specifications and standards, it leaves room for ambiguity, but this is a high quality document that every people concerned with PDF issues should read first (well, as far as you can spen enough time to walk through the 1300 pages that this document contains...)
- The phpclasses.org site, which allowed me to publish this class and provided me with a medium to help new users of my class to solve issues
- The "*unknown developer*" ; when I have been asked for the first time at work to extract text from pdf files, I have been provided with the code referenced here : [contributions/pdftotext.php](contributions/pdftotext.php "contributions/pdftotext.php"). I don't know who this developer is (the source code did not contain any name), but I would like to really thank him, because his works were able to rapidly give me some knowledge of the PDF file format. Although I developed my class my own way, I borrowed from him the **decodeAsciiHex** and **decodeAscii85** functions.
- I also would like to thank Adeel Ahmad Khan whose works gave me further understanding of the Pdf file format ([https://github.com/adeel/php-pdf-parser](https://github.com/adeel/php-pdf-parser "https://github.com/adeel/php-pdf-parser")).
- The author of the TCPDF package
# USERS OF PDFTOTEXT #
When I first published the **PdfToText** class on the *phpclasses.org* site, I already knew that it was not able to handle all the possible situations. The Pdf file format is so versatile that I could not get enough samples to check my class against them.
This is why I clearly asked users to send me sample Pdf files whenever they encountered issues on them, to help me enhance my class ; and every user played the game, so I would like to thank the following people, in completely random order (and hoping that I did not miss anyone of them...) :
- Pawel Lancucki and Blaine Hilton, who helped me to document more precisely on the fact that the class required a PHP version greater or equal to 5.5
- Stephen Layton, who provided me with samples and actively tested my new versions
- Theodis Butler, who also provided me with samples and helped me solve some issues
- Rafael Rojas Torres, who gave me the idea of handling password-protected pdf files. Although not yet implemented, this definitely is on my roadmap.
- Rolf Kellner , who had issues with unicode translations on far-east and middle-east languages. I have not yet solved them, but I'm still working on it !
- Yuri Kadeev, who had issues with data presented in tabular format. I won't be able to solve all of them, but it helped me a lot to solve issues presented by other users.
- Steve Majors, from CashFlowProducts.com, who gave me several samples to work on and even provided me with an access to his bug-tracking system. He also gave me the idea to implement PDF form data extraction.
- Antonio Jùnior, who gave me a sample using text images encoded in a format I did not handle yet ; still under work...
- Tom Perro and the user named *srizoophari*, because they gave me the idea of implementing some features which allow for searching text page by page (and handle page contents separately, instead of a single block of text)
- Shishant Todi, who gave me pdf samples built in a very strange way. I'm still working on them !
- Menny Grossmann, for yet another way to write pdf files in tabular format
- Carin Pretorius, who sent me samples with the biggest character maps I've ever seen
- Rolf Mast, who sent me samples that (finally) did not use character maps and allowed me to solve more easily a few bugs in the way I was parsing text drawing instructions
- Rajnish Tatiwala who, among other things, sent me my first sample containing objects encoded with the CCITT FAX standard.
- Jocemar Varela, who sent me samples that were generated using OCR software
- Aryan Schmitz, who tried to port the PdfToText class to a system running PHP 5.2. This successful attempt led to long and detailed support exchanges, where I really appreciated his proactivity.
- Francisco Godoy, who sent me a PDF sample which was enough simple to help me solve a long-time issue I had with PDF files using inline "templates"
- Patryk, from expromo.pl, who helped me to handle font aliases that are local to a page by providing me with samples easy enough to investigate ; the same samples also helped me
to start an experimental support of CID fonts.
- DL, from aloha-intbiz.eu, who suggested me to give the option of saving images on-the-fly without storing them into memory, and who gave me samples that helped me to process more cases during image extraction.
- Kis Balazs, who gave me a sample which helped me understand why sometimes certain accentuated characters where incorrectly translated.
- Massimo Baglione, who sent me sample covering various artistic domains, and helped me identify and correct
- Aldo Mariussi, which supplied me a 1-page sample that helped me enhance the way 2-bytes character sequences are decoded when specified between parentheses
- Jens Kirk and Roshayne Jaimon, who sent me samples containing compound objects, which incited me to entirely review the way I was handling them. As a side-effect, this new way of handling PDF objects solved as a miracle 3 other bugs !
- Youen Toupin, with a sample containing embedded binary images in regular PDF object streams, which is a feature I was not aware of
- Javier Diez, who submitted a sample created by Quark XPress and helped me solve basic problems not seen so far
- Thomas Bourgeois, who sent me a very comprehensive set of small PDF samples showing issues, some of them were existing for long
- Rob Webster, who sent me my first sample using the LZW compression algorithm
- Darren Jett for his support in helping me to start implementing page layout rendering
- Manuel Osuna, who gave me the idea of defining text capture areas inside a PDF file
- Luis Manuel Reyes, who submitted me samples that helped me improve text layout rendering
- Piotr Markowski, who gave me links to thousands of documents written in Polish, which helped me to considerably enhance my character maps
- And much more...
Although I did not solved all the issues yet, I would like to thank you all for your contributions and your help !
PK JvK README.mdnu W+A # INTRODUCTION #
The PdfToText class has been designed to extract textual contents from a PDF file.
It's pretty simple to use :
include ( 'PdfToText.phpclass' ) ;
$pdf = new PdfToText ( 'sample.pdf' ) ;
echo $pdf -> Text ; // or you could also write : echo ( string ) $pdf ;
The same PdfToText object can be reused to process additional files :
$pdf -> Load ( 'sample2.pdf' ) ;
echo $pdf -> Text ;
Additionally, the **PdfToText** class provides support methods for getting the page number of any text in the underlying PDF file.
Look at the class' blog for an overview on the underlying mechanics that are involved into extracting text contents from pdf files.
Examples are also provided in the **examples/** directory. Please have a look at the [examples/README.md](examples/README.md "README.md") file for a brief explanation on their structure.
**IMPORTANT** : the **PdfToText** class generates UTF8-encoded text. If your default character set is not UTF-8, you may need to add the following **meta** tag in the <head> part of your HTML page :
# FEATURES #
Text rendering in a PDF file is made using an obscure language which provides multiple ways to position the same text at the same location on a page. You could say for example :
. Goto coordinates (x,y)
. Render text ( "Mail : someone@somewhere.com" )
Or :
. Goto next line
. Goto (x1,y)
. Render text ( "Mail" )
. Goto (x2, y)
. Render text ( ":" )
. Goto (x3, y)
. Render text ( "someone@somewhere.com" )
(note that I'm using a pseudo-language here).
Both pieces of code would probably display the same text at the same position, by using rather different ways.
This is why the **PdfToText** class tracks the following information from the drawing-instruction stream to provide more accurate text rendering (even if the output is only pure text) :
- The currently selected font is tracked. This is important because :
- Each font in a PDF file can have its own character map. This means in this case that characters to be drawn using the Adobe language do not specify actual character codes, but an index into the font's character map.
- The current font size is memorized ; this helps to evaluate what is the current y-coordinate when relative positioning instructions are used (such as "goto next line"). Although approximative, this works in a great majority of cases
- If multiple strings are rendered using identical y-coordinate, they will be grouped onto the same line. Note that they must appear sequentially in the instruction flow for this trick to work
- Sub/super-scripted text is usually written at a slightly different y-coordinate than the line it appears in. Such a situation is detected, and the sub/super-scripted text will correctly appear onto the same line
These symptoms will not appear if the *PDFOPT\_BASIC\_LAYOUT* option is specified.
# ADVANCED FEATURES #
The class is able to :
- Render basic page layout (ie, the text is drawn in the same order that Acrobat Reader renders it) using the *PDFOPT\_BASIC\_LAYOUT* option.
- Retrieve form data as a standalone object, using the *GetFormData()* method.
- Capture areas of text within a page
# KNOWN ISSUES #
Here is a list about known issues for the **PdfToText** class ; I'm working on solving them, so I hope this whole paragraph will soon completely disappear !
- Unwanted line breaks may occur within text lines. This is due to the fact that the pdf file contains drawing instructions that use relative positioning. This is especially true for file created with generators such as **PdfCreator**. However, some provisions have been made to try to track put text with roughly the same y-coordinates onto the same line. This limitation does not apply if the *PDFOPT\_BASIC\_LAYOUT* option is specified.
- Encrypted PDF files are not supported
# A NOTE FOR WINDOWS USERS #
An Apache server on Linux platforms allocates a default stack size of 8Mb for its threads. This value is set to 1Mb on Windows platforms.
However, some regular expressions used by the **PdfToText** class may cause the PHP PCRE extension to require a little bit more than 1Mb of stack space when processing certain PDF files.
Such a situation will cause your Windows Apache server to crash and your browser to display a message such as : *Connection reset*. This behavior affect several products such as EasyPHP, XAMPP or Wamp.
To solve this issue, you will have to enable the **mpm** module in your *httpd.conf* file and define a new stack size, as in the following example, given for a Wamp server :
Include conf/extra/httpd-mpm.conf
ThreadStackSize 8388608
# TESTING #
I have tested this class against dozens of documents from various origins, and tested the output generated from each sample document by the *PdfCreator*, *PrimoPdf* and *PDF Pro* tools.
I also compared the output of the **PdfToText** class with that of *Acrobat Reader*, when you choose the *Save as...Text* option. In many situations, the class performs better in positioning the final text than *Acrobat Reader* does.
However, all of that will not guarantee that it will work in every situation ; so, if you find something weird or not functioning properly using the **PdfToText** class, feel free to contact me on this class' blog, and/or send me a sample PDF file at the following email address :
christian.vigh@wuthering-bytes.com
# OTHER LINKS #
This class can also be found here :
[http://www.phpclasses.org/package/9732-PHP-Extract-text-contents-from-PDF-files.html](http://www.phpclasses.org/package/9732-PHP-Extract-text-contents-from-PDF-files.html "http://www.phpclasses.org/package/9732-PHP-Extract-text-contents-from-PDF-files.html")
and here, where you will also find a FAQ section and be able to upload your PDF file samples for live testing :
[http://www.pdftotext.eu](http://www.pdftotext.eu "http://www.pdftotext.eu")
and also here :
[https://github.com/christian-vigh-phpclasses/PdfToText](https://github.com/christian-vigh-phpclasses/PdfToText)
# REFERENCE #
## METHODS ##
### Constructor ###
$pdf = new PdfToText ( $filename = null, $options = self::PDFOPT_NONE, $user\_password = false, $owner\_password = false ) ;
Instantiates a **PdfToText** object. If a filename has been specified, its text contents will be loaded and made available in the *Text* property (otherwise, you will have to call the *Load()* method for that).
See the *Options* property for a description of the *$options* parameter.
The *$user\_password* and *$owner\_password* parameters specify the user/owner password to be used for decrypting a password-protected file (note that this class is not a password cracker !).
In the current version, decryption of password-protected files is not yet supported.
### Load ( $filename, $user\_password = false, $owner\_password = false ) ###
Loads the text contents of the specified filename.
The *$user\_password* and *$owner\_password* parameters specify the user/owner password to be used for decrypting a password-protected file (note that this class is not a password cracker !).
In the current version, decryption of password-protected files is not yet supported.
The method returns the decoded text contents, which are also available through the *Text* property.
### LoadFromString ( $contents, $user\_password = false, $owner\_password = false ) ###
Loads the text contents of the specified PDF contents.
The *$user\_password* and *$owner\_password* parameters specify the user/owner password to be used for decrypting a password-protected file (note that this class is not a password cracker !).
In the current version, decryption of password-protected files is not yet supported.
The method returns the decoded text contents, which are also available through the *Text* property.
### AddAdobeExtraMappings ( $mappings ) ###
Adobe supports 4 predefined fonts : standard, Mac, WinAnsi and PDF). All the characters in these fonts are identified by a character time, a little bit like HTML entities ; for example, 'one' will be the
character '1', 'acircumflex' will be 'â', etc.
There are thousands of character names defined by Adobe (see [https://mupdf.com/docs/browse/source/pdf/pdf-glyphlist.h.html](https://mupdf.com/docs/browse/source/pdf/pdf-glyphlist.h.html "https://mupdf.com/docs/browse/source/pdf/pdf-glyphlist.h.html")).
Some of them are not in this list ; this is the case for example of the 'ax' character names, where 'x' is a decimal number. When such a character is specified in a /Differences array, then there is somewhere
a CharProc[] array giving an object id for each of those characters.
The referenced object(s) in turn contain drawing instructions to draw the glyph. At no point you could
guess what is the corresponding Unicode character for this glyph, since the information is not contained in the PDF file.
The *AddAdobeExtraMappings()* method allows you to specify such correspondences. Specify an array as the *$mappings* parameter, whose keys are the Adobe character name (for example, "a127") and values the
corresponding Unicode values.
The *$mappings* parameter is an associative array whose keys are Adobe character names. The array values can take several forms :
- A character
- An integer value
- An array of up to four character or integer values. Internally, every specified value is converted to an array of four integer values, one for each of the standard Adobe character sets (Standard, Mac, WinAnsi and PDF). The following rules apply :
- If the input value is a single character, the output array corrsponding the Adobe character name will be a set of 4 elements corresponding to the ordinal value of the supplied character.
- If the input value is an integer, the output array will be a set of 4 identical values
- If the input value is an array :
- Arrays with less that 4 elements will be padded, using the last array item for padding
- Arrays with more than 4 elements will be silently truncated
- Each array value can either be a character or a numeric value.
**Note**
In this current implementation, the method applies the mappings to ALL Adobe default fonts. That is,
you cannot have one mapping for one Adobe font referenced in the PDF file, then a second mapping for
a second Adobe font, etc.
### GetCaptures ###
$captures = $pdf -> GetCaptures ( $full = false ) ;
Retrieves the areas of text captured by the **PdfToText** class. This assumes that you specified first the *PDFOPT\_CAPTURE* flag to the class constructor, then called either the *SetCaptures()* or *SetCapturesFromString()* method.
When the *$full* parameter is set to *false* (the default), the returned object is a hierarchy of **stdClass** objects which maps capture names to their values.
When set to *true*, the returned object is of type **PdfToTextCaptures**, which holds much more information. It should be useful only when doing internal debugging of the PdfToText class.
**Note** :
Accessing a property value when the *$full* parameter is *false* can be performed like this (here, we are accessing the value of the *Title* capture in the first page) :
$captures -> Title [1]
When this parameter is *true*, you have to specify the *Text* property to retrieve its contents :
$captures -> Title [1] -> Text
If you plan to switch between both return types during your development phase, you can use a unified approach that works in both cases :
( string ) $captures -> Title [1]
See the **Capturing Text* section for more information on capturing text from PDF files.
### GetFormCount ###
$count = $pdf -> GetFormCount ( ) ;
Returns the actual number of top-level forms defined in the PDF file.
### GetFormData ###
$object = $pdf -> GetFormData ( $template_xml, $index = 0 ) ;
Retrieves the form data for the specified top-level form index. Data is returned as an object inheriting from class **PdfToTextFormData**, which provides ony helper functions to its derived classes.
Data retrieval can be based on a template XML file, or, when the *$template\_xml* parameter is null, a default template will be created using the field names defined in the PDF file.
See the *Form templates* later in this file to get more information on how templates are used and how form data objects are built.
### GetPageFromOffset ( $offset ) ###
Given a byte offset in the Text property, returns its page number in the pdf document.
Page numbers start from 1.
### HasFormData ###
$status = $pdf -> HasFormData ( ) ;
Returns true if the PDF file contains form data.
### MarkTextLike ( $regex, $mark_start, $mark_end ) ###
Sometimes it may be convenient, when you want to extract only a portion of text, to say : "I want to
extract text between this title and this title". The MarkTextLike() method provides some support for
such a task. Imagine you have documents that have the same structure, all starting with an "Introduction"
title :
Introduction
...
some text
...
Some other title
...
By calling the MarkTextLike() method such as in the example below :
$pdf -> MarkTextLike ( '/\bIntroduction\b/', '', 'Introduction
...
some text
...
Some other title
Adding such markers in the output will allow you to easily extract the text between the chapters
"Introduction" and "Some other title", using a regular expression.
The font name used for the first string matched by the specified regular expression will be searched
later to add markers around all the text portions using this font.
The parameters are the following :
- *$regex* (string) : A regular expression to match the text to be matched. Subsequent portions of text using the same font will be surrounded by the marker start/end strings.
- *$marker_start*, *$marker_end* (string) : Markers to surround the string when a match is found.
### SetCaptures ###
$pdf -> SetCaptures ( $xml_file ) ;
Loads the capture definitions from the specified XML file.
Note that you must instantiate the **PdfToText** class with the *PDFOPT\_CAPTURE* flag for this function to work.
See the **Capturing Text* section for more information on capturing text from PDF files.
### SetCapturesFromString ###
$pdf -> SetCaptures ( $xml_data ) ;
Same as the *SetCaptures()* method, but loads the capture definitions from a string instead of a file.
Note that you must instantiate the **PdfToText** class with the *PDFOPT\_CAPTURE* flag for this function to work.
See the **Capturing Text* section for more information on capturing text from PDF files.
### text\_strpos, text\_stripos ###
$result = $pdf -> text_strpos ( $search, $start = 0 ) ;
$result = $pdf -> text_stripos ( $search, $start = 0 ) ;
These methods behave as the strpos/stripos PHP functions, except that :
- They operate on the text contents of the pdf file (Text property)
- They return an array containing the page number and text offset. $result [0] will be set to the page number of the searched text, and $result [1] to its offset in the Text property
Parameters are the following :
- *$search* (string) : String to be searched.
- *$start* (integer) : Start offset in the pdf text contents.
The method returns an array of two values containing the page number and text offset if the searched string has been found, or *false* otherwise.
### document\_strpos, document\_stripos ###
$result = $pdf -> document_strpos ( $search, $group_by_page = false ) ;
$result = $pdf -> document_stripos ( $search, $group_by_page = false ) ;
Searches for ALL occurrences of a given string in the pdf document. The value of the $group_by_page parameter determines how the results are returned :
- When true, the returned value will be an associative array whose keys will be page numbers and values arrays of offset of the found string within the page
- When false, the returned value will be an array of arrays containing two entries : the page number and the text offset.
For example, if a pdf document contains the string "here" at character offset 100 and 200 in page 1, and position 157 in page 3, the returned value will be :
- When *$group\_by\_page* is false :
[ [ 1, 100 ], [ 1, 200 ], [ 3, 157 ] ]
- When *$group\_by\_page* is true :
[ 1 => [ 100, 200 ], 3 => [ 157 ]
The parameters are the following :
- *$search* (string) : String to be searched.
- *$group\_by\_page (boolean) : Indicates whether the found offsets should be grouped by page number or not.
The method returns an array of page numbers/character offsets or *false* if the specified string does not appear in the document.
### text\_match, document\_match ###
$status = $pdf -> text_match ( $pattern, &$match = null, $flags = 0, $offset = 0 ) ;
$status = $pdf -> document_match ( $pattern, &$match = null, $flags = 0, $offset = 0 ) ;
*text\_match()* calls the preg\_match() PHP function on the pdf text contents, to locate the first occurrence of text that matches the specified regular expression.
*document\_match()* calls the preg\_match\_all() function to locate all occurrences that match the specified regular expression.
Note that both methods add the PREG\_OFFSET\_CAPTURE flag when calling preg\_match/preg\_match\_all so you should be aware that all captured results are an array containing the following entries :
- Item [0] is the captured string
- Item [1] is its text offset
- The *text\_match()* and *document\_match()* methods add an extra array item (index 2), which contains the number of the page where the matched text was found
Parameters are the following :
- *$pattern* (string) : Regular expression to be searched.
- *$match* (any) : Output captures. See preg\_match/preg\_match\_all.
- *$flags* (integer) : PCRE flags. See preg\_match/preg\_match\_all.
- *$offset* (integer) : Start offset. See preg\_match/preg\_match\_all.
As for their PHP counterparts, these methods return the number of matched occurrences, or *false* if the specified regular expression is invalid.
## PROPERTIES ##
This section describes the properties that are available in a **PdfTText** object. Note that they should be considered as read-only.
### Author ###
Author name, as inscribed in the PDF file.
### AutoSavedImageFiles ###
When the *PDFOPT\_AUTOSAVE\_IMAGES* flag has been specified, this array of strings will contain the filenames where the auto-saved images have been put.
### BlockSeparator ###
A string to be used for separating chunks of text. The main goal is for processing data displayed in tabular form, to ensure that column contents will not be catenated. However, this does not work in all cases.
The default value is the empty string.
When the *PDFOPT\_BASIC\_LAYOUT* option is specified, this property is used to separate parts of text that are visually on a different x-axis on the same line. In this case, the default separator will be a white space.
### CIDTablesDirectory ###
Path to the directory containing CID mapping tables.
### CreationDate ###
A string containing the document creation date, in UTC format. The value can be used as a parameter to the *strtotime()* PHP function.
### CreatorApplication ###
Application used to create the original document.
### DocumentStartOffset ###
A PDF document normally starts with a string of the form :
%PDF-a.b[.c.d...]
where "a" and "b" (and the "c", "d", ... following) represent the version number of the PDF file.
Some PDF documents may come with garbage at the beginning ; this is "illegal" of course, but Acrobat Reader is able to cope with that. So can do the **PdfToText** class...
This property holds the byte offset in the input file where the starting "%PDF" string has been found.
### EncryptionAlgorithm ###
Algorithm used for password-protected files.
The Adobe documentation states :
A code specifying the algorithm to be used in encrypting and decrypting the document :
- 0 : An alternate algorithm that is undocumented and no longer supported, and whose use is strongly discouraged.
- 1 : Algorithm 3.1.
- 2 [PDF 1.4] : Algorithm 3.1, but allowing key lengths greater than 40 bits.
- 3 [PDF 1.4] : An unpublished algorithm allowing key lengths up to 128 bits. This algorithm is unpublished as an export requirement of the U.S. Department of Commerce.
### EncryptionAlgorithmRevision ###
The revision number of the Standard security handler that is required to interpret this dictionary. The revision number is :
- 2 : for documents that do not require the new encryption features of PDF 1.4, meaning documents encrypted with an *EncryptionAlgorithm* value of 1 and using *EncryptionFlags* bits 1– 6
- 3 : for documents requiring the new encryption features of PDF 1.4, meaning documents encrypted with an *EncryptionAlgorithm* value of 2 or greater or that use the extended *EncryptionFlags* bits 17–21.
### EncryptionFlags ###
A set of *PDFPERM\_** constants describing which operations are authorized on a password-protected PDF file.
### EncryptionKeyLength ###
Defined only when *EncryptionAlgorithm* is 2 or 3. Length of key, in bits, used for encryption and decryption. The size is a multiple of 8, with a minimum value of 40 and maximum value of 128.
### EncryptionMode ###
One of the *PDFCRYPT\_\** constants.
This value is set to *PDFCRYPT\_NONE if the PDF file is not password-protected.
### EncryptMetadata ###
A flag coming from a password-protected file that says is the document metadata is also encrypted.
### EOL ###
The string to be used for line breaks. The default is PHP\_EOL.
### ExtraTextWidth ###
This property is expressed in percents ; it gives the extra percentage to add to the values computed by
the **PdfTexterFont::GetStringWidth()** method.
This value is basically used when computing text positions and string lengths with the *PDFOPT\_BASIC\_LAYOUT option : the computed string length is shorter than its actual length (because of extra spacing determined by character kerning in the font data, among other details).
To determine whether two consecutive blocks of text on the same should be separated by a space, the class will empirically add this extra percentage to the computed string length. The default value is -5 (percent).
### Filename ###
Name of the file whose text contents have been extracted. This value will be an empty string if the
**LoadFromString()** method has been called instead of **Load()**.
### ID, ID2 ###
A pair of unique ids generated for the document. The value of **ID** is used for decrypting password-protected documents.
The second id is not clearly described in the Pdf specifications.
### ImageAutoSaveFileTemplate ###
A template string to be used for generating filenames when the *PDFOPT\_AUTOSAVE\_IMAGES* flag has been specified.
It can contain the following *print*-like formats :
- **%p** : Replaced by the directory where the input PDF file resides.
- **%f** : Replaced by the filename part (without suffix) of the input PDF file.
- **%s** : Replaced by the suffix appropriate to the image format given by the **ImageAutoSaveFormat** property.
- **%d** : Replaced by a sequential value, starting from 1, which gives the image number.
The default value for this property is :
$ImageAutoSaveFileTemplate = "%p/%f.%d.%s" ;
Using the template above, if your input filename is "/tmp/test.pdf" and contains 3 images, then you will get the following output images :
- /tmp/test.1.jpg
- /tmp/test.2.jpg
- /tmp/test.3.jpg
You can also specify a width with the "%d" format specifier ; the numbering will then be padded with leading zeroes. For example, the following template using the same example PDF file as above :
$pdf -> ImageAutoSaveFileTemplate = "%p/%f.%3d.%s" ;
will generate the following filenames :
- /tmp/test.001.jpg
- /tmp/test.002.jpg
- /tmp/test.003.jpg
### ImageAutoSaveFormat ###
When the *PDFOPT\_AUTOSAVE\_IMAGES* flag has been specified, indicates the format to be used for saving the images found in the PDF file. It can be any of the constants defined by the *gd* library regarding image formats :
IMG_JPEG => 'jpg',
IMG_JPG => 'jpg',
IMG_GIF => 'gif',
IMG_PNG => 'png',
IMG_WBMP => 'wbmp',
IMG_XPM => 'xpm'
Note that the association between the constant and corresponding file suffix is automatically handled.
### Images ###
An array of objects inheriting from the **PdfImage** class. Currently, only the **PdfJpegIMage** class is implemented.
The class currently supports the following properties :
- *ImageResource* : a resource that can be used with the Php *imagexxx()* functions to process image contents.
The following methods are available :
- *SaveAs ( $output\_file, $image\_type = IMG\_JPG )* : Saves the current image to the specified output file, using the specified file format (one of the predefined PHP constants : IMG\_JPG, IMG\_GIF, IMG\_PNG, IMG\_XBMP and IMG\_XBM).
- *Output ( )* : Echoes the image contents to the standard output.
Currently, images stored in proprietary Adobe format are not processed and will not appear in this array.
Note that images will be extracted only if the PDFOPT\_DECODE\_IMAGE\_DATA is enabled.
### ImageCount ###
Number of images found in the supplied PDF file. This number will only take into account the images whose format is recognized by the **PdfToText** class.
### ImageData ###
An array of associative arrays that contain the following entries :
- 'type' : Image type. Can be one of the following :
- 'jpeg' : Jpeg image type. Note that in the current version, only jpeg images are processed.
- 'data' : Raw image data.
Note that image data will be extracted only if the PDFOPT\_GET\_IMAGE\_DATA is enabled.
### IsEncrypted ###
This property is set to *true* if the Pdf file is encrypted through some kind of password protection scheme.
### Keywords ###
Keywords, as recorded in the author information part.
### MaxExecutionTime ###
Specifies a maximum execution time in seconds for processing a single file. If this limit is reached, a **PdfToTextTimeoutException** exception will be thrown before PHP terminates the script. This allows the script to gracefully handle the error instead of PHP itself.
Positive values are indicated in seconds. Negative values are subtracted from the *max\_execution\_time* PHP setting to compute the maximum execution time allowed.
If the computed timeout value is out of range, the retained execution time will be *max\_execution\_time* minus one second.
The value of this property is taken into account only if the *PDFOPT\_ENFORCE\_EXECUTION\_TIME* option has been specified.
### MaxExtractedImages ###
Maximum number of images to be extracted. The default is the value 0, meaning that all images will be selected for output if the *PDFOPT\_GET\_IMAGE\_DATA* or *PDFOPT\_AUTOSAVE\_IMAGES* option is set.
### MaxGlobalExecutionTime ###
This static property is the same as **MaxExecutionTime**, except that it works globally. If you have to process *x* files, then it will ensure that the global execution time does not exceed the value of this property.
The value of this property is taken into account only if the *PDFOPT\_ENFORCE\_GLOBAL\_EXECUTION\_TIME* option has been specified.
### MaxSelectedPages ###
Maximum number of pages to be selected. The default is the value 0, meaning that all pages will be selected for output.
A value of 1 will extract the contents of the first page only, which can be useful if your PDF file is large and you're only interested by the contents of the first page.
When this number is negative, selection starts from the end of the file : -1 means "extract the last page", -2 means "extract the last two pages", and so on.
### MemoryUsage, MemoryPeakUsage ###
Report the memory (peak) used by the *Load()* method.
### MinSpaceWidth ###
Sometimes, characters (or blocks of characters) are separated by an offset which is counted in 1/1000's of text units. For certain ranges of values, when displayed on a graphical device, these consecutive characters appear to be separated by one space (or more). Of course, when generating ascii output, we would like to have some equivalent of such spacing.
This is what the *MinSpaceWidth* property is meant for : insert an ascii space in the generated output whenever the offset found exceeds *MinSpaceWidth* text units.
Note that if the *PDFOPT\_REPEAT\_SEPARATOR* flag is set for the *Options* property, the number of spaces inserted will always be based on a multiple of 1000, even if *MinSpaceWidth* is less than 1000. This means that if *MinSpaceWidth* is 200, and the *Options* property has the *PDFOPT\_REPEAT\_SEPARATOR* flag set, AND the offset between two chunks of characters is 1000 text units, only one space will be inserted, not 5 (which would be the result of 1000/200).
### ModificationDate ###
A string containing the last document modification date, in UTC format. The value can be used as a parameter to the *strtotime()* PHP function.
### Options ###
A combination of the following flags :
- *PDFOPT\_REPEAT\_SEPARATOR* : Sometimes, groups of characters are separated by an integer value, which specifies the offset to subtract to the current position before drawing the next group of characters. This quantity is expressed in thousands of "text units". The **PdfToText** class considers that if this value is less than -1000, then the string specified by the *Separator* property needs to be appended to the result before the next group of characters. If this flag is specified, then the *Separator* string will be appended (*offset* % 1000) times.
- *PDFOPT\_GET\_IMAGE\_DATA* : Store image data from the Pdf file to the **ImageData** array property.
- *PDFOPT\_DECODE\_IMAGE\_DATA* : Decode image data and put it in the **Images** array property.
- *PDFOPT\_AUTOSAVE\_IMAGES* : Auto-saves the images found in the PDF file, using a filename template given by the **ImageAutoSaveFileTemplate** property. The **ImageAutoSaveFormat** property will define the image format to be used when generating the image files. The default output format is *IMG\_JPEG*. Note that the **Images** property will be left empty. This flag has been introduced to save internal memory if you only need to extract images.
- *PDFOPT\_IGNORE\_TEXT_LEADING* : This option must be used when you notice that an unnecessary amount of empty lines are inserted between two text elements. This is the symptom that the pdf file contains only relative positioning instructions combined with big values of text leading instructions.
- *PDFOPT\_RAW\_LAYOUT* : Renders the text as it comes from the PDF file. This may sometimes lead to out-of-order text or strings concatenated in an inappropriate way, but this option is to be preferred if you only need to index contents or focus on performance. This is the default option.
- *PDFOPT\_BASIC\_LAYOUT* : Tries to render the text in the order you can see it with Acrobat Reader. Note that the elements will not be mapped in the output exactly as they appear with Acrobat Reader : elements physically disjoint on the x-axis will be separated by a space by default. The **BlockSeparator** property can be used to modify this separator. The following text for example :
Company1 Company2
address1 address2
city1 city2
will be rendered as :
Company1 Company2
address1 address2
city1 city2
or, if you set the **BlockSeparator** property to "#", the output will be :
Company1#Company2
address1#address2
city1#city2
- *PDFOPT\_NO\_HYPHENATED\_WORDS* : When specified, tries to join back hyphenated words into a single word. For example, the following text :
this is a sam-
ple text using hyphe-
nated words that can split
over seve-
ral lines.
will be rendered as :
this is a sample
text using hyphenated
words that can split
over several lines.
- *PDFOPT\_ENFORCE\_EXECUTION\_TIME* : when specified, the **MaxExecutionTime** property will be checked against the PHP setting *max\_execution\_time*. If the time taken to process a single file may risk to take more time than the value in seconds defined for this property, a **PdfToTextTimeout** exception will be thrown before PHP tries to terminate the script execution.
- *PDFOPT\_ENFORCE\_GLOBAL\_EXECUTION\_TIME* : when specified, the **MaxGlobalExecutionTime** static property will be checked against the PHP setting *max\_execution\_time*. If the time taken to process all PDF files since the start of the script may risk to take more time than the value in seconds defined for this property, a **PdfToTextTimeout** exception will be thrown before PHP tries to terminate the script execution.
- *PDFOPT\_DEBUG\_SHOW\_COORDINATES* : Shows the graphics coordinates before each part of text in the output. This option is useful if you want to define capture areas.
- *PDFOPT\_CAPTURE* : Enables capturing areas of text based on an XML definition file or string. Note that specifying this option will automatically set the *PDFOPT\_BASIC\_LAYOUT* flag.
- *PDFOPT\_NONE* : Default value. No special processing flags apply.
### Pages ###
Associative array containing individual page contents. The array key is the page number, starting from 1.
### PageSeparator ###
String to be used when building the *Text* property to separate individual pages. The default value is a newline.
### ProducerApplication ###
Application used to generate the PDF file contents.
### Separator ###
A string to be used for separating blocks when a negative offset less than -1000 thousands of characters is specified between two sequences of characters specified as an array notation. This trick is often used when a pdf file contains tabular data.
The default value is a space.
### Subject ###
Subject written in the author information part.
### Statistics ###
An associative array that contains the following entries :
- 'TextSize' : Contains the total size in bytes represented by the Postscript-like instructions that draw the document contents
- 'OptimizedTextSize' : Not all Postscript-like instructions for drawing page contents are significant ; since the parsing is done in pure PHP, it is very slow. This is why removing useless instructions with the preg\_replace() builtin function will in most cases significantly reduce the size of the data to be parsed. This entry gives the total size of the data that will be effectively parsed after removing the useless instructions.
### Text ###
A string containing the whole text extracted from the underlying pdf file. Note that pages are separated with a form feed.
### Title ###
Document title, as specified in the author information object.
### Utf8Placeholder ###
When a Unicode character cannot be correctly recognized, the Utf8Placeholder property will be used as a substitution.
The string can contain format specifiers recognized by the sprintf() function. The parameter passed to sprintf() is the Unicode codepoint that could not be recognized (an integer value).
The default value is the empty string, or the string '[Unknown character 0x%08X]' when debug mode is enabled.
Note that if you change the *PdfToText::$DEBUG** variable **after** the first instantiation of the class, then you will need to manually set the value of the *PdfToText::Utf8PlaceHolder* static property.
## CONSTANTS ##
### PDFOPT\_\* ###
The PDFOPT\_\* constants are a set of flags which can be combined when either instantiating the class or setting the *Options* property before calling the **Load** method. It can be a combination of any of the following flags :
- *PDFOPT\_REPEAT\_SEPARATOR* : Sometimes, groups of characters are separated by an integer value, which specifies the offset to subtract to the current position before drawing the next group of characters. This quantity is expressed in thousands of "text units". The **PdfToText** class considers that if this value is less than -1000, then the string specified by the *Separator* property needs to be appended to the result before the next group of characters. If this flag is specified, then the *Separator* string will be appended (*offset* % 1000) times.
- *PDFOPT\_GET\_IMAGE\_DATA* : Store image data from the Pdf file to the **ImageData** array property.
- *PDFOPT\_DECODE\_IMAGE\_DATA* : Decode image data and put it in the **Images** array property.
- *PDFOPT\_AUTOSAVE\_IMAGES* : Auto-saves the images found in the PDF file, using a filename template given by the **ImageAutoSaveFileTemplate** property. The **ImageAutoSaveFormat** property will define the image format to be used when generating the image files. The default output format is *IMG\_JPEG*. Note that the **Images** property will be left empty. This flag has been introduced to save internal memory if you only need to extract images.
- *PDFOPT\_IGNORE\_TEXT_LEADING* : This option must be used when you notice that an unnecessary amount of empty lines are inserted between two text elements. This is the symptom that the pdf file contains only relative positioning instructions combined with big values of text leading instructions.
- *PDFOPT\_RAW\_LAYOUT* : Renders the text as it comes from the PDF file. This may sometimes lead to out-of-order text or strings concatenated in an inappropriate way, but this option is to be preferred if you only need to index contents or focus on performance. This is the default option.
- *PDFOPT\_BASIC\_LAYOUT* : Tries to render the text in the order you can see it with Acrobat Reader. Note that the elements will not be mapped in the output exactly as they appear with Acrobat Reader : elements physically disjoint on the x-axis will be separated by a space by default. The **BlockSeparator** property can be used to modify this separator. The following text for example :
Company1 Company2
address1 address2
city1 city2
will be rendered as :
Company1 Company2
address1 address2
city1 city2
or, if you set the **BlockSeparator** property to "#", the output will be :
Company1#Company2
address1#address2
city1#city2
- *PDFOPT\_NO\_HYPHENATED\_WORDS* : When specified, tries to join back hyphenated words into a single word. For example, the following text :
this is a sam-
ple text using hyphe-
nated words that can split
over seve-
ral lines.
will be rendered as :
this is a sample
text using hyphenated
words that can split
over several lines.
- *PDFOPT\_ENFORCE\_EXECUTION\_TIME* : when specified, the **MaxExecutionTime** property will be checked against the PHP setting *max\_execution\_time*. If the time taken to process a single file may risk to take more time than the value in seconds defined for this property, a **PdfToTextTimeout** exception will be thrown before PHP tries to terminate the script execution.
- *PDFOPT\_ENFORCE\_GLOBAL\_EXECUTION\_TIME* : when specified, the **MaxGlobalExecutionTime** static property will be checked against the PHP setting *max\_execution\_time*. If the time taken to process all PDF files since the start of the script may risk to take more time than the value in seconds defined for this property, a **PdfToTextTimeout** exception will be thrown before PHP tries to terminate the script execution.
- *PDFOPT\_NONE* : Default value. No special processing flags apply.
### Pages ###
Associative array containing individual page contents. The array key is the page number, starting from 1.
### PageSeparator ###
String to be used when building the *Text* property to separate individual pages. The default value is a newline.
### VERSION ###
Current version of the **PdfToText** class, as a string containing a major, minor and release version numbers. For example : "1.2.19".
## Exceptions ##
The **PdfToText** class can throw any of the following exceptions :
### PdfToTextException ###
This is the base class for all exceptions thrown by the **PdfToText** class.
### PdfToTextDecodingException ###
This exception is thrown if an error occurs when decoding a PDF object. Normally, most of these exceptions are thrown only if debug mode is activated.
### PdfToTextDecryptionException ###
Occurs when decryption failed on an encrypted file.
### PdfToTextTimeoutException ###
This exception is thrown only if one of the following conditions occur :
- The *PDFOPT\_ENFORCE\_EXECUTION\_TIME* option has been set, and processing one file took more time than the number of seconds computed from the **$MaxExecutionTime** property
- The *PDFOPT\_ENFORCE\_GLOBAL\_EXECUTION\_TIME* option has been set, and processing all the files your script had to process took more than the number of seconds computed from the **$MaxGlobalExecutionTime** static property
### PdfToTextFormTemplateException ###
Thrown when an error is detected while parsing a template file for retrieving form data, or when retrieving form data.
# Form data extraction #
Extracting form data is fairly simple : use the *GetFormData()* method and it will return you an object containing all the field values contained in your PDF file, whether they have been filled or not.
You have two ways to retrieve form data :
- Either by supplying an XML template, that maps actual form field names to more readable names. It provides additional features such as the ability of grouping field values together
- Or by relying on the default behavior, which will return the form field names as they are defined in the PDF file.
Both methods return a new object inheriting from the **PdfToTextFormData** class, which mainly contain helper functions that have no interest for the caller.
The derived class returned by the *GetFormData()* method has a set of properties that give you access to the form fields contents.
The examples given in the following sections are based on the file "sample.pdf", located in the examples directory "examples/formdata-extraction". It has been taken from a very common form used in the US, located here :
[ https://www.irs.gov/pub/irs-pdf/fw9.pdf]( https://www.irs.gov/pub/irs-pdf/fw9.pdf " https://www.irs.gov/pub/irs-pdf/fw9.pdf")
## Getting form data without a template ##
Gettig form data without a template is very simply ; just execute the following code :
$pdf = new PdfToText ( 'sample.pdf' ) ;
$form_data = $pdf -> GetFormData ( null ) ;
Of course, we should have checked first that form data is present in the PDF file by calling :
if ( $pdf -> HasFormData ( ) )
$form_data = $pdf -> GetFormData ( null ) ;
The object returned in *$form\_data* has the following definition :
$form_data = (object) PdfFormData
{
protected $f1_1 = (string[6]) "ZZNAME"
protected $f1_2 = (string[14]) "ZZBUSINESSNAME"
protected $c1_1 = (string[1]) "6"
protected $f1_3 = (string[1]) "C"
protected $c1_7 = (string[1]) "7"
protected $f1_4 = (string[7]) "ZZOTHER"
protected $f1_5 = (string[4]) "EX01"
protected $f1_6 = (string[4]) "EX02"
protected $f1_7 = (string[9]) "ZZADDRESS"
protected $f1_8 = (string[6]) "ZZCITY"
protected $f1_9 = (string[28]) "ZZREQUESTERNAME\naddress\ncity"
protected $f1_10 = (string[16]) "ZZACCOUNTNUMBERS"
protected $f1_11 = (string[3]) "123"
protected $f1_12 = (string[2]) "45"
protected $f1_13 = (string[4]) "6789"
protected $f1_14 = (string[2]) "EI"
protected $f1_15 = (string[5]) "ZZEMP"
}
You can open file *sample.pdf* to verify that the data listed above is conformant to the one contained in the PDF file.
However, you will see that the field names are not very explicit : *$f1\_1*, *$f1\_2*, etc. Moreover, information such as social security number is splitted in three parts : *$f1\_11*, *$f1\_12* and *$f1\_13*.
This is why you may want to spend some time designing a template XML file that maps PDF field names to human-readable ones...
## Getting form data with a template ##
Using an XML template does not require many changes to your existing code ; you just need to supply the path of your XML template when calling the *GetFormData()* method :
$pdf = new PdfToText ( 'sample.pdf' ) ;
$form_data = $pdf -> GetFormData ( 'sample.xml' ) ;
Using the supplied example, your *$form\_data* object will look like this :
$form_data = (object) W9
{
const TAXCLASS_INDIVIDUAL = 1 ;
const TAXCLASS_C_CORPORATION = 2 ;
const TAXCLASS_S_CORPORATION = 3 ;
const TAXCLASS_PARTNERSHIP = 4 ;
const TAXCLASS_TRUST_ESTATE = 5 ;
const TAXCLASS_LIMITED_LIABILITY_COMPANY = 6 ;
const TAXCLASS_UNDEFINED = "" ;
const TAXCLASS_OTHER = 7 ;
protected $Name = (string[6]) "ZZNAME"
protected $BusinessName = (string[14]) "ZZBUSINESSNAME"
protected $FederalTaxClassification = (string[1]) "6"
protected $LLCClassification = (string[1]) "C"
protected $OtherFederalTaxClassification = (string[1]) "7"
protected $OtherFederalTaxInfo = (string[7]) "ZZOTHER"
protected $ExemptPayeeCode = (string[4]) "EX01"
protected $FATCAExemptionCode = (string[4]) "EX02"
protected $Address = (string[9]) "ZZADDRESS"
protected $City = (string[6]) "ZZCITY"
protected $RequesterCoordinates = (string[28]) "ZZREQUESTERNAME\naddress\ncity"
protected $AccountNumbers = (string[16]) "ZZACCOUNTNUMBERS"
protected $SSN_1 = (string[3]) "123"
protected $SSN_2 = (string[2]) "45"
protected $SSN_3 = (string[4]) "6789"
protected $EIN_1 = (string[2]) "EI"
protected $EIN_2 = (string[5]) "ZZEMP"
protected $SSN = (string[11]) "123-45-6789"
protected $EIN = (string[8]) "EI-ZZEMP"
}
You can notice some important differences with the templateless version :
- The class name is **W9** instead of **PdfFormData** ; this information comes from the template file
- Constants have been defined ; they also come from the template file
- Form fields have an explicit name, such as *BusinessName* (instead of *f1\_2*) or *ExemptPayeeCode* (instead of *f1\_5*)
- Two new properties have appeared : *SSN* and *EIN*. In the original form, the social security number is divided into three parts : *f1\_11*, *f1\_12* and *f1\_13*. These fields have been renamed to *SSN\_1*, *SSN\_2* and *SSN\_3* respectively, by the template XML file. But it also defined *SSN* and *EIN*, which are *grouped* properties. *SSN* has been defined to be the concatenation of the *SSN\_1*, *SSN\_2* and *SSN\_3* properties, and *EIN* the concatenation of the *EIN\_1* and *EIN\_2* properties.
All of the above have been defined in the template file, and the parent class, *PdfToTextFormData*, is able to handle any modifications made to any of the properties involved in a grouped property. For example, if you modify the *SSN\_1* property, then the *SSN* property will be rebuilt accordingly. Similarly, if you modify the *SSN* property, then the *SSN\_1*, *SSN\_2* and *SSN\_3* properties will be changed accordingly.
This internal work is performed by the **PdfToTextFormData**, from which any class returned by the *GetFormData()* method inherits.
Now, this is time to have a look at what is a template. This is described in the next section.
## A typical form template ##
Here is the typical form that has been designed to extract form data from our sample PDF file :
The root tag is specified by *<forms>*. Subtags are *<form>* definitions.
Currently, the following are implemented :
- The *class* attribute of the *<forms>* tag gives the name of the class (inheriting from **PdfToTextFormData**) that will be returned by the *GetFormData()* method, for all the child *<form>* entries.
- Each *<form>* entry has a *version* attribute ; this will be used in the future to handle different versions of the same PDF form.
Please note that the above information could be subject to changes in future releases.
### Defining fields ###
Form fields can currently be of three types :
- String fields
- Choice fields. This is typically used for radiobutton-like checkboxes, which represent a unique field that can have different value, depending on what is checked. Choice fields allow you to associate constants to each individual value.
- Grouped fields. Grouped fields are *virtual* fields that are the result of the concatenation of several existing fields.
A (somewhat) tedious way to get the knowledge of which PDF form field contains which data is :
- Open your PDF form. Fill the values. You may have to test individual values when you are faced with checkboxes (in our above example, properties *FederalTaxClassification* and *OtherFederalTaxClassifications* appear like checkboxes, whose values range from 1 to 7 ; however they have been separated into two fields)
- Make a print_r() of the value returned by the *GetFormData()* method, without specifying any template
- The above steps should help you recognize which field contains what, and design your template accordingly
#### String fields ####
String fields within a form are basically specified with the following XML **field** construct :
The attributes are the following :
- **name** : Property name, as it will be present in the class returned by the *GetFormData()* method.
- **form-field** : corresponding name in the PDF form definition.
- **type** : *string*
#### Choice fields ####
Choice fields are typically used for a group of checkboxes that behave like radiobuttons :
They basically contain the same information as *string* fields, except that the *type* attribute is set to **choice**.
They can be paired to a set of constants defined either through the *<case>* or *<default>* tags :
- *<case>* tags allow you to associate a named constant with a specific value
- *<default>* allow you to associate a named constant when none of the *<case>* tags defined matches the form value.
Note that each defined constant, such as *TAXCLASS\_INDIVIDUAL* in the above example, will be defined as a class constant in the object returned by the *GetFormData()* method.
#### Grouped fields ####
Grouped fields allow you to create new properties, coming from the concatenation of existing fields. A typical definition looks like this :
In our template example, we have seen that the social security number (SSN) was splitted into three parts : *SSN\_1*, *SSN\_2* and *SSN\_3*. The above example creates an *SSN* property, which is the result of the concatenation of the specified fields.
The required attributes are the following :
- *name* : Name of the grouped property
- *fields* : A comma-separated list of existing field names that should be grouped together
- *separator* : Separator string used to separate each component of the grouped field.
Note that modifying the value of a property referenced by a grouped field will modify the corresponding grouped field value. Similarly, modifying the grouped field value will modify its associated properties.
# Capturing text #
Sometimes, it's easier to tell the **PdfToText** class which area(s) of text you want to retrieve from which page(s), rather than having to struggle with regular expressions to isolate the information you want. This is especially true when you want to retrieve data from tabular reports.
Captures are a solution for such needs ; they allow you to define shapes of the following types :
- *Rectangles* : rectangles are used to surround areas of text whose contents you want to extract after processing.
- *Lines* : allow you to capture lines (and columns within lines) when you have to process a report presented in tabular format.
Areas to be captured are specified using a capture definition file or string, in XML format.
## A step-by-step overview ##
Capturing areas of your PDF document will require you a few preliminary steps that involve some extra work. This is why you will have to choose between using captures or using regular expressions on the extracted text :
- If you have several documents of the same type (reports, for example), then it makes sense to spend some time designing a capture definition file than will allow to easily retrieve line/column values
- If you have many documents with many different presentations, then regular expressions will be of better help for you
The step-by-step overview below references the files located in the examples/text-captures directory.
### Determining what to capture ###
A PDF file uses a coordinate system whose values are more or less expressed in "relative units". The point at coordinates (0,0) is located at the bottom-left corner of the page ; the point at coordinates (x,y), where "x" is the page width and "y" the page height, is located at the top-right corner of the page.
That's nice, but how to find the coordinates (x, y, width and height) of the rectangle that contains the text you want to capture ? of course, if you have an Adobe product that allows you to modify PDF files, it may give you such information. But if you don't have such a tool, you're stuck.
The **PdfToText** class has a flag, *PDFOPT\_DEBUG\_SHOW\_COORDINATES*, that includes in the text output the (x,y) coordinates, width and height of each block of text found in the PDF stream. This may be the only occasion you will have to use this option. The following example script explains how the file *sample-report.txt* in the *examples/text-capture* directory of this package was generated :
Text ) ;
The first few lines of file *sample-report.txt* now contain things like this :
[Page : 1, width = 596, height = 843]
[x:248.76, y:760.4, w: 79.895, h:12]REPORT HEADER
[x:70.695, y:746.6, w: 2.381, h:12]
[x:84.495, y:722.6, w: 2.381, h:12]
[x:84.495, y:734.6, w: 2.381, h:12]
[x:0, y:708.08, w: 124.619, h:12]Column1 Column2 Column3
[x:70.8, y:690.32, w: 76.99, h:12]L1C1 L1C2 L1C3
[x:70.8, y:676.04, w: 76.99, h:12]L2C1 L2C2 L2C3
[x:70.8, y:661.76, w: 76.99, h:12]L3C1 L3C2 L3C3
[x:70.8, y:647.48, w: 76.99, h:12]L4C1 L4C2 L4C3
[x:70.8, y:633.2, w: 2.381, h:12]
[Page : 2, width = 596, height = 843]
[x:70.8, y:760.4, w: 2.381, h:12]
[x:0, y:745.88, w: 124.619, h:12]Column1 Column2 Column3
[x:70.8, y:731.72, w: 178.533, h:12]L1C1 (page 2) L1C2 (page 2) L1C3 (page 2)
[x:70.8, y:717.44, w: 178.533, h:12]L2C1 (page 2) L2C2 (page 2) L2C3 (page 2)
[x:70.8, y:703.16, w: 178.533, h:12]L3C1 (page 2) L3C2 (page 2) L3C3 (page 2)
[x:70.8, y:688.88, w: 178.533, h:12]L4C1 (page 2) L4C2 (page 2) L4C3 (page 2)
[x:70.8, y:674.6, w: 2.381, h:12]
instead of the default output with no specific options (see file *sample-report.pdf* for its graphic counterpart) :
REPORT HEADER
Column1 Column2 Column3
L1C1 L1C2 L1C3
L2C1 L2C2 L2C3
L3C1 L3C2 L3C3
L4C1 L4C2 L4C3
Column1 Column2 Column3
L1C1 (page 2) L1C2 (page 2) L1C3 (page 2)
L2C1 (page 2) L2C2 (page 2) L2C3 (page 2)
L3C1 (page 2) L3C2 (page 2) L3C3 (page 2)
L4C1 (page 2) L4C2 (page 2) L4C3 (page 2)
In the output generated with the *PDFOPT\_DEBUG\_SHOW\_COORDINATES* option, you will notice some additional information between square brackets :
- The first one appears at the start of each page :
[Page : 1, width = 596, height = 843]
...
[Page : 2, width = 596, height = 843]
...
It gives the page number, its width and its height in graphics coordinates.
- The second kind of information that appears between square brackets gives size information regarding the block of text immediately following it :
[x:248.76, y:760.4, w: 79.895, h:12]REPORT HEADER
### Designing the capture definitions file (or string) ###
The various information added to the output using the *PDFOPT\_DEBUG\_SHOW\_COORDINATES* option should give you enough data to design the capture definitions file.
An example is given below, which will capture some contents of the PDF file *sample-report.pdf* ; a more detailed explanation of this XML format is given in the **XML Capture Definitions** section :
Basically, the above data says that it wants to capture two things :
- A *<rectangle>*, located on page 1, and named "Title". The specified coordinates (left, top, right, bottom - but you can also specify width or height instead of right and bottom) define the rectangle that contains the string "REPORT HEADER" in the PDF file
- A *<lines>* tag named "ReportLines" that defines which columns are to be captured from the input PDF stream. This is done by using the *<column>* tags, which give the x-position and individual width of every column you want to capture.
You may have noticed that both of the *<rectangle>* and *<lines>* contain subtags named *<page>* ; they define which pages of the input PDF file are applicable to the parent tag. For example :
- The rectangle we want to capture is only defined on page 1 of the PDF file
- The group of lines we want to capture start at y-position 690, and 731 for page 2 until the last page ($). Line heights are 16 in both cases. Inside this group of lines, you can specify as many columns you want to capture (in our example, only one column is defined ; its name is "Column1").
All the coordinates, widths and heights listed in this definition have been taken from the information contained in file *sample-report.txt*, generated at the previous step (the above section).
### Setting up PdfToText to process captures ###
Captures are processed independently of text extraction ; the only two things you have to do is :
- Specify the *PDFOPT\_CAPTURE* in the Options flags
- Call either the *SetCaptures()* or the *SetCapturesFromString()* method to load the capture definitions, as in the following example :
$pdf = new PdfToText ( 'sample-report.pdf', PdfToText::PDFOPT_CAPTURE ) ;
$pdf -> SetCaptures ( 'sample-report.xml' ) ;
### Retrieving capture data ###
Retrieving capture data is fairly simple :
$captures = $pdf -> GetCaptures ( ) ;
This will return an object of type **PdfToTextCaptureLines**.
Each tag that has been defined in the XML definition file (*sample-report.txt* in our example) has a name ; for example, our rectangle shape has the name "Title", and the group of lines is named "ReportLines" (each report line having one column named "Column1").
Every capture name specified in the Capture definitions file can be accessed as a property name in the object returned by the *GetCaptures()* method :
$capture -> Title
$capture -> ReportLines
However, the way these various informations are processed depend on the capture type :
- For Rectangle captures, the property will be an array, since the same capture can be defined on different pages at different locations. To retrieve the Title located on the first page of our PDF file, we will have to write :
$capture -> Title [1] -> Text
or :
( string ) $capture -> Title [1]
Rectangle captures are accessible by their page number. There will be a capture for each page of the document, even if not present in the list of applicable pages.
- For lines captures, the situation is a little bit different : the interest of capturing report lines (together with their column data) is to be able to process them all at once. This is why they are grouped together in a single collection, that you can display or process with such kind of loops :
foreach ( $captures -> ReportLines as $line )
{
foreach ( $line as $column )
// do something with $column -> Text
}
Inside a line, you can also reference a column by its name :
$line -> Column1 -> Text
## XML Capture definitions ##
This section describes the format of an XML Capture definition.
### <captures> tag ###
The <captures> tag is the top-level node for the XML Capture definitions. It has no specific attributes and can contain one or more of the following subtags :
- <rectangle>
- <lines>
### <rectangle> tag ###
The <rectangle> tag defines a rectangular area used to capture text enclosed by it. It has the following attributes :
- *name* : Name of the shape. Must be a valid PHP identifier that will be used to access this property information from the object returned by the *GetCaptures()* method. This name must be unique.
The <rectangle> tag must specify at least one <page> subtag, to indicate the **PdfToText** class on which pages of the document the captured text should be searched.
#### <page> subtag ####
The <page> subtag of the <rectangle> tag has the following attributes :
- *number* : Page number(s). This can be a comma-separated list of pages or ranges of pages separated by an ellipsis, as in the following example :
"1,2"
"1,2..10"
The special character "**$**" means "the last page".
Expressions are allowed ; the following for example :
"1, $-9..$"
indicates that the rectangle area applies to page 1 and to the last 10 pages of the document.
The other attributes for the <page> tag are the following :
- *left* : left x-coordinate of the rectangle.
- *right* : right x-coordinate.
- *top* : top y-coordinate.
- *bottom* : bottom y-coordinate.
- *height* : Specifies the rectangle height. One of the following combinations of attributes must be specified : ($top, $height), ($bottom, $height) or ($top, $bottom)
- *width* : Specifies the rectangle width. One of the following combinations of attributes must be specified : ($left, $width), ($right, $width) or ($left, $right).
### <lines> tag ###
The <lines> tag allows to define a group of lines to be captured. It defines applicable pages, and provides definitions about each column to be captured. It is mainly used for capturing report lines and has the following attributes :
- *name* : Element name. Must be a valid PHP identifier that will be used to access this property information from the object returned by the *GetCaptures()* method. This name must be unique.
- *default* : Provides a default value for columns that have no captured text inside the PDF document.
- *separator* : Each line contains a *Text* property that represents all the columns of the lines, separated by this attribute value.
The *<lines>* tag can contain as many *<page>* and *<column>* subtags as needed.
#### <page> subtag ####
The *<page>* subtag of the *<lines>* tag has more or less the same objective as the *<page>* subtag of the *<rectangle>* tag, with a few differences although. It is not used to define the shape of a rectangle, but rather the top and bottom coordinates of the first and last line of a page, along with the line height.
The following attributes are available :
- *number* : Page number(s). It has the same syntax as for the *<page>* subtag of the *<rectangle>* tag
- *top* : the y-coordinate of the first line to be captured on the page
- *bottom* : the y-coordinate of the last line to be captured on the page. The default is 0.
- *height* : line height.
#### <column> subtag ####
The <column> subtag identifies a column position within a line. It has the following attributes :
- *name* : Column name. This name must be a valid PHP identifier that will be used to access this property information from the object returned by the *GetCaptures()* method. Column names must be unique within a <lines> tag.
- *default* : default value to be put in the capture if no information has been found in this line/column combination. If not specified, the value of the "*default*" attribute of the <lines;> will be used. If not specified, the default value will be the empty string.
- *left* : first x-position of the column
- *width* : column width
- *right* : last x-position of the column.
Either the *width* or *right* attribute must be specified.
## Capture classes reference ##
The object returned by the *GetCaptures()* method needs some explanation ; a distinction has been made between *what* is captured and *how* to access it.
The *GetCaptures()* method returns an object hierarchy that answers the *how* ; every object in this hierarchy contains objects that answer the *what*. The method returns an object of class **PdfToTextCaptures**, described below.
### PdftoTextCaptures class ###
This class dynamically creates properties coming directly from the names specified with the <*rectangle*> and <*lines*> tags of the Capture XML definitions.
Thus, if we take our example definition file and call the *GetCaptures()* method :
$captures = $pdf -> GetCaptures ( ) ;
Then we will be able to access the properties defined in our capture file in the following way :
$captures -> Title
or :
$captures -> ReportLines
Here is the correspondance between Capture XML definitions and the properties found in this object :
- A <*rectangle*> tag will give a property with the same name as the one specified in the *name* attribute of the tag. This property is of type **PdfToTextRectangleCapture**. This is an array property whose indexes are the page numbers containing the captures. Note that there will be an entry for each page of the document, even if empty or if not specified in the <*page*> tag of the <*rectangle*> entry.
- The same principle applies for <*lines*<, which gives a property of type **PdfToTextLinesCapture**.
### PdfToTextRectangleCapture class ###
This class allows to retrieve information about the text captured based on a <*rectangle*> definition. It behaves like an array containing elements of type **PdfToTextCapturedRectangle**.
The reason why this class is an array is because the *rectangle* shape can be used to capture text at different locations on different pages.
### PdfToTextLinesCapture class ###
This class also behaves as an array that gives elements of type **PdfToTextCaptureLine**. It contains the lines that have been captured on the whole document.
### PdfToTextCapturedText class ###
This is the base abstract class for the various shapes captured in the document (PdfToTextCapturedRectangle, etc.). It has the following properties :
- *Name* : capture name
- *Page* : page number where the captured text
- *Text* : captured text
- *Left*, *Right*, *Top*, *Bottom* : coordinates of the captured text
### PdfToTextCapturedRectangle class ###
Inherits from the **PfToTextCapturedText** class. It currently does not add any new properties or methods.
### PdfToTextCapturedLine class ###
Inherits from the **PfToTextCapturedText** class. Adds the following properties :
- *Columns* : An array of **PdfToTextCapturedColumn** objects.
An object of this class can be iterated like an array. It also provides direct access to a **PdfToTextCapturedColumn** object by specifying its name as a property ; for example :
$captured_line -> Column1
Of course, the column name has been specified in the Capture XML definition, with the *name* attribute of the <*column>* tag.
PK JvK}w w FormTemplates/US-IRS-W9.xmlnu W+A
PK JvK`p p PdfToText.phpclassnu W+A Text ; // or : echo ( string ) $pdf ;
Or :
$pdf = new PdfToText ( ) ;
// Modify any property here before loading the file ; for example :
// $pdf -> BlockSeparator = " " ;
$pdf -> Load ( 'sample.pdf' ) ;
echo $pdf -> Text ;
AUTHOR
Christian Vigh, 04/2016.
HISTORY
[Version : 1.6.7] [Date : 2017/05/31] [Author : CV]
. Added CID fonts
. Changed the way CID font maps are searched and handled
(...)
[Version : 1.0] [Date : 2016/04/16] [Author : CV]
Initial version.
**************************************************************************************************************/
/*==============================================================================================================
class PdfToTextException et al -
Implements an exception thrown when an error is encountered while decoding PDF files.
==============================================================================================================*/
// PdfToText exception -
// Base class for all other PdfToText exceptions.
class PdfToTextException extends Exception
{
public static $IsObject = false ;
} ;
// PdfToTextDecodingException -
// Thrown when unexpected data is encountered while analyzing PDF contents.
class PdfToTextDecodingException extends PdfToTextException
{
public function __construct ( $message, $object_id = false )
{
$text = "Pdf decoding error" ;
if ( $object_id !== false )
$text .= " (object #$object_id)" ;
$text .= " : $message" ;
parent::__construct ( $text ) ;
}
}
// PdfToTextDecryptionException -
// Thrown when something unexpected is encountered while processing encrypted data.
class PdfToTextDecryptionException extends PdfToTextException
{
public function __construct ( $message, $object_id = false )
{
$text = "Pdf decryption error" ;
if ( $object_id !== false )
$text .= " (object #$object_id)" ;
$text .= " : $message" ;
parent::__construct ( $text ) ;
}
}
// PdfToTextTimeoutException -
// Thrown when the PDFOPT_ENFORCE_EXECUTION_TIME or PDFOPT_ENFORCE_GLOBAL_EXECUTION_TIME option is set, and
// the script took longer than the allowed execution time limit.
class PdfToTextTimeoutException extends PdfToTextException
{
// Set to true if the reason why the max execution time was reached because of too many invocations of the Load() method
// Set to false if the max execution time was reached by simply processing one PDF file
public $GlobalTimeout ;
public function __construct ( $message, $global, $php_setting, $class_setting )
{
$text = "PdfToText max execution time reached " ;
if ( ! $global )
$text .= "for one single file " ;
$text .= "(php limit = {$php_setting}s, class limit = {$class_setting}s) : $message" ;
$this -> GlobalTimeout = $global ;
parent::__construct ( $text ) ;
}
}
// PdfToTextFormException -
// Thrown if the xml template passed to the GetFormData() method contains an error.
class PdfToTextFormException extends PdfToTextException
{
public function __construct ( $message )
{
$text = "Pdf form template error" ;
$text .= " : $message" ;
parent::__construct ( $text ) ;
}
}
// PdfToTextCaptureException -
// Thrown if the xml template passed to the SetCaptures() method contains an error.
class PdfToTextCaptureException extends PdfToTextException
{
public function __construct ( $message )
{
$text = "Pdf capture template error" ;
$text .= " : $message" ;
parent::__construct ( $text ) ;
}
}
/*==============================================================================================================
Custom error reporting functions.
==============================================================================================================*/
if ( ! function_exists ( 'warning' ) )
{
function warning ( $message )
{
trigger_error ( $message, E_USER_WARNING ) ;
}
}
if ( ! function_exists ( 'error' ) )
{
function error ( $message )
{
if ( is_string ( $message ) )
trigger_error ( $message, E_USER_ERROR ) ;
else if ( is_a ( $message, '\Exception' ) )
throw $message ;
}
}
/*==============================================================================================================
Backward-compatibility issues.
==============================================================================================================*/
// hex2bin -
// This function appeared only in version 5.4.0
if ( ! function_exists ( 'hex2bin' ) )
{
function hex2bin ( $hexstring )
{
$length = strlen ( $hexstring ) ;
$binstring = '' ;
$index = 0 ;
while ( $index < $length )
{
$byte = substr ( $hexstring, $index, 2 ) ;
$ch = pack ( 'H*', $byte ) ;
$binstring .= $ch ;
$index += 2 ;
}
return ( $binstring ) ;
}
}
/*==============================================================================================================
class PfObjectBase -
Base class for all PDF objects defined here.
==============================================================================================================*/
abstract class PdfObjectBase // extends Object
{
// Possible encoding types for streams inside objects ; "unknown" means that the object contains no stream
const PDF_UNKNOWN_ENCODING = 0 ; // No stream decoding type could be identified
const PDF_ASCIIHEX_ENCODING = 1 ; // AsciiHex encoding - not tested
const PDF_ASCII85_ENCODING = 2 ; // Ascii85 encoding - not tested
const PDF_FLATE_ENCODING = 3 ; // Flate/deflate encoding
const PDF_TEXT_ENCODING = 4 ; // Stream data appears in clear text - no decoding required
const PDF_LZW_ENCODING = 5 ; // Not implemented yet
const PDF_RLE_ENCODING = 6 ; // Runtime length encoding ; not implemented yet
const PDF_DCT_ENCODING = 7 ; // JPEG images
const PDF_CCITT_FAX_ENCODING = 8 ; // CCITT Fax encoding - not implemented yet
const PDF_JBIG2_ENCODING = 9 ; // JBIG2 filter encoding (black/white) - not implemented yet
const PDF_JPX_ENCODING = 10 ; // JPEG2000 encoding - not implemented yet
// Regular expression used for recognizing references to a font (this list is far from being exhaustive, as it seems
// that you can specify almost everything - however, trying to recognize everything would require to develop a complete
// parser)
protected static $FontSpecifiers = '
(/F \d+ (\.\d+)? ) |
(/R \d+) |
(/f-\d+-\d+) |
(/[CT]\d+_\d+) |
(/TT \d+) |
(/OPBaseFont \d+) |
(/OPSUFont \d+) |
(/[0-9a-zA-Z]) |
(/F\w+) |
(/[A-Za-z][A-Za-z0-9]* ( [\-+] [A-Za-z][A-Za-z0-9]* ))
' ;
// Maps alien Unicode characters such as special spaces, letters with ligatures to their ascii string equivalent
protected static $UnicodeToSimpleAscii = false ;
/*--------------------------------------------------------------------------------------------------------------
Constructor -
Performs static initializations such as the Unicode to Ascii table.
*-------------------------------------------------------------------------------------------------------------*/
public function __construct ( )
{
if ( self::$UnicodeToSimpleAscii === false )
{
$charset_file = dirname ( __FILE__ ) . "/Maps/unicode-to-ansi.map" ;
include ( $charset_file ) ;
self::$UnicodeToSimpleAscii = ( isset ( $unicode_to_ansi ) ) ? $unicode_to_ansi : array ( ) ;
}
// parent::__construct ( ) ;
}
/*--------------------------------------------------------------------------------------------------------------
NAME
CodePointToUtf8 - Encodes a Unicode codepoint to UTF8.
PROTOTYPE
$char = $this -> CodePointToUtf8 ( $code ) ;
DESCRIPTION
Encodes a Unicode codepoint to UTF8, trying to handle all possible cases.
PARAMETERS
$code (integer) -
Unicode code point to be translated.
RETURN VALUE
A string that contains the UTF8 bytes representing the Unicode code point.
*-------------------------------------------------------------------------------------------------------------*/
protected function CodePointToUtf8 ( $code )
{
if ( $code )
{
$result = '' ;
while ( $code )
{
$word = ( $code & 0xFFFF ) ;
if ( ! isset ( self::$UnicodeToSimpleAscii [ $word ] ) )
{
$entity = "$word;" ;
$result .= mb_convert_encoding ( $entity, 'UTF-8', 'HTML-ENTITIES' ) . $result ;
}
else
$result .= self::$UnicodeToSimpleAscii [ $word ] ;
$code = ( integer ) ( $code / 0xFFFF ) ; // There is no unsigned right-shift operator in PHP...
}
return ( $result ) ;
}
// No translation is apparently possible : use a placeholder to signal this situation
else
{
if ( strpos ( PdfToText::$Utf8Placeholder, '%' ) === false )
{
return ( PdfToText::$Utf8Placeholder ) ;
}
else
return ( sprintf ( PdfToText::$Utf8Placeholder, $code ) ) ;
}
}
/*--------------------------------------------------------------------------------------------------------------
DecodeRawName -
Decodes a string that may contain constructs such as '#xy', where 'xy' are hex digits.
*-------------------------------------------------------------------------------------------------------------*/
public static function DecodeRawName ( $str )
{
return ( rawurldecode ( str_replace ( '#', '%', $str ) ) ) ;
}
/*--------------------------------------------------------------------------------------------------------------
NAME
GetEncodingType - Gets an object encoding type.
PROTOTYPE
$type = $this -> GetEncodingType ( $object_id, $object_data ) ;
DESCRIPTION
When an object is a stream, returns its encoding type.
PARAMETERS
$object_id (integer) -
PDF object number.
$object_data (string) -
Object contents.
RETURN VALUE
Returns one of the following values :
- PdfToText::PDF_ASCIIHEX_ENCODING :
Hexadecimal encoding of the binary values.
Decoding algorithm was taken from the unknown contributor and not tested so far, since I
couldn't find a PDF file with such an encoding type.
- PdfToText::PDF_ASCII85_ENCODING :
Obscure encoding format.
Decoding algorithm was taken from the unknown contributor and not tested so far, since I
couldn't find a PDF file with such an encoding type.
- PdfToText::PDF_FLATE_ENCODING :
gzip/deflate encoding.
- PdfToText::PDF_TEXT_ENCODING :
Stream data is unencoded (ie, it is pure ascii).
- PdfToText::PDF_UNKNOWN_ENCODING :
The object data does not specify any encoding at all. It can happen on objects that do not have
a "stream" part.
- PdfToText::PDF_DCT_ENCODING :
a lossy filter based on the JPEG standard.
The following constants are defined but not yet implemented ; an exception will be thrown if they are
encountered somewhere in the PDF file :
- PDF_LZW_ENCODING :
a filter based on LZW Compression; it can use one of two groups of predictor functions for more
compact LZW compression : Predictor 2 from the TIFF 6.0 specification and predictors (filters)
from the PNG specification
- PDF_RLE_ENCODING :
a simple compression method for streams with repetitive data using the run-length encoding
algorithm and the image-specific filters.
PDF_CCITT_FAX_ENCODING :
a lossless bi-level (black/white) filter based on the Group 3 or Group 4 CCITT (ITU-T) fax
compression standard defined in ITU-T T.4 and T.6.
PDF_JBIG2_ENCODING :
a lossy or lossless bi-level (black/white) filter based on the JBIG2 standard, introduced in
PDF 1.4.
PDF_JPX_ENCODING :
a lossy or lossless filter based on the JPEG 2000 standard, introduced in PDF 1.5.
*-------------------------------------------------------------------------------------------------------------*/
protected function GetEncodingType ( $object_id, $object_data )
{
$status = preg_match ( '# / (?P (ASCIIHexDecode) | (AHx) | (ASCII85Decode) | (A85) | (FlateDecode) | (Fl) | (DCTDecode) | (DCT) | ' .
'(LZWDecode) | (LZW) | (RunLengthDecode) | (RL) | (CCITTFaxDecode) | (CCF) | (JBIG2Decode) | (JPXDecode) ) \b #imsx',
$object_data, $match ) ;
if ( ! $status )
return ( self::PDF_TEXT_ENCODING ) ;
switch ( strtolower ( $match [ 'encoding' ] ) )
{
case 'asciihexdecode' :
case 'ahx' : return ( self::PDF_ASCIIHEX_ENCODING ) ;
case 'ascii85decode' :
case 'a85' : return ( self::PDF_ASCII85_ENCODING ) ;
case 'flatedecode' :
case 'fl' : return ( self::PDF_FLATE_ENCODING ) ;
case 'dctdecode' :
case 'dct' : return ( self::PDF_DCT_ENCODING ) ;
case 'lzwdecode' :
case 'lzw' : return ( self::PDF_LZW_ENCODING ) ;
case 'ccittfaxdecode' :
case 'ccf' :
case 'runlengthdecode' :
case 'rl' :
case 'jbig2decode' :
case 'jpxdecode' :
if ( PdfToText::$DEBUG > 1 )
warning ( "Encoding type \"{$match [ 'encoding' ]}\" not yet implemented for pdf object #$object_id." ) ;
default : return ( self::PDF_UNKNOWN_ENCODING ) ;
}
}
/*--------------------------------------------------------------------------------------------------------------
NAME
GetObjectReferences - Gets object references from a specified construct.
PROTOTYPE
$status = $this -> GetObjectReferences ( $object_id, $object_data, $searched_string, &$object_ids ) ;
DESCRIPTION
Certain parameter specifications are followed by an object reference of the form :
x 0 R
but it can also be an array of references :
[x1 0 R x2 0 R ... xn 0 r]
Those kind of constructs can occur after parameters such as : /Pages, /Contents, /Kids...
This method extracts the object references found in such a construct.
PARAMETERS
$object_id (integer) -
Id of the object to be analyzed.
$object_data (string) -
Object contents.
$searched_string (string) -
String to be searched, that must be followed by an object or an array of object references.
This parameter can contain constructs used in regular expressions. Note however that the '#'
character must be escaped, since it is used as a delimiter in the regex that is applied on
object data.
$object_ids (array of integers) -
Returns on output the ids of the pdf object that have been found after the searched string.
RETURN VALUE
True if the searched string has been found and is followed by an object or array of object references,
false otherwise.
*-------------------------------------------------------------------------------------------------------------*/
protected function GetObjectReferences ( $object_id, $object_data, $searched_string, &$object_ids )
{
$status = true ;
$object_ids = array ( ) ;
if ( preg_match ( "#$searched_string \s* \\[ (?P [^\]]+ ) \\]#ix", $object_data, $match ) )
{
$object_list = $match [ 'objects' ] ;
if ( preg_match_all ( '/(?P