| 1 | typedef struct |
|---|
| 2 | { |
|---|
| 3 | UT_U32 lo; |
|---|
| 4 | UT_I32 hi; |
|---|
| 5 | } UT_I64; |
|---|
| 6 | |
|---|
| 7 | static void ut_Mul(UT_I32 multiplicand, UT_I32 multiplier, UT_I64* result) |
|---|
| 8 | { |
|---|
| 9 | UT_U32 lo1 = multiplicand & 0x0000FFFFU; |
|---|
| 10 | UT_U32 hi1 = multiplicand >> 16; |
|---|
| 11 | UT_U32 lo2 = multiplier & 0x0000FFFFU; |
|---|
| 12 | UT_U32 hi2 = multiplier >> 16; |
|---|
| 13 | UT_U32 lo = lo1 * lo2; |
|---|
| 14 | UT_U32 i1 = lo1 * hi2; |
|---|
| 15 | UT_U32 i2 = lo2 * hi1; |
|---|
| 16 | UT_U32 hi = hi1 * hi2; |
|---|
| 17 | UT_TRACE2("ut_Mul() multiplicand = %d", multiplicand); |
|---|
| 18 | UT_TRACE2(" multiplier = %d", multiplier); |
|---|
| 19 | UT_TRACE_TAB_INC(); |
|---|
| 20 | i1 += i2; |
|---|
| 21 | hi += (UT_U32)(i1 < i2) << 16; |
|---|
| 22 | hi += i1 >> 16; |
|---|
| 23 | i1 = i1 << 16; |
|---|
| 24 | lo += i1; |
|---|
| 25 | hi += (lo < i1); |
|---|
| 26 | result->hi = hi; |
|---|
| 27 | result->lo = lo; |
|---|
| 28 | UT_TRACE2(" result->hi = %d", result->hi); |
|---|
| 29 | UT_TRACE2(" result->lo = %d", result->lo); |
|---|
| 30 | } |
|---|
| 31 | |
|---|
| 32 | static UT_I32 ut_Div(UT_I64 dividend, UT_U32 divisor) |
|---|
| 33 | { |
|---|
| 34 | UT_U32 r = dividend.hi; |
|---|
| 35 | UT_U32 q = 0; |
|---|
| 36 | int i = 32; |
|---|
| 37 | if (r >= divisor) return 0x7FFFFFFFU; |
|---|
| 38 | UT_TRACE2("ut_Div() dividend.hi = %d", dividend.hi); |
|---|
| 39 | UT_TRACE2(" dividend.lo = %d", dividend.lo); |
|---|
| 40 | do |
|---|
| 41 | { |
|---|
| 42 | r <<= 1; |
|---|
| 43 | q <<= 1; |
|---|
| 44 | r |= dividend.lo >> 31; |
|---|
| 45 | if (r >= divisor) |
|---|
| 46 | { |
|---|
| 47 | r -= divisor; |
|---|
| 48 | q |= 1; |
|---|
| 49 | } |
|---|
| 50 | dividend.lo <<= 1; |
|---|
| 51 | } while (i--); |
|---|
| 52 | UT_TRACE2(" result = %d", q); |
|---|
| 53 | return q; |
|---|
| 54 | } |
|---|
| 55 | |
|---|
| 56 | static UT_I32 ut_MulDiv(UT_I32 multiplicand, UT_I32 multiplier, UT_I32 divisor) |
|---|
| 57 | { |
|---|
| 58 | UT_I32 s; |
|---|
| 59 | UT_TRACE2("ut_MulDiv() multiplicand = %d", multiplicand); |
|---|
| 60 | UT_TRACE2(" multiplier = %d", multiplier); |
|---|
| 61 | UT_TRACE2(" divisor = %d", divisor); |
|---|
| 62 | if (multiplier == divisor) |
|---|
| 63 | { |
|---|
| 64 | UT_TRACE2(" result = %d", multiplicand); |
|---|
| 65 | return multiplicand; |
|---|
| 66 | } |
|---|
| 67 | s = multiplicand; multiplicand = (multiplicand < 0) ? -multiplicand : multiplicand; |
|---|
| 68 | s ^= multiplier; multiplier = (multiplier < 0) ? -multiplier : multiplier; |
|---|
| 69 | s ^= divisor; divisor = (divisor < 0) ? -divisor : divisor; |
|---|
| 70 | if ((multiplicand <= 46340) && (multiplier <= 46340) && (divisor <= 176095)) |
|---|
| 71 | { |
|---|
| 72 | multiplicand = (multiplicand * multiplier + (divisor >> 1)) / divisor; |
|---|
| 73 | UT_TRACE2(" result = %d", (s < 0) ? -multiplicand : multiplicand); |
|---|
| 74 | return (s < 0) ? -multiplicand : multiplicand; |
|---|
| 75 | } |
|---|
| 76 | else |
|---|
| 77 | { |
|---|
| 78 | UT_I64 dividend; |
|---|
| 79 | ut_Mul(multiplicand, multiplier, ÷nd); |
|---|
| 80 | return ut_Div(dividend, divisor); |
|---|
| 81 | } |
|---|
| 82 | } |
|---|
| 83 | |
|---|
| 84 | static UT_FIXED ut_MulFixed(UT_FIXED multiplicand, UT_FIXED multiplier) |
|---|
| 85 | { |
|---|
| 86 | UT_I32 s; |
|---|
| 87 | UT_U32 ua, ub; |
|---|
| 88 | UT_TRACE2("ut_MulFixed() multiplicand = %d", multiplicand); |
|---|
| 89 | UT_TRACE2(" multiplier = %d", multiplier); |
|---|
| 90 | if (multiplier == 0x10000) |
|---|
| 91 | { |
|---|
| 92 | UT_TRACE2(" result = %d", multiplicand); |
|---|
| 93 | return multiplicand; |
|---|
| 94 | } |
|---|
| 95 | s = multiplicand; multiplicand = (multiplicand < 0) ? -multiplicand : multiplicand; |
|---|
| 96 | s ^= multiplier; multiplier = (multiplier < 0) ? -multiplier : multiplier; |
|---|
| 97 | ua = (UT_U32)multiplicand; |
|---|
| 98 | ub = (UT_U32)multiplier; |
|---|
| 99 | if ((ua <= 2048) && (ub <= 1048576)) |
|---|
| 100 | { |
|---|
| 101 | ua = (ua * ub + 0x8000) >> 16; |
|---|
| 102 | } |
|---|
| 103 | else |
|---|
| 104 | { |
|---|
| 105 | UT_U32 al = ua & 0xFFFF; |
|---|
| 106 | ua = (ua >> 16) * ub + al * (ub >> 16) + ((al * (ub & 0xFFFF) + 0x8000) >> 16); |
|---|
| 107 | } |
|---|
| 108 | UT_TRACE2(" result = %d", (s < 0) ? -(UT_FIXED)ua : (UT_FIXED)ua); |
|---|
| 109 | return (s < 0) ? -(UT_FIXED)ua : (UT_FIXED)ua; |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | static UT_FIXED ut_DivFixed(UT_FIXED dividend, UT_FIXED divisor) |
|---|
| 113 | { |
|---|
| 114 | UT_I32 s; |
|---|
| 115 | UT_U32 q; |
|---|
| 116 | UT_TRACE2("ut_DivFixed() dividend = %d", dividend); |
|---|
| 117 | UT_TRACE2(" divisor = %d", divisor); |
|---|
| 118 | s = dividend; dividend = (dividend < 0) ? -dividend : dividend; |
|---|
| 119 | s ^= divisor; divisor = (divisor < 0) ? -divisor : divisor; |
|---|
| 120 | if (dividend >> 16) |
|---|
| 121 | { |
|---|
| 122 | UT_I64 dividend64; |
|---|
| 123 | dividend64.hi = dividend >> 16; |
|---|
| 124 | dividend64.lo = dividend << 16; |
|---|
| 125 | q = ut_Div(dividend64, (UT_I32)divisor); |
|---|
| 126 | } |
|---|
| 127 | else |
|---|
| 128 | { |
|---|
| 129 | q = (UT_U32)((dividend << 16) + (divisor >> 1)) / (UT_U32)divisor; |
|---|
| 130 | } |
|---|
| 131 | UT_TRACE2(" result = %d", (s < 0) ? -(UT_FIXED)q : (UT_FIXED)q); |
|---|
| 132 | return (s < 0) ? -(UT_FIXED)q : (UT_FIXED)q; |
|---|
| 133 | } |
|---|
| 134 | |
|---|
| 135 | int ut_DecryptNum(UT_POINTER* w) |
|---|
| 136 | { |
|---|
| 137 | int num=0; |
|---|
| 138 | |
|---|
| 139 | if(w==NULL) { |
|---|
| 140 | printf("!!Error ut_DecryptNum w == NULL\n"); |
|---|
| 141 | return 0; |
|---|
| 142 | } |
|---|
| 143 | |
|---|
| 144 | num = *w->i8++; |
|---|
| 145 | if (num == -128) |
|---|
| 146 | { |
|---|
| 147 | num = (w->i8[0] << 8) | w->u8[1]; |
|---|
| 148 | w += 2; |
|---|
| 149 | } |
|---|
| 150 | else if (num >= 123) |
|---|
| 151 | { |
|---|
| 152 | num = ((num - 123) << 8) + (int)(*w->u8++) + 123; |
|---|
| 153 | } |
|---|
| 154 | else if (num <= -123) |
|---|
| 155 | { |
|---|
| 156 | num = ((num + 123) << 8) - (int)(*w->u8++) - 123; |
|---|
| 157 | } |
|---|
| 158 | UT_TRACE2("ut_DecryptNum() num = %d", num); |
|---|
| 159 | return num; |
|---|
| 160 | } |
|---|
| 161 | |
|---|
| 162 | #define _X_TOUCHED_BY_STEM_CONTROL 0x01 |
|---|
| 163 | #define _Y_TOUCHED_BY_STEM_CONTROL 0x02 |
|---|
| 164 | |
|---|
| 165 | static void ut_Shift(int p1, int p2, int p, UT_I32* original, UT_COORD* hinted) |
|---|
| 166 | { |
|---|
| 167 | int i; |
|---|
| 168 | UT_COORD d; |
|---|
| 169 | UT_TRACE2("ut_Shift() p1 = %d", p1); |
|---|
| 170 | UT_TRACE2(" p2 = %d", p2); |
|---|
| 171 | UT_TRACE2(" p = %d", p); |
|---|
| 172 | d = hinted[p] - original[p]; |
|---|
| 173 | UT_TRACE2(" d = %d", d); |
|---|
| 174 | for (i=p1; i<p; i++) |
|---|
| 175 | { |
|---|
| 176 | hinted[i] += d; |
|---|
| 177 | } |
|---|
| 178 | for (i=p+1; i<=p2; i++) |
|---|
| 179 | { |
|---|
| 180 | hinted[i] += d; |
|---|
| 181 | } |
|---|
| 182 | } |
|---|
| 183 | |
|---|
| 184 | static void itrp_IUP(UT_FONT_TASK* task, UT_I32* original, UT_COORD* hinted, UT_U8 touchedMask) |
|---|
| 185 | { |
|---|
| 186 | UT_U8* touched = task->workGlyph.touched; |
|---|
| 187 | UT_I32 *ref; |
|---|
| 188 | UT_I32 *stop; |
|---|
| 189 | UT_I32 *originalEnd; |
|---|
| 190 | UT_I32 refCoord1; |
|---|
| 191 | UT_I32 refCoord2; |
|---|
| 192 | UT_I32 refBase; |
|---|
| 193 | UT_I32 refDelta; |
|---|
| 194 | UT_I32 refDelta2; |
|---|
| 195 | UT_COORD *cur; |
|---|
| 196 | UT_COORD curBase; |
|---|
| 197 | UT_COORD curOffset; |
|---|
| 198 | UT_COORD curDelta; |
|---|
| 199 | UT_I32 pointIndex; |
|---|
| 200 | UT_I32 startPointIndex; |
|---|
| 201 | UT_I32 endPointIndex; |
|---|
| 202 | UT_I32 stopPointIndex; |
|---|
| 203 | UT_I32 refPointIndex1; |
|---|
| 204 | UT_I32 refPointIndex2; |
|---|
| 205 | UT_I32 pathIndex; |
|---|
| 206 | UT_I32 temp; |
|---|
| 207 | UT_FIXED ratio; |
|---|
| 208 | UT_TRACE2("itrp_IUP(touchedMask=%d)", touchedMask); |
|---|
| 209 | UT_TRACE_TAB_INC(); |
|---|
| 210 | for (pathIndex=0; pathIndex<task->workGlyph.nPath; pathIndex++) |
|---|
| 211 | { |
|---|
| 212 | startPointIndex = task->workGlyph.startPointIndex[pathIndex]; |
|---|
| 213 | endPointIndex = task->workGlyph.endPointIndex[pathIndex]; |
|---|
| 214 | originalEnd = &original[endPointIndex]; |
|---|
| 215 | pointIndex = startPointIndex; |
|---|
| 216 | while (!(touched[pointIndex] & touchedMask) && (pointIndex <= endPointIndex)) pointIndex++; |
|---|
| 217 | if (pointIndex <= endPointIndex) |
|---|
| 218 | { |
|---|
| 219 | stopPointIndex = pointIndex; |
|---|
| 220 | do |
|---|
| 221 | { |
|---|
| 222 | do |
|---|
| 223 | { |
|---|
| 224 | refPointIndex1 = pointIndex; |
|---|
| 225 | pointIndex++; |
|---|
| 226 | if (pointIndex > endPointIndex) pointIndex = startPointIndex; |
|---|
| 227 | } while ((touched[pointIndex] & touchedMask) && pointIndex != stopPointIndex); |
|---|
| 228 | if (pointIndex != stopPointIndex) |
|---|
| 229 | { |
|---|
| 230 | refPointIndex2 = pointIndex; |
|---|
| 231 | do |
|---|
| 232 | { |
|---|
| 233 | refPointIndex2++; |
|---|
| 234 | if (refPointIndex2 > endPointIndex) refPointIndex2 = startPointIndex; |
|---|
| 235 | } while (!(touched[refPointIndex2] & touchedMask)); |
|---|
| 236 | refCoord1 = original[refPointIndex1]; |
|---|
| 237 | refCoord2 = original[refPointIndex2]; |
|---|
| 238 | if (refCoord1 < refCoord2) |
|---|
| 239 | { |
|---|
| 240 | refBase = refCoord1; |
|---|
| 241 | refDelta = refCoord2 - refCoord1; |
|---|
| 242 | curBase = hinted[refPointIndex1]; |
|---|
| 243 | curOffset = hinted[refPointIndex2]; |
|---|
| 244 | } |
|---|
| 245 | else |
|---|
| 246 | { |
|---|
| 247 | refBase = refCoord2; |
|---|
| 248 | refDelta = refCoord1 - refCoord2; |
|---|
| 249 | curBase = hinted[refPointIndex2]; |
|---|
| 250 | curOffset = hinted[refPointIndex1]; |
|---|
| 251 | } |
|---|
| 252 | if (refDelta) |
|---|
| 253 | { |
|---|
| 254 | UT_TRACE2("refPointIndex1 = %d)", refPointIndex1); |
|---|
| 255 | UT_TRACE2("refPointIndex2 = %d)", refPointIndex2); |
|---|
| 256 | UT_TRACE2("refBase = %d)", refBase); |
|---|
| 257 | UT_TRACE2("refDelta = %d)", refDelta); |
|---|
| 258 | UT_TRACE2("curBase = %d)", curBase); |
|---|
| 259 | UT_TRACE2("curOffset = %d)", curOffset); |
|---|
| 260 | curDelta = curOffset - curBase; |
|---|
| 261 | if (refDelta < 32768 && curDelta < 32768) |
|---|
| 262 | { |
|---|
| 263 | ref = &original[pointIndex]; |
|---|
| 264 | cur = &hinted[pointIndex]; |
|---|
| 265 | refDelta2 = refDelta >> 1; |
|---|
| 266 | stop = &original[refPointIndex2]; |
|---|
| 267 | for (; ref<stop; ref++,cur++) |
|---|
| 268 | { |
|---|
| 269 | if ((*cur <= curBase) || (*cur >= curOffset)) continue; |
|---|
| 270 | UT_TRACE2(" old = %d)", *cur); |
|---|
| 271 | UT_TRACE2(" new = %d)", curBase + ((*ref-refBase) * curDelta + refDelta2) / refDelta); |
|---|
| 272 | *cur = curBase + ((*ref-refBase) * curDelta + refDelta2) / refDelta; |
|---|
| 273 | } |
|---|
| 274 | while (ref != stop) |
|---|
| 275 | { |
|---|
| 276 | if ((*cur > curBase) && (*cur < curOffset)) |
|---|
| 277 | { |
|---|
| 278 | UT_TRACE2(" old = %d)", *cur); |
|---|
| 279 | UT_TRACE2(" new = %d)", curBase + ((*ref-refBase) * curDelta + refDelta2) / refDelta); |
|---|
| 280 | *cur = curBase + ((*ref-refBase) * curDelta + refDelta2) / refDelta; |
|---|
| 281 | } |
|---|
| 282 | ref++; |
|---|
| 283 | cur++; |
|---|
| 284 | if (ref > originalEnd) |
|---|
| 285 | { |
|---|
| 286 | ref = &original[startPointIndex]; |
|---|
| 287 | cur = &hinted[startPointIndex]; |
|---|
| 288 | } |
|---|
| 289 | } |
|---|
| 290 | pointIndex = refPointIndex2; |
|---|
| 291 | } |
|---|
| 292 | else |
|---|
| 293 | { |
|---|
| 294 | ratio = ut_DivFixed(curDelta, refDelta); |
|---|
| 295 | while (pointIndex != refPointIndex2) |
|---|
| 296 | { |
|---|
| 297 | temp = hinted[pointIndex]; |
|---|
| 298 | if ((temp > curBase) && (temp < curOffset)) |
|---|
| 299 | { |
|---|
| 300 | temp = original[pointIndex]; |
|---|
| 301 | temp -= refBase; |
|---|
| 302 | temp = ut_MulFixed(temp, ratio); |
|---|
| 303 | UT_TRACE2(" old = %d)", hinted[pointIndex]); |
|---|
| 304 | UT_TRACE2(" new = %d)", temp + curBase); |
|---|
| 305 | hinted[pointIndex] = temp + curBase; |
|---|
| 306 | } |
|---|
| 307 | if (pointIndex < endPointIndex) pointIndex++; |
|---|
| 308 | else pointIndex = startPointIndex; |
|---|
| 309 | } |
|---|
| 310 | } |
|---|
| 311 | } |
|---|
| 312 | else |
|---|
| 313 | { |
|---|
| 314 | while (pointIndex != refPointIndex2) |
|---|
| 315 | { |
|---|
| 316 | if (pointIndex < endPointIndex) pointIndex++; |
|---|
| 317 | else pointIndex = startPointIndex; |
|---|
| 318 | } |
|---|
| 319 | } |
|---|
| 320 | } |
|---|
| 321 | } while (pointIndex != stopPointIndex); |
|---|
| 322 | } |
|---|
| 323 | } |
|---|
| 324 | UT_TRACE_TAB_DEC(); |
|---|
| 325 | } |
|---|
| 326 | |
|---|
| 327 | #define ut_ScaleCoord(emSize, coord, gridFitSize) (((coord) << _UT_PIXEL_SHIFT) * (gridFitSize) / emSize) |
|---|
| 328 | |
|---|
| 329 | static UT_COORD itrp_RTG(int coord) |
|---|
| 330 | { |
|---|
| 331 | UT_COORD value = coord; |
|---|
| 332 | if (value >= 0) |
|---|
| 333 | { |
|---|
| 334 | value += _UT_HALF_PIXEL; |
|---|
| 335 | value &= ~(_UT_ONE_PIXEL - 1); |
|---|
| 336 | } |
|---|
| 337 | else |
|---|
| 338 | { |
|---|
| 339 | value = -value; |
|---|
| 340 | value += _UT_HALF_PIXEL; |
|---|
| 341 | value &= ~(_UT_ONE_PIXEL - 1); |
|---|
| 342 | value = -value; |
|---|
| 343 | } |
|---|
| 344 | if (((coord ^ value)) < 0 && coord) value = 0; |
|---|
| 345 | UT_TRACE2("itrp_RTG() coord = %d", coord); |
|---|
| 346 | UT_TRACE2(" value = %d", value); |
|---|
| 347 | return value; |
|---|
| 348 | } |
|---|
| 349 | |
|---|
| 350 | static UT_COORD itrp_RTG_Gray(US_RASTER_DIR* dir, int coord) |
|---|
| 351 | { |
|---|
| 352 | UT_COORD value = coord; |
|---|
| 353 | if (value >= 0) |
|---|
| 354 | { |
|---|
| 355 | value += dir->graySubHalf; |
|---|
| 356 | value &= ~dir->graySubPix; |
|---|
| 357 | } |
|---|
| 358 | else |
|---|
| 359 | { |
|---|
| 360 | value = -value; |
|---|
| 361 | value += dir->graySubHalf; |
|---|
| 362 | value &= ~dir->graySubPix; |
|---|
| 363 | value = -value; |
|---|
| 364 | } |
|---|
| 365 | if (((coord ^ value)) < 0 && coord) value = 0; |
|---|
| 366 | UT_TRACE2("itrp_RTG_Gray() coord = %d", coord); |
|---|
| 367 | UT_TRACE2(" value = %d", value); |
|---|
| 368 | return value; |
|---|
| 369 | } |
|---|
| 370 | |
|---|
| 371 | static void itrp_STEM_Check(UT_FONT_TASK* task, US_RASTER_DIR* dir, UT_SW* sw, UT_COORD original_b, UT_COORD original_o, UT_COORD r) |
|---|
| 372 | { |
|---|
| 373 | int i; |
|---|
| 374 | UT_COORD hinted_b; |
|---|
| 375 | UT_COORD hinted_o; |
|---|
| 376 | UT_TRACE2("itrp_STEM_Check(touchedMask=%d)", dir->touchedMask); |
|---|
| 377 | UT_TRACE_TAB_INC(); |
|---|
| 378 | UT_TRACE2("original_b = %d", original_b); |
|---|
| 379 | UT_TRACE2("original_o = %d", original_o); |
|---|
| 380 | UT_TRACE2("r = %d", r); |
|---|
| 381 | if (dir->isGray) |
|---|
| 382 | { |
|---|
| 383 | hinted_b = itrp_RTG_Gray(dir, original_b + r); |
|---|
| 384 | hinted_o = itrp_RTG_Gray(dir, original_o + r); |
|---|
| 385 | if (original_b < original_o) |
|---|
| 386 | { |
|---|
| 387 | UT_COORD d = original_o - original_b; |
|---|
| 388 | if (sw) |
|---|
| 389 | { |
|---|
| 390 | int ci64 = ut_SWAP_U16(sw->ci64); |
|---|
| 391 | int depth = ut_SWAP_U16(sw->depth); |
|---|
| 392 | depth = ut_ScaleCoord(task->emSize, depth, dir->gridFitSize); |
|---|
| 393 | if ((d > (depth-ci64)) && (d < (depth+ci64))) d = depth; |
|---|
| 394 | } |
|---|
| 395 | d = itrp_RTG(d); |
|---|
| 396 | if (!d) d = dir->graySubPix + 1; |
|---|
| 397 | hinted_o = hinted_b + d; |
|---|
| 398 | } |
|---|
| 399 | else |
|---|
| 400 | { |
|---|
| 401 | UT_COORD d = original_b - original_o; |
|---|
| 402 | if (sw) |
|---|
| 403 | { |
|---|
| 404 | int ci64 = ut_SWAP_U16(sw->ci64); |
|---|
| 405 | int depth = ut_SWAP_U16(sw->depth); |
|---|
| 406 | depth = ut_ScaleCoord(task->emSize, depth, dir->gridFitSize); |
|---|
| 407 | if ((d > (depth-ci64)) && (d < (depth+ci64))) d = depth; |
|---|
| 408 | } |
|---|
| 409 | d = itrp_RTG(d); |
|---|
| 410 | if (!d) d = dir->graySubPix + 1; |
|---|
| 411 | hinted_o = hinted_b - d; |
|---|
| 412 | } |
|---|
| 413 | } |
|---|
| 414 | else |
|---|
| 415 | { |
|---|
| 416 | hinted_b = itrp_RTG(original_b + r); |
|---|
| 417 | hinted_o = itrp_RTG(original_o + r); |
|---|
| 418 | if (original_b < original_o) |
|---|
| 419 | { |
|---|
| 420 | UT_COORD d = original_o - original_b; |
|---|
| 421 | if (sw) |
|---|
| 422 | { |
|---|
| 423 | int ci64 = ut_SWAP_U16(sw->ci64); |
|---|
| 424 | int depth = ut_SWAP_U16(sw->depth); |
|---|
| 425 | depth = ut_ScaleCoord(task->emSize, depth, dir->gridFitSize); |
|---|
| 426 | if ((d > (depth-ci64)) && (d < (depth+ci64))) d = depth; |
|---|
| 427 | } |
|---|
| 428 | d = itrp_RTG(d); |
|---|
| 429 | if (!d) d = _UT_ONE_PIXEL; |
|---|
| 430 | hinted_o = hinted_b + d; |
|---|
| 431 | } |
|---|
| 432 | else |
|---|
| 433 | { |
|---|
| 434 | UT_COORD d = original_b - original_o; |
|---|
| 435 | if (sw) |
|---|
| 436 | { |
|---|
| 437 | int ci64 = ut_SWAP_U16(sw->ci64); |
|---|
| 438 | int depth = ut_SWAP_U16(sw->depth); |
|---|
| 439 | depth = ut_ScaleCoord(task->emSize, depth, dir->gridFitSize); |
|---|
| 440 | if ((d > (depth-ci64)) && (d < (depth+ci64))) d = depth; |
|---|
| 441 | } |
|---|
| 442 | d = itrp_RTG(d); |
|---|
| 443 | if (!d) d = _UT_ONE_PIXEL; |
|---|
| 444 | hinted_o = hinted_b - d; |
|---|
| 445 | } |
|---|
| 446 | } |
|---|
| 447 | UT_TRACE2("hinted_b = %d", hinted_b); |
|---|
| 448 | UT_TRACE2("hinted_o = %d", hinted_o); |
|---|
| 449 | for (i=0; i<task->workGlyph.nPoint; i++) |
|---|
| 450 | { |
|---|
| 451 | if (dir->original[i] == original_b) |
|---|
| 452 | { |
|---|
| 453 | UT_TRACE2("base match[%d]", i); |
|---|
| 454 | UT_TRACE2(" old = %d", dir->hinted[i]); |
|---|
| 455 | UT_TRACE2(" new = %d", hinted_b); |
|---|
| 456 | dir->hinted[i] = hinted_b; |
|---|
| 457 | task->workGlyph.touched[i] |= dir->touchedMask; |
|---|
| 458 | } |
|---|
| 459 | else if (dir->original[i] == original_o) |
|---|
| 460 | { |
|---|
| 461 | UT_TRACE2("offset match[%d]", i); |
|---|
| 462 | UT_TRACE2(" old = %d", dir->hinted[i]); |
|---|
| 463 | UT_TRACE2(" new = %d", hinted_o); |
|---|
| 464 | dir->hinted[i] = hinted_o; |
|---|
| 465 | task->workGlyph.touched[i] |= dir->touchedMask; |
|---|
| 466 | } |
|---|
| 467 | } |
|---|
| 468 | UT_TRACE_TAB_DEC(); |
|---|
| 469 | } |
|---|
| 470 | |
|---|
| 471 | static void itrp_STEM(UT_FONT_TASK* task, US_RASTER_DIR* dir, UT_POINTER* w, UT_SW* sw, int offset) |
|---|
| 472 | { |
|---|
| 473 | int b, o; |
|---|
| 474 | UT_COORD original_b; |
|---|
| 475 | UT_COORD original_o; |
|---|
| 476 | UT_TRACE1("itrp_STEM()"); |
|---|
| 477 | UT_TRACE_TAB_INC(); |
|---|
| 478 | b = ut_DecryptNum(w) + offset; |
|---|
| 479 | o = ut_DecryptNum(w) + b; |
|---|
| 480 | original_b = ut_ScaleCoord(task->emSize, b, dir->gridFitSize); |
|---|
| 481 | original_o = ut_ScaleCoord(task->emSize, o, dir->gridFitSize); |
|---|
| 482 | itrp_STEM_Check(task, dir, sw, original_b, original_o, 0); |
|---|
| 483 | UT_TRACE_TAB_DEC(); |
|---|
| 484 | } |
|---|
| 485 | |
|---|
| 486 | static void itrp_SNAP_STEM(UT_FONT_TASK* task, US_RASTER_DIR* dir, UT_POINTER* w, UT_SW* sw, int offset) |
|---|
| 487 | { |
|---|
| 488 | int b, o, r; |
|---|
| 489 | UT_COORD original_b; |
|---|
| 490 | UT_COORD original_o; |
|---|
| 491 | UT_TRACE1("itrp_SNAP_STEM()"); |
|---|
| 492 | UT_TRACE_TAB_INC(); |
|---|
| 493 | b = ut_DecryptNum(w) + offset; |
|---|
| 494 | o = ut_DecryptNum(w) + b; |
|---|
| 495 | r = ut_DecryptNum(w); |
|---|
| 496 | original_b = ut_ScaleCoord(task->emSize, b, dir->gridFitSize); |
|---|
| 497 | original_o = ut_ScaleCoord(task->emSize, o, dir->gridFitSize); |
|---|
| 498 | r = ut_ScaleCoord(task->emSize, r, dir->gridFitSize); |
|---|
| 499 | if (r > 0) |
|---|
| 500 | { |
|---|
| 501 | if (r > _UT_CVCI) r = 0; |
|---|
| 502 | } |
|---|
| 503 | else |
|---|
| 504 | { |
|---|
| 505 | if (-r > _UT_CVCI) r = 0; |
|---|
| 506 | } |
|---|
| 507 | r = 0; |
|---|
| 508 | itrp_STEM_Check(task, dir, sw, original_b, original_o, r); |
|---|
| 509 | UT_TRACE_TAB_DEC(); |
|---|
| 510 | } |
|---|
| 511 | |
|---|
| 512 | static void itrp_POINT(UT_FONT_TASK* task, US_RASTER_DIR* dir, UT_POINTER* w) |
|---|
| 513 | { |
|---|
| 514 | int i, b; |
|---|
| 515 | UT_COORD original_b, hinted_b; |
|---|
| 516 | UT_TRACE1("itrp_POINT()"); |
|---|
| 517 | UT_TRACE_TAB_INC(); |
|---|
| 518 | b = ut_DecryptNum(w); |
|---|
| 519 | original_b = ut_ScaleCoord(task->emSize, dir->original[b], dir->gridFitSize); |
|---|
| 520 | if (dir->isGray) |
|---|
| 521 | { |
|---|
| 522 | hinted_b = itrp_RTG_Gray(dir, original_b); |
|---|
| 523 | } |
|---|
| 524 | else |
|---|
| 525 | { |
|---|
| 526 | hinted_b = itrp_RTG(original_b); |
|---|
| 527 | } |
|---|
| 528 | for (i=0; i<task->workGlyph.nPoint; i++) |
|---|
| 529 | { |
|---|
| 530 | if (dir->original[i] == original_b) |
|---|
| 531 | { |
|---|
| 532 | dir->hinted[i] = hinted_b; |
|---|
| 533 | task->workGlyph.touched[i] |= dir->touchedMask; |
|---|
| 534 | } |
|---|
| 535 | } |
|---|
| 536 | UT_TRACE_TAB_DEC(); |
|---|
| 537 | } |
|---|
| 538 | |
|---|
| 539 | static void itrp_SNAP_POINT(UT_FONT_TASK* task, US_RASTER_DIR* dir, UT_POINTER* w) |
|---|
| 540 | { |
|---|
| 541 | int i, b, r; |
|---|
| 542 | UT_COORD original_b, hinted_b; |
|---|
| 543 | UT_TRACE1("itrp_SNAP_POINT()"); |
|---|
| 544 | UT_TRACE_TAB_INC(); |
|---|
| 545 | b = ut_DecryptNum(w); |
|---|
| 546 | r = ut_DecryptNum(w); |
|---|
| 547 | original_b = ut_ScaleCoord(task->emSize, dir->original[b], dir->gridFitSize); |
|---|
| 548 | r = ut_ScaleCoord(task->emSize, r, dir->gridFitSize); |
|---|
| 549 | if (r > 0) |
|---|
| 550 | { |
|---|
| 551 | if (r > _UT_CVCI) r = 0; |
|---|
| 552 | } |
|---|
| 553 | else |
|---|
| 554 | { |
|---|
| 555 | if (-r > _UT_CVCI) r = 0; |
|---|
| 556 | } |
|---|
| 557 | if (dir->isGray) |
|---|
| 558 | { |
|---|
| 559 | hinted_b = itrp_RTG_Gray(dir, original_b + r); |
|---|
| 560 | } |
|---|
| 561 | else |
|---|
| 562 | { |
|---|
| 563 | hinted_b = itrp_RTG(original_b + r); |
|---|
| 564 | } |
|---|
| 565 | for (i=0; i<task->workGlyph.nPoint; i++) |
|---|
| 566 | { |
|---|
| 567 | if (dir->original[i] == original_b) |
|---|
| 568 | { |
|---|
| 569 | dir->hinted[i] = hinted_b; |
|---|
| 570 | task->workGlyph.touched[i] |= dir->touchedMask; |
|---|
| 571 | } |
|---|
| 572 | } |
|---|
| 573 | UT_TRACE_TAB_DEC(); |
|---|
| 574 | } |
|---|
| 575 | |
|---|
| 576 | #define ut_IsRootGlyphNull(task) !task->rootGlyph.nPoint |
|---|
| 577 | #define ut_IsWorkGlyphNull(task) !task->workGlyph.nPoint |
|---|
| 578 | #define ut_NewPath(task) task->workGlyph.startPointIndex[task->workGlyph.nPath] = task->workGlyph.nPoint |
|---|
| 579 | #define ut_EndPath(task) task->workGlyph.endPointIndex[task->workGlyph.nPath++] = task->workGlyph.nPoint-1 |
|---|
| 580 | |
|---|
| 581 | static void ut_NewGlyph(UT_FONT_TASK* task) |
|---|
| 582 | { |
|---|
| 583 | UT_TRACE1("ut_NewGlyph()"); |
|---|
| 584 | task->workGlyph.startPointIndex += task->workGlyph.nPath; |
|---|
| 585 | task->workGlyph.endPointIndex += task->workGlyph.nPath; |
|---|
| 586 | task->workGlyph.x += task->workGlyph.nPoint; |
|---|
| 587 | task->workGlyph.y += task->workGlyph.nPoint; |
|---|
| 588 | task->workGlyph.on += task->workGlyph.nPoint; |
|---|
| 589 | task->workGlyph.touched += task->workGlyph.nPoint; |
|---|
| 590 | task->workGlyph.ox += task->workGlyph.nPoint; |
|---|
| 591 | task->workGlyph.oy += task->workGlyph.nPoint; |
|---|
| 592 | task->workGlyph.nPath = 0; |
|---|
| 593 | task->workGlyph.nPoint = 0; |
|---|
| 594 | } |
|---|
| 595 | |
|---|
| 596 | static void ut_EndGlyph(UT_FONT_TASK* task) |
|---|
| 597 | { |
|---|
| 598 | int i; |
|---|
| 599 | UT_TRACE1("ut_EndGlyph()"); |
|---|
| 600 | for (i=0; i<task->workGlyph.nPath; i++) |
|---|
| 601 | { |
|---|
| 602 | task->workGlyph.startPointIndex[i] += task->rootGlyph.nPoint; |
|---|
| 603 | task->workGlyph.endPointIndex[i] += task->rootGlyph.nPoint; |
|---|
| 604 | } |
|---|
| 605 | task->rootGlyph.nPath += task->workGlyph.nPath; |
|---|
| 606 | task->rootGlyph.nPoint += task->workGlyph.nPoint; |
|---|
| 607 | } |
|---|
| 608 | |
|---|
| 609 | static void ut_AddPoint(UT_FONT_TASK* task, int x, int y, int on) |
|---|
| 610 | { |
|---|
| 611 | UT_TRACE2("ut_AddPoint(%d)", task->workGlyph.nPoint); |
|---|
| 612 | UT_TRACE2(" x = %d", x); |
|---|
| 613 | UT_TRACE2(" y = %d", y); |
|---|
| 614 | UT_TRACE2(" on = %d", on); |
|---|
| 615 | task->workGlyph.x[task->workGlyph.nPoint] = task->workGlyph.ox[task->workGlyph.nPoint] = ut_ScaleCoord(task->emSize, x, task->xDir.gridFitSize); |
|---|
| 616 | task->workGlyph.y[task->workGlyph.nPoint] = task->workGlyph.oy[task->workGlyph.nPoint] = ut_ScaleCoord(task->emSize, y, task->yDir.gridFitSize); |
|---|
| 617 | task->workGlyph.on[task->workGlyph.nPoint] = on; |
|---|
| 618 | task->workGlyph.touched[task->workGlyph.nPoint] = 0; |
|---|
| 619 | UT_TRACE2(" scaled_x = %d", task->workGlyph.ox[task->workGlyph.nPoint]); |
|---|
| 620 | UT_TRACE2(" scaled_y = %d", task->workGlyph.oy[task->workGlyph.nPoint]); |
|---|
| 621 | task->workGlyph.nPoint++; |
|---|
| 622 | } |
|---|
| 623 | |
|---|
| 624 | static UT_BOOL ut_InterpreteSimpleGlyph(UT_FONT_TASK* task, UT_CMAP* cmap, UT_POINTER w, UT_BOOL applyHint, int xOffset) |
|---|
| 625 | { |
|---|
| 626 | UT_U8 f; |
|---|
| 627 | int i, count; |
|---|
| 628 | int x = xOffset; |
|---|
| 629 | int y = 0; |
|---|
| 630 | UT_BOOL first = _UT_TRUE; |
|---|
| 631 | UT_U8* op; |
|---|
| 632 | UT_TRACE1("ut_InterpreteSimpleGlyph()"); |
|---|
| 633 | UT_TRACE_TAB_INC(); |
|---|
| 634 | count = ut_DecryptNum(&w); |
|---|
| 635 | op = w.u8; |
|---|
| 636 | w.p += (count + 1) >> 1; |
|---|
| 637 | ut_NewGlyph(task); |
|---|
| 638 | for (i=0;;) |
|---|
| 639 | { |
|---|
| 640 | f = *op >> 4; |
|---|
| 641 | if (f & _UT_POINT_MASK_HAS_X) |
|---|
| 642 | { |
|---|
| 643 | x += ut_DecryptNum(&w); |
|---|
| 644 | } |
|---|
| 645 | if (f & _UT_POINT_MASK_HAS_Y) |
|---|
| 646 | { |
|---|
| 647 | y += ut_DecryptNum(&w); |
|---|
| 648 | } |
|---|
| 649 | if (f & _UT_POINT_MASK_IS_START) |
|---|
| 650 | { |
|---|
| 651 | if (first) first = _UT_FALSE; |
|---|
| 652 | else ut_EndPath(task); |
|---|
| 653 | ut_NewPath(task); |
|---|
| 654 | } |
|---|
| 655 | ut_AddPoint(task, x, y, f & _UT_POINT_MASK_IS_ON); |
|---|
| 656 | i++; if (i == count) break; |
|---|
| 657 | f = *op++ & 15; |
|---|
| 658 | if (f & _UT_POINT_MASK_HAS_X) |
|---|
| 659 | { |
|---|
| 660 | x += ut_DecryptNum(&w); |
|---|
| 661 | } |
|---|
| 662 | if (f & _UT_POINT_MASK_HAS_Y) |
|---|
| 663 | { |
|---|
| 664 | y += ut_DecryptNum(&w); |
|---|
| 665 | } |
|---|
| 666 | if (f & _UT_POINT_MASK_IS_START) |
|---|
| 667 | { |
|---|
| 668 | if (first) first = _UT_FALSE; |
|---|
| 669 | else ut_EndPath(task); |
|---|
| 670 | ut_NewPath(task); |
|---|
| 671 | } |
|---|
| 672 | ut_AddPoint(task, x, y, f & _UT_POINT_MASK_IS_ON); |
|---|
| 673 | i++; if (i == count) break; |
|---|
| 674 | } |
|---|
| 675 | ut_EndPath(task); |
|---|
| 676 | if (!ut_IsWorkGlyphNull(task)) |
|---|
| 677 | { |
|---|
| 678 | if (applyHint) |
|---|
| 679 | { |
|---|
| 680 | US_RASTER_DIR* xDir = &task->xDir; |
|---|
| 681 | US_RASTER_DIR* yDir = &task->yDir; |
|---|
| 682 | int vTouched = 0; |
|---|
| 683 | int hTouched = 0; |
|---|
| 684 | UT_SW* sw = 0; |
|---|
| 685 | xDir->touchedMask = _X_TOUCHED_BY_STEM_CONTROL; |
|---|
| 686 | yDir->touchedMask = _X_TOUCHED_BY_STEM_CONTROL; |
|---|
| 687 | xDir->original = task->workGlyph.ox; |
|---|
| 688 | yDir->original = task->workGlyph.oy; |
|---|
| 689 | xDir->hinted = task->workGlyph.x; |
|---|
| 690 | yDir->hinted = task->workGlyph.y; |
|---|
| 691 | for (;;) |
|---|
| 692 | { |
|---|
| 693 | f = *w.u8++; |
|---|
| 694 | if (f == _UT_HINT_END) break; |
|---|
| 695 | switch (f) |
|---|
| 696 | { |
|---|
| 697 | case _UT_HINT_V_STEM: |
|---|
| 698 | vTouched = 1; |
|---|
| 699 | itrp_STEM(task, xDir, &w, 0, xOffset); |
|---|
| 700 | break; |
|---|
| 701 | case _UT_HINT_H_STEM: |
|---|
| 702 | hTouched = 1; |
|---|
| 703 | itrp_STEM(task, yDir, &w, 0, 0); |
|---|
| 704 | break; |
|---|
| 705 | case _UT_HINT_V_SNAP_STEM: |
|---|
| 706 | vTouched = 1; |
|---|
| 707 | itrp_SNAP_STEM(task, xDir, &w, 0, xOffset); |
|---|
| 708 | break; |
|---|
| 709 | case _UT_HINT_H_SNAP_STEM: |
|---|
| 710 | hTouched = 1; |
|---|
| 711 | itrp_SNAP_STEM(task, yDir, &w, 0, 0); |
|---|
| 712 | break; |
|---|
| 713 | case _UT_HINT_V_POINT: |
|---|
| 714 | vTouched = 1; |
|---|
| 715 | itrp_POINT(task, xDir, &w); |
|---|
| 716 | break; |
|---|
| 717 | case _UT_HINT_H_POINT: |
|---|
| 718 | hTouched = 1; |
|---|
| 719 | itrp_POINT(task, yDir, &w); |
|---|
| 720 | break; |
|---|
| 721 | case _UT_HINT_V_SNAP_POINT: |
|---|
| 722 | vTouched = 1; |
|---|
| 723 | itrp_SNAP_POINT(task, xDir, &w); |
|---|
| 724 | break; |
|---|
| 725 | case _UT_HINT_H_SNAP_POINT: |
|---|
| 726 | hTouched = 1; |
|---|
| 727 | itrp_SNAP_POINT(task, yDir, &w); |
|---|
| 728 | break; |
|---|
| 729 | case _UT_HINT_V_SW_STEM: |
|---|
| 730 | vTouched = 1; |
|---|
| 731 | itrp_STEM(task, xDir, &w, sw, xOffset); |
|---|
| 732 | break; |
|---|
| 733 | case _UT_HINT_H_SW_STEM: |
|---|
| 734 | hTouched = 1; |
|---|
| 735 | itrp_STEM(task, yDir, &w, sw, 0); |
|---|
| 736 | break; |
|---|
| 737 | case _UT_HINT_V_SW_SNAP_STEM: |
|---|
| 738 | vTouched = 1; |
|---|
| 739 | itrp_SNAP_STEM(task, xDir, &w, sw, xOffset); |
|---|
| 740 | break; |
|---|
| 741 | case _UT_HINT_H_SW_SNAP_STEM: |
|---|
| 742 | hTouched = 1; |
|---|
| 743 | itrp_SNAP_STEM(task, yDir, &w, sw, 0); |
|---|
| 744 | break; |
|---|
| 745 | case _UT_HINT_SSW: |
|---|
| 746 | i = ut_DecryptNum(&w); |
|---|
| 747 | if (i) sw = ut_SW(cmap, i); |
|---|
| 748 | else sw = 0; |
|---|
| 749 | break; |
|---|
| 750 | } |
|---|
| 751 | } |
|---|
| 752 | if (vTouched) itrp_IUP(task, task->workGlyph.ox, task->workGlyph.x, _X_TOUCHED_BY_STEM_CONTROL); |
|---|
| 753 | if (hTouched) itrp_IUP(task, task->workGlyph.oy, task->workGlyph.y, _Y_TOUCHED_BY_STEM_CONTROL); |
|---|
| 754 | } |
|---|
| 755 | ut_EndGlyph(task); |
|---|
| 756 | } |
|---|
| 757 | UT_TRACE_TAB_DEC(); |
|---|
| 758 | return _UT_TRUE; |
|---|
| 759 | } |
|---|
| 760 | |
|---|
| 761 | static UT_BOOL ut_InterpreteGlyph(UT_FC* fc) |
|---|
| 762 | { |
|---|
| 763 | int i = fc->glyph->count - 1; |
|---|
| 764 | UT_TRACE1("ut_InterpreteGlyph()"); |
|---|
| 765 | UT_TRACE_TAB_INC(); |
|---|
| 766 | for (; i>=0; i--) |
|---|
| 767 | { |
|---|
| 768 | if (!ut_InterpreteSimpleGlyph(fc->task, fc->glyph->cmap, fc->glyph->data[i].p, !fc->preventHint, fc->glyph->data[i].xOffset)) return _UT_FALSE; |
|---|
| 769 | } |
|---|
| 770 | if (fc->task->emulItalic) |
|---|
| 771 | { |
|---|
| 772 | int i; |
|---|
| 773 | for (i=0; i<fc->task->rootGlyph.nPoint; i++) |
|---|
| 774 | { |
|---|
| 775 | fc->task->rootGlyph.x[i] += ut_ItalicY(fc->task->rootGlyph.y[i]); |
|---|
| 776 | } |
|---|
| 777 | fc->task->emulItalic = 0; |
|---|
| 778 | } |
|---|
| 779 | UT_TRACE_TAB_DEC(); |
|---|
| 780 | return _UT_TRUE; |
|---|
| 781 | } |
|---|