| 1 | //#include <string.h> |
|---|
| 2 | #include "utfStruct.h" |
|---|
| 3 | #include "_utfDebugOn.hxx" |
|---|
| 4 | |
|---|
| 5 | //#define _UT_USE_DROPOUT_COLTROL |
|---|
| 6 | |
|---|
| 7 | /***************************************************************************/ |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | #define ut_SetPixel(task, x, y) task->image[(y)*task->i_bSize+((x)>>5)] |= (0x80000000>>((x)&0x1f)) |
|---|
| 11 | |
|---|
| 12 | void ut_SetPixel2(UT_FONT_TASK* task, int x, int y) |
|---|
| 13 | { |
|---|
| 14 | int i; |
|---|
| 15 | UT_U32* p = task->image + y*task->i_bSize + (x >> 5); |
|---|
| 16 | UT_U32* m = task->strokeMask->bitmap; |
|---|
| 17 | int shift = x & 0x1f; |
|---|
| 18 | for (i=task->strokeMask->size; i; i--) |
|---|
| 19 | { |
|---|
| 20 | UT_U32 mm = *m << (31 - shift); |
|---|
| 21 | *p |= *m >> shift; |
|---|
| 22 | if (mm) p[1] |= mm; |
|---|
| 23 | m++; |
|---|
| 24 | p += task->i_bSize; |
|---|
| 25 | } |
|---|
| 26 | } |
|---|
| 27 | |
|---|
| 28 | #include "_utMath.cxx" |
|---|
| 29 | |
|---|
| 30 | UT_STATIC_API void itrp_STROKE(UT_FONT_TASK* task, US_RASTER_DIR* dir, UT_POINTER* w, int offset) |
|---|
| 31 | { |
|---|
| 32 | if (dir->isGray) |
|---|
| 33 | { |
|---|
| 34 | int i; |
|---|
| 35 | for (i=0; i<task->workGlyph.nPoint; i++) |
|---|
| 36 | { |
|---|
| 37 | dir->hinted[i] = itrp_RTG_Gray(dir, dir->hinted[i]); |
|---|
| 38 | task->workGlyph.touched[i] |= dir->touchedMask; |
|---|
| 39 | } |
|---|
| 40 | } |
|---|
| 41 | } |
|---|
| 42 | |
|---|
| 43 | UT_STATIC_API UT_BOOL ut_InterpreteSimpleGlyph(UT_FONT_TASK* task, UT_CMAP* cmap, UT_POINTER w, UT_BOOL applyHint, int xOffset) |
|---|
| 44 | { |
|---|
| 45 | UT_U8 f; |
|---|
| 46 | int i, count; |
|---|
| 47 | int x = xOffset; |
|---|
| 48 | int y = 0; |
|---|
| 49 | UT_BOOL first = _UT_TRUE; |
|---|
| 50 | UT_U8* op; |
|---|
| 51 | UT_TRACE1("ut_InterpreteSimpleGlyph()"); |
|---|
| 52 | UT_TRACE_TAB_INC(); |
|---|
| 53 | count = ut_DecryptNum(&w); |
|---|
| 54 | op = w.u8; |
|---|
| 55 | w.p += (count + 1) >> 1; |
|---|
| 56 | ut_NewGlyph(task); |
|---|
| 57 | for (i=0;;) |
|---|
| 58 | { |
|---|
| 59 | f = *op >> 4; |
|---|
| 60 | if (f & _UT_POINT_MASK_HAS_X) |
|---|
| 61 | { |
|---|
| 62 | x += ut_DecryptNum(&w); |
|---|
| 63 | } |
|---|
| 64 | if (f & _UT_POINT_MASK_HAS_Y) |
|---|
| 65 | { |
|---|
| 66 | y += ut_DecryptNum(&w); |
|---|
| 67 | } |
|---|
| 68 | if (f & _UT_POINT_MASK_IS_START) |
|---|
| 69 | { |
|---|
| 70 | if (first) first = _UT_FALSE; |
|---|
| 71 | else ut_EndPath(task); |
|---|
| 72 | ut_NewPath(task); |
|---|
| 73 | } |
|---|
| 74 | ut_AddPoint(task, x, y, f & _UT_POINT_MASK_IS_ON); |
|---|
| 75 | i++; if (i == count) break; |
|---|
| 76 | f = *op++ & 15; |
|---|
| 77 | if (f & _UT_POINT_MASK_HAS_X) |
|---|
| 78 | { |
|---|
| 79 | x += ut_DecryptNum(&w); |
|---|
| 80 | } |
|---|
| 81 | if (f & _UT_POINT_MASK_HAS_Y) |
|---|
| 82 | { |
|---|
| 83 | y += ut_DecryptNum(&w); |
|---|
| 84 | } |
|---|
| 85 | if (f & _UT_POINT_MASK_IS_START) |
|---|
| 86 | { |
|---|
| 87 | if (first) first = _UT_FALSE; |
|---|
| 88 | else ut_EndPath(task); |
|---|
| 89 | ut_NewPath(task); |
|---|
| 90 | } |
|---|
| 91 | ut_AddPoint(task, x, y, f & _UT_POINT_MASK_IS_ON); |
|---|
| 92 | i++; if (i == count) break; |
|---|
| 93 | } |
|---|
| 94 | ut_EndPath(task); |
|---|
| 95 | if (!ut_IsWorkGlyphNull(task)) |
|---|
| 96 | { |
|---|
| 97 | if (cmap->isStroke) |
|---|
| 98 | { |
|---|
| 99 | US_RASTER_DIR* xDir = &task->xDir; |
|---|
| 100 | US_RASTER_DIR* yDir = &task->yDir; |
|---|
| 101 | xDir->touchedMask = _X_TOUCHED_BY_STEM_CONTROL; |
|---|
| 102 | yDir->touchedMask = _X_TOUCHED_BY_STEM_CONTROL; |
|---|
| 103 | xDir->original = task->workGlyph.ox; |
|---|
| 104 | yDir->original = task->workGlyph.oy; |
|---|
| 105 | xDir->hinted = task->workGlyph.x; |
|---|
| 106 | yDir->hinted = task->workGlyph.y; |
|---|
| 107 | itrp_STROKE(task, xDir, &w, xOffset); |
|---|
| 108 | itrp_STROKE(task, yDir, &w, 0); |
|---|
| 109 | itrp_IUP(task, task->workGlyph.ox, task->workGlyph.x, _X_TOUCHED_BY_STEM_CONTROL); |
|---|
| 110 | itrp_IUP(task, task->workGlyph.oy, task->workGlyph.y, _Y_TOUCHED_BY_STEM_CONTROL); |
|---|
| 111 | } |
|---|
| 112 | else if (applyHint) |
|---|
| 113 | { |
|---|
| 114 | US_RASTER_DIR* xDir = &task->xDir; |
|---|
| 115 | US_RASTER_DIR* yDir = &task->yDir; |
|---|
| 116 | int vTouched = 0; |
|---|
| 117 | int hTouched = 0; |
|---|
| 118 | UT_GS* gs = &task->gs; |
|---|
| 119 | UT_MEMSET(gs, 0, sizeof(UT_GS)); |
|---|
| 120 | xDir->touchedMask = _X_TOUCHED_BY_STEM_CONTROL; |
|---|
| 121 | yDir->touchedMask = _X_TOUCHED_BY_STEM_CONTROL; |
|---|
| 122 | xDir->original = task->workGlyph.ox; |
|---|
| 123 | yDir->original = task->workGlyph.oy; |
|---|
| 124 | xDir->hinted = task->workGlyph.x; |
|---|
| 125 | yDir->hinted = task->workGlyph.y; |
|---|
| 126 | for (;;) |
|---|
| 127 | { |
|---|
| 128 | f = *w.u8++; |
|---|
| 129 | if (f == _UT_HINT_END) break; |
|---|
| 130 | switch (f) |
|---|
| 131 | { |
|---|
| 132 | case _UT_HINT_V_STEM: |
|---|
| 133 | vTouched = 1; |
|---|
| 134 | itrp_STEM(task, xDir, &w, xOffset); |
|---|
| 135 | break; |
|---|
| 136 | case _UT_HINT_H_STEM: |
|---|
| 137 | hTouched = 1; |
|---|
| 138 | itrp_STEM(task, yDir, &w, 0); |
|---|
| 139 | break; |
|---|
| 140 | case _UT_HINT_V_POINT: |
|---|
| 141 | vTouched = 1; |
|---|
| 142 | itrp_POINT(task, xDir, &w, xOffset); |
|---|
| 143 | break; |
|---|
| 144 | case _UT_HINT_H_POINT: |
|---|
| 145 | hTouched = 1; |
|---|
| 146 | itrp_POINT(task, yDir, &w, 0); |
|---|
| 147 | break; |
|---|
| 148 | case _UT_HINT_SSP: |
|---|
| 149 | gs->snapPos = ut_DecryptNum(&w); |
|---|
| 150 | UT_TRACE2("SetSnapPosPositin(%d)", gs->snapPos); |
|---|
| 151 | break; |
|---|
| 152 | case _UT_HINT_SSPCI: |
|---|
| 153 | gs->snapPosCutIn = ut_DecryptNum(&w); |
|---|
| 154 | UT_TRACE2("SetSnapPosPositinCutIn(%d)", gs->snapPosCutIn); |
|---|
| 155 | break; |
|---|
| 156 | case _UT_HINT_SSD: |
|---|
| 157 | gs->snapStem = ut_DecryptNum(&w); |
|---|
| 158 | UT_TRACE2("SetSnapPosDepth(%d)", gs->snapStem); |
|---|
| 159 | break; |
|---|
| 160 | case _UT_HINT_SSDCI: |
|---|
| 161 | gs->snapStemCutIn = ut_DecryptNum(&w); |
|---|
| 162 | UT_TRACE2("SetSnapPosDepthCutIn(%d)", gs->snapStemCutIn); |
|---|
| 163 | break; |
|---|
| 164 | } |
|---|
| 165 | } |
|---|
| 166 | if (vTouched) itrp_IUP(task, task->workGlyph.ox, task->workGlyph.x, _X_TOUCHED_BY_STEM_CONTROL); |
|---|
| 167 | if (hTouched) itrp_IUP(task, task->workGlyph.oy, task->workGlyph.y, _Y_TOUCHED_BY_STEM_CONTROL); |
|---|
| 168 | } |
|---|
| 169 | ut_EndGlyph(task); |
|---|
| 170 | } |
|---|
| 171 | UT_TRACE_TAB_DEC(); |
|---|
| 172 | return _UT_TRUE; |
|---|
| 173 | } |
|---|
| 174 | |
|---|
| 175 | UT_STATIC_API UT_BOOL ut_InterpreteGlyph(UT_FC* fc) |
|---|
| 176 | { |
|---|
| 177 | int i = fc->task->glyph->count - 1; |
|---|
| 178 | UT_TRACE1("ut_InterpreteGlyph()"); |
|---|
| 179 | UT_TRACE_TAB_INC(); |
|---|
| 180 | for (; i>=0; i--) |
|---|
| 181 | { |
|---|
| 182 | if (!ut_InterpreteSimpleGlyph(fc->task, fc->task->glyph->cmap, fc->task->glyph->data[i].p, !fc->preventHint, fc->task->glyph->data[i].xOffset)) return _UT_FALSE; |
|---|
| 183 | } |
|---|
| 184 | if (fc->task->emulItalic) |
|---|
| 185 | { |
|---|
| 186 | int i; |
|---|
| 187 | for (i=0; i<fc->task->rootGlyph.nPoint; i++) |
|---|
| 188 | { |
|---|
| 189 | fc->task->rootGlyph.x[i] += ut_ItalicY(fc->task->rootGlyph.y[i]); |
|---|
| 190 | } |
|---|
| 191 | fc->task->emulItalic = 0; |
|---|
| 192 | } |
|---|
| 193 | UT_TRACE_TAB_DEC(); |
|---|
| 194 | return _UT_TRUE; |
|---|
| 195 | } |
|---|
| 196 | |
|---|
| 197 | /***************************************************************************/ |
|---|
| 198 | |
|---|
| 199 | UT_STATIC_API void ut_PrepareScanGlyph(UT_FC* fc, UT_IMAGE* image) |
|---|
| 200 | { |
|---|
| 201 | UT_FONT_TASK* task = fc->task; |
|---|
| 202 | US_RASTER_DIR* xDir = &task->xDir; |
|---|
| 203 | US_RASTER_DIR* yDir = &task->yDir; |
|---|
| 204 | UT_TRACE1("ut_PrepareScanGlyph()"); |
|---|
| 205 | UT_TRACE_TAB_INC(); |
|---|
| 206 | task->isEmpty = 0; |
|---|
| 207 | if (task->rootGlyph.nPoint) |
|---|
| 208 | { |
|---|
| 209 | UT_COORD* x; |
|---|
| 210 | UT_COORD* y; |
|---|
| 211 | UT_COORD* stop; |
|---|
| 212 | int iPath, iStartPoint, iEndPoint; |
|---|
| 213 | UT_COORD cx, cy; |
|---|
| 214 | UT_COORD o_xMax = task->rootGlyph.x[0]; |
|---|
| 215 | UT_COORD o_xMin = task->rootGlyph.x[0]; |
|---|
| 216 | #ifdef _UT_REVERSE_OUTLINE_IMAGE |
|---|
| 217 | UT_COORD o_yMax = task->emSize - task->rootGlyph.y[0]; |
|---|
| 218 | UT_COORD o_yMin = task->emSize - task->rootGlyph.y[0]; |
|---|
| 219 | #else |
|---|
| 220 | UT_COORD o_yMax = task->rootGlyph.y[0]; |
|---|
| 221 | UT_COORD o_yMin = task->rootGlyph.y[0]; |
|---|
| 222 | #endif |
|---|
| 223 | for (iPath=0; iPath<task->rootGlyph.nPath; iPath++) |
|---|
| 224 | { |
|---|
| 225 | iStartPoint = task->rootGlyph.startPointIndex[iPath]; |
|---|
| 226 | iEndPoint = task->rootGlyph.endPointIndex[iPath]; |
|---|
| 227 | if (iStartPoint == iEndPoint) continue; |
|---|
| 228 | x = &task->rootGlyph.x[iStartPoint]; |
|---|
| 229 | y = &task->rootGlyph.y[iStartPoint]; |
|---|
| 230 | stop = &task->rootGlyph.x[iEndPoint]; |
|---|
| 231 | while (x <= stop) |
|---|
| 232 | { |
|---|
| 233 | #ifdef _UT_REVERSE_OUTLINE_IMAGE |
|---|
| 234 | *y = task->emSize - *y; |
|---|
| 235 | #endif |
|---|
| 236 | cx = *x++; |
|---|
| 237 | cy = *y++; |
|---|
| 238 | if (o_xMax < cx) o_xMax = cx; |
|---|
| 239 | else if (o_xMin > cx) o_xMin = cx; |
|---|
| 240 | if (o_yMax < cy) o_yMax = cy; |
|---|
| 241 | else if (o_yMin > cy) o_yMin = cy; |
|---|
| 242 | } |
|---|
| 243 | } |
|---|
| 244 | if (o_xMin < 0) o_xMin = (o_xMin - _UT_ONE_PIXEL + 1) >> _UT_PIXEL_SHIFT; |
|---|
| 245 | else o_xMin = o_xMin >> _UT_PIXEL_SHIFT; |
|---|
| 246 | if (o_yMin < 0) o_yMin = (o_yMin - _UT_ONE_PIXEL + 1) >> _UT_PIXEL_SHIFT; |
|---|
| 247 | else o_yMin = o_yMin >> _UT_PIXEL_SHIFT; |
|---|
| 248 | if (o_xMax < 0) o_xMax = (o_xMax - _UT_HALF_PIXEL) >> _UT_PIXEL_SHIFT; |
|---|
| 249 | else o_xMax = (o_xMax + _UT_HALF_PIXEL) >> _UT_PIXEL_SHIFT; |
|---|
| 250 | if (o_yMax < 0) o_yMax = (o_yMax - _UT_HALF_PIXEL) >> _UT_PIXEL_SHIFT; |
|---|
| 251 | else o_yMax = (o_yMax + _UT_HALF_PIXEL) >> _UT_PIXEL_SHIFT; |
|---|
| 252 | if (o_xMin == o_xMax) |
|---|
| 253 | { |
|---|
| 254 | o_xMax++; |
|---|
| 255 | task->isEmpty = 1; |
|---|
| 256 | } |
|---|
| 257 | if (o_yMin == o_yMax) |
|---|
| 258 | { |
|---|
| 259 | o_yMax++; |
|---|
| 260 | task->isEmpty = 1; |
|---|
| 261 | } |
|---|
| 262 | if (o_xMin >= 0) |
|---|
| 263 | { |
|---|
| 264 | o_xMin = (o_xMin >> task->grayShift) << task->grayShift; |
|---|
| 265 | } |
|---|
| 266 | else |
|---|
| 267 | { |
|---|
| 268 | o_xMin = ((o_xMin-xDir->pixelBitCount+1) >> task->grayShift) << task->grayShift; |
|---|
| 269 | } |
|---|
| 270 | if (o_xMax >= 0) |
|---|
| 271 | { |
|---|
| 272 | o_xMax = ((o_xMax+xDir->pixelBitCount) >> task->grayShift) << task->grayShift; |
|---|
| 273 | } |
|---|
| 274 | else |
|---|
| 275 | { |
|---|
| 276 | o_xMax = ((o_xMax+1) >> task->grayShift) << task->grayShift; |
|---|
| 277 | } |
|---|
| 278 | if (o_yMin >= 0) |
|---|
| 279 | { |
|---|
| 280 | o_yMin = (o_yMin >> task->grayShift) << task->grayShift; |
|---|
| 281 | } |
|---|
| 282 | else |
|---|
| 283 | { |
|---|
| 284 | o_yMin = ((o_yMin-yDir->pixelBitCount+1) >> task->grayShift) << task->grayShift; |
|---|
| 285 | } |
|---|
| 286 | if (o_yMax >= 0) |
|---|
| 287 | { |
|---|
| 288 | o_yMax = ((o_yMax+yDir->pixelBitCount) >> task->grayShift) << task->grayShift; |
|---|
| 289 | } |
|---|
| 290 | else |
|---|
| 291 | { |
|---|
| 292 | o_yMax = ((o_yMax+1) >> task->grayShift) << task->grayShift; |
|---|
| 293 | } |
|---|
| 294 | if (task->emulBold) |
|---|
| 295 | { |
|---|
| 296 | task->emulBold = ut_BoldExtra(fc->xSize) << task->grayShift; |
|---|
| 297 | o_xMax += task->emulBold; |
|---|
| 298 | } |
|---|
| 299 | #ifdef _UT_USE_BITMAP_EFFECT |
|---|
| 300 | if (task->emulOutline) |
|---|
| 301 | { |
|---|
| 302 | o_xMin -= 1 << task->grayShift; |
|---|
| 303 | o_yMin -= 1 << task->grayShift; |
|---|
| 304 | o_xMax += 1 << task->grayShift; |
|---|
| 305 | o_yMax += 1 << task->grayShift; |
|---|
| 306 | } |
|---|
| 307 | else if (task->emulEdge) |
|---|
| 308 | { |
|---|
| 309 | o_xMin -= ut_GetExtraSizeEdge(task->ySize) << task->grayShift; |
|---|
| 310 | o_yMin -= ut_GetExtraSizeEdge(task->ySize) << task->grayShift; |
|---|
| 311 | o_xMax += ut_GetExtraSizeEdge(task->ySize) << task->grayShift; |
|---|
| 312 | o_yMax += ut_GetExtraSizeEdge(task->ySize) << task->grayShift; |
|---|
| 313 | } |
|---|
| 314 | #endif |
|---|
| 315 | task->i_xMin = o_xMin; |
|---|
| 316 | task->i_xMax = o_xMax; |
|---|
| 317 | task->i_yMin = o_yMin; |
|---|
| 318 | task->i_yMax = o_yMax; |
|---|
| 319 | x = &task->rootGlyph.x[0]; |
|---|
| 320 | y = &task->rootGlyph.y[0]; |
|---|
| 321 | stop = &task->rootGlyph.x[task->rootGlyph.nPoint]; |
|---|
| 322 | o_xMin <<= _UT_PIXEL_SHIFT; |
|---|
| 323 | o_yMin <<= _UT_PIXEL_SHIFT; |
|---|
| 324 | while (x <= stop) |
|---|
| 325 | { |
|---|
| 326 | *x++ -= o_xMin; |
|---|
| 327 | *y++ -= o_yMin; |
|---|
| 328 | } |
|---|
| 329 | } |
|---|
| 330 | else |
|---|
| 331 | { |
|---|
| 332 | task->i_xMin = 0; |
|---|
| 333 | task->i_xMax = 0; |
|---|
| 334 | task->i_yMin = 0; |
|---|
| 335 | task->i_yMax = 0; |
|---|
| 336 | } |
|---|
| 337 | if (fc->task->glyph->cmap->isStroke) |
|---|
| 338 | { |
|---|
| 339 | task->i_xMax += fc->strokeMask.size; |
|---|
| 340 | task->i_yMax += fc->strokeMask.size; |
|---|
| 341 | } |
|---|
| 342 | task->i_ySize = task->i_yMax - task->i_yMin; |
|---|
| 343 | task->i_xSize = task->i_xMax - task->i_xMin; |
|---|
| 344 | task->i_bSize = (task->i_xSize + 31) >> 5; |
|---|
| 345 | task->i_lSize = task->i_ySize * task->i_bSize; |
|---|
| 346 | ut_CalcScanBufferSize(task); |
|---|
| 347 | if (task->compelPackedImage && (xDir->pixelBitCount == 1) && (yDir->pixelBitCount == 1)) |
|---|
| 348 | { |
|---|
| 349 | image->type = _UT_IMAGE_TYPE_BITMAP; |
|---|
| 350 | image->bbox.ox = task->i_xMin; |
|---|
| 351 | image->bbox.oy = task->i_yMin; |
|---|
| 352 | image->bbox.sx = task->i_xSize; |
|---|
| 353 | image->bbox.sy = task->i_ySize; |
|---|
| 354 | image->bSize = ut_BSIZE(image->bbox.sx); |
|---|
| 355 | image->lSize = image->bSize * image->bbox.sy; |
|---|
| 356 | } |
|---|
| 357 | else if (task->xDir.subPixelScale) |
|---|
| 358 | { |
|---|
| 359 | image->type = _UT_IMAGE_TYPE_SUBPIXEL_H; |
|---|
| 360 | image->bbox.ox = task->i_xMin >> task->grayShift; |
|---|
| 361 | image->bbox.oy = task->i_yMin >> task->grayShift; |
|---|
| 362 | image->bbox.sx = task->i_xSize >> task->grayShift; |
|---|
| 363 | image->bbox.sy = task->i_ySize >> task->grayShift; |
|---|
| 364 | image->bSize = ut_BALIGN(image->bbox.sx); |
|---|
| 365 | image->lSize = image->bSize * image->bbox.sy; |
|---|
| 366 | } |
|---|
| 367 | else |
|---|
| 368 | { |
|---|
| 369 | image->type = _UT_IMAGE_TYPE_BITMAP_65; |
|---|
| 370 | image->bbox.ox = task->i_xMin >> task->grayShift; |
|---|
| 371 | image->bbox.oy = task->i_yMin >> task->grayShift; |
|---|
| 372 | image->bbox.sx = task->i_xSize >> task->grayShift; |
|---|
| 373 | image->bbox.sy = task->i_ySize >> task->grayShift; |
|---|
| 374 | image->bSize = ut_BALIGN(image->bbox.sx); |
|---|
| 375 | image->lSize = image->bSize * image->bbox.sy; |
|---|
| 376 | if (ut_IsByteImage(fc)) |
|---|
| 377 | { |
|---|
| 378 | task->i_bSize = image->bSize; |
|---|
| 379 | task->i_lSize = image->lSize; |
|---|
| 380 | } |
|---|
| 381 | } |
|---|
| 382 | UT_TRACE2("task->i_xMin = %d", task->i_xMin); |
|---|
| 383 | UT_TRACE2("task->i_xMax = %d", task->i_xMax); |
|---|
| 384 | UT_TRACE2("task->i_yMin = %d", task->i_yMin); |
|---|
| 385 | UT_TRACE2("task->i_yMax = %d", task->i_yMax); |
|---|
| 386 | UT_TRACE2("task->i_ySize = %d", task->i_ySize); |
|---|
| 387 | UT_TRACE2("task->i_xSize = %d", task->i_xSize); |
|---|
| 388 | UT_TRACE2("task->i_bSize = %d", task->i_bSize); |
|---|
| 389 | UT_TRACE2("task->i_lSize = %d", task->i_lSize); |
|---|
| 390 | UT_TRACE_TAB_DEC(); |
|---|
| 391 | } |
|---|
| 392 | |
|---|
| 393 | UT_STATIC_API UT_BOOL ut_PrepareOutlineGlyphImage(UT_FC* fc, UT_IMAGE* image) |
|---|
| 394 | { |
|---|
| 395 | UT_FONT_TASK* task = fc->task; |
|---|
| 396 | UT_TRACE1("ut_PrepareOutlineGlyphImage()"); |
|---|
| 397 | UT_TRACE_TAB_INC(); |
|---|
| 398 | UT_TRACE2("task->compelPackedImage = %d", task->compelPackedImage); |
|---|
| 399 | UT_TRACE2("task->xDir.pixelBitCount = %d", task->xDir.pixelBitCount); |
|---|
| 400 | UT_TRACE2("task->yDir.pixelBitCount = %d", task->yDir.pixelBitCount); |
|---|
| 401 | if (ut_IsRootGlyphNull(task)) |
|---|
| 402 | { |
|---|
| 403 | image->type = _UT_IMAGE_TYPE_NULL; |
|---|
| 404 | image->bbox.ox = 0; |
|---|
| 405 | image->bbox.oy = 0; |
|---|
| 406 | image->bbox.sx = 0; |
|---|
| 407 | image->bbox.sy = 0; |
|---|
| 408 | image->bSize = 0; |
|---|
| 409 | image->lSize = 0; |
|---|
| 410 | UT_TRACE1("image->type = _UT_IMAGE_TYPE_NULL"); |
|---|
| 411 | UT_TRACE_TAB_DEC(); |
|---|
| 412 | return _UT_TRUE; |
|---|
| 413 | } |
|---|
| 414 | if (!task->xDir.pixelBitCount || !task->yDir.pixelBitCount) |
|---|
| 415 | { |
|---|
| 416 | image->type = _UT_RASTER_TYPE_OUTLINE; |
|---|
| 417 | UT_TRACE1("image->type = _UT_RASTER_TYPE_OUTLINE"); |
|---|
| 418 | UT_TRACE_TAB_DEC(); |
|---|
| 419 | return _UT_FALSE; |
|---|
| 420 | } |
|---|
| 421 | ut_PrepareScanGlyph(fc, image); |
|---|
| 422 | UT_TRACE_TAB_DEC(); |
|---|
| 423 | return _UT_TRUE; |
|---|
| 424 | } |
|---|
| 425 | |
|---|
| 426 | UT_STATIC_API UT_BOOL ut_PrepareRasterGlyphOutline(UT_FC* fc, UT_IMAGE* image) |
|---|
| 427 | { |
|---|
| 428 | /* OL G65 G17 G5 G2 B2*/ |
|---|
| 429 | char pixelBitCount[] = { 0, 8, 4, 2, 1, 1}; |
|---|
| 430 | char grayFullShift[] = { 0, 3, 2, 1, 0, 0}; |
|---|
| 431 | char grayPreShift[] = { 0, 3, 2, 1, 0, 0}; |
|---|
| 432 | char compelPack[] = { 0, 0, 0, 0, 0, 1}; |
|---|
| 433 | UT_FONT_TASK* task = fc->task; |
|---|
| 434 | US_RASTER_DIR* xDir = &task->xDir; |
|---|
| 435 | US_RASTER_DIR* yDir = &task->yDir; |
|---|
| 436 | int rasterType = fc->rasterType; |
|---|
| 437 | int xGrayType = fc->xGrayType; |
|---|
| 438 | int yGrayType = fc->yGrayType; |
|---|
| 439 | UT_BOOL result; |
|---|
| 440 | if (fc->task->glyph->cmap->isStroke) |
|---|
| 441 | { |
|---|
| 442 | rasterType = _UT_RASTER_TYPE_GRAY_5; |
|---|
| 443 | xGrayType = 0; |
|---|
| 444 | yGrayType = 0; |
|---|
| 445 | } |
|---|
| 446 | UT_TRACE1("ut_PrepareRasterGlyphOutline()"); |
|---|
| 447 | UT_TRACE_TAB_INC(); |
|---|
| 448 | task->xSize = fc->xSize; |
|---|
| 449 | task->ySize = fc->ySize; |
|---|
| 450 | task->grayShift = grayFullShift[rasterType+1]; |
|---|
| 451 | xDir->gridFitSize = fc->xSize; |
|---|
| 452 | yDir->gridFitSize = fc->ySize; |
|---|
| 453 | xDir->subPixelScale = 0; |
|---|
| 454 | yDir->subPixelScale = 0; |
|---|
| 455 | #ifdef _UT_USE_BITMAP_EFFECT |
|---|
| 456 | if (task->emulOutline) task->emulEdge = 0; |
|---|
| 457 | #endif |
|---|
| 458 | if (!task->grayShift) |
|---|
| 459 | { |
|---|
| 460 | xDir->pixelBitCount = 1; |
|---|
| 461 | yDir->pixelBitCount = 1; |
|---|
| 462 | task->grayShift = 0; |
|---|
| 463 | task->grayShift = 0; |
|---|
| 464 | xDir->grayPreShift = 0; |
|---|
| 465 | yDir->grayPreShift = 0; |
|---|
| 466 | xDir->grayPostShift = 0; |
|---|
| 467 | yDir->grayPostShift = 0; |
|---|
| 468 | } |
|---|
| 469 | else |
|---|
| 470 | { |
|---|
| 471 | xDir->pixelBitCount = pixelBitCount[rasterType+1]; |
|---|
| 472 | yDir->pixelBitCount = pixelBitCount[rasterType+1]; |
|---|
| 473 | xDir->grayPreShift = task->grayShift - task->grayShift * xGrayType / 3; |
|---|
| 474 | yDir->grayPreShift = task->grayShift - task->grayShift * yGrayType / 3; |
|---|
| 475 | xDir->grayPostShift = task->grayShift - xDir->grayPreShift; |
|---|
| 476 | yDir->grayPostShift = task->grayShift - yDir->grayPreShift; |
|---|
| 477 | xDir->graySubHalf = _UT_HALF_PIXEL; |
|---|
| 478 | yDir->graySubHalf = _UT_HALF_PIXEL; |
|---|
| 479 | xDir->graySubPix = _UT_ONE_PIXEL - 1; |
|---|
| 480 | yDir->graySubPix = _UT_ONE_PIXEL - 1; |
|---|
| 481 | xDir->isGray = xDir->grayPreShift; |
|---|
| 482 | yDir->isGray = yDir->grayPreShift; |
|---|
| 483 | if (fc->subPixelType == _UT_SUBPIXEL_TYPE_HORI) xDir->subPixelScale = 3; |
|---|
| 484 | else if (fc->subPixelType == _UT_SUBPIXEL_TYPE_VERT) yDir->subPixelScale = 3; |
|---|
| 485 | if (xDir->isGray) |
|---|
| 486 | { |
|---|
| 487 | xDir->gridFitSize <<= xDir->grayPreShift; |
|---|
| 488 | xDir->graySubHalf = _UT_HALF_PIXEL << xDir->grayPreShift; |
|---|
| 489 | xDir->graySubPix = (_UT_ONE_PIXEL << xDir->grayPreShift) - 1; |
|---|
| 490 | } |
|---|
| 491 | if (yDir->isGray) |
|---|
| 492 | { |
|---|
| 493 | yDir->gridFitSize <<= yDir->grayPreShift; |
|---|
| 494 | yDir->graySubHalf = _UT_HALF_PIXEL << yDir->grayPreShift; |
|---|
| 495 | yDir->graySubPix = (_UT_ONE_PIXEL << yDir->grayPreShift) - 1; |
|---|
| 496 | } |
|---|
| 497 | } |
|---|
| 498 | task->compelPackedImage = compelPack[rasterType+1]; |
|---|
| 499 | task->isDropout = !fc->preventDropout && ((xDir->gridFitSize < 30) || (yDir->gridFitSize < 30)); |
|---|
| 500 | task->LineTo = ut_LineTo_Standard; |
|---|
| 501 | #ifdef _UT_USE_DROPOUT_COLTROL |
|---|
| 502 | if (task->isDropout) task->LineTo = ut_LineTo_Dropout; |
|---|
| 503 | #endif |
|---|
| 504 | if (fc->task->glyph->cmap->isStroke) |
|---|
| 505 | { |
|---|
| 506 | int strokeDepth = (yDir->gridFitSize / 20) + 1; |
|---|
| 507 | ut_InitBitMask(&fc->strokeMask, strokeDepth); |
|---|
| 508 | task->strokeMask = &fc->strokeMask; |
|---|
| 509 | xDir->gridFitSize--; |
|---|
| 510 | yDir->gridFitSize--; |
|---|
| 511 | xDir->gridFitSize--; |
|---|
| 512 | yDir->gridFitSize--; |
|---|
| 513 | } |
|---|
| 514 | UT_TRACE2("task->xSize = %d", task->xSize); |
|---|
| 515 | UT_TRACE2("task->ySize = %d", task->ySize); |
|---|
| 516 | UT_TRACE2("task->xDir.gridFitSize = %d", task->xDir.gridFitSize); |
|---|
| 517 | UT_TRACE2("task->yDir.gridFitSize = %d", task->yDir.gridFitSize); |
|---|
| 518 | UT_TRACE2("task->xDir.graySubHalf = %d", task->xDir.graySubHalf); |
|---|
| 519 | UT_TRACE2("task->yDir.graySubHalf = %d", task->yDir.graySubHalf); |
|---|
| 520 | UT_TRACE2("task->xDir.graySubPix = %d", task->xDir.graySubPix ); |
|---|
| 521 | UT_TRACE2("task->yDir.graySubPix = %d", task->yDir.graySubPix ); |
|---|
| 522 | UT_TRACE2("task->isDropout = %d", task->isDropout); |
|---|
| 523 | #ifdef _UT_USE_BITMAP_EFFECT |
|---|
| 524 | if (task->emulEdge || task->emulOutline) task->compelPackedImage = 0; |
|---|
| 525 | #endif |
|---|
| 526 | task->rootGlyph.nPath = 0; |
|---|
| 527 | task->rootGlyph.nPoint = 0; |
|---|
| 528 | task->workGlyph = task->rootGlyph; |
|---|
| 529 | task->isBezier = fc->task->glyph->cmap->glyphType == _UT_OUTLINE_TYPE_BEZIER; |
|---|
| 530 | task->emSize = ut_SWAP_U16(fc->task->glyph->cmap->depend.emSize); |
|---|
| 531 | image->width = (fc->task->glyph->width * fc->xSize + (task->emSize>>1)) / task->emSize; |
|---|
| 532 | image->height = (fc->task->glyph->height * fc->ySize + (task->emSize>>1)) / task->emSize; |
|---|
| 533 | if (!fc->task->glyph->count) |
|---|
| 534 | { |
|---|
| 535 | image->type = _UT_IMAGE_TYPE_NULL; |
|---|
| 536 | image->bbox.ox = 0; |
|---|
| 537 | image->bbox.oy = 0; |
|---|
| 538 | image->bbox.sx = 0; |
|---|
| 539 | image->bbox.sy = 0; |
|---|
| 540 | image->bSize = 0; |
|---|
| 541 | image->lSize = 0; |
|---|
| 542 | UT_TRACE_TAB_DEC(); |
|---|
| 543 | return _UT_TRUE; |
|---|
| 544 | } |
|---|
| 545 | if (!ut_InterpreteGlyph(fc)) |
|---|
| 546 | { |
|---|
| 547 | UT_TRACE_TAB_DEC(); |
|---|
| 548 | return _UT_FALSE; |
|---|
| 549 | } |
|---|
| 550 | if (xDir->grayPostShift) |
|---|
| 551 | { |
|---|
| 552 | int i; |
|---|
| 553 | for (i=0; i<task->rootGlyph.nPoint; i++) |
|---|
| 554 | { |
|---|
| 555 | task->rootGlyph.x[i] <<= xDir->grayPostShift; |
|---|
| 556 | } |
|---|
| 557 | } |
|---|
| 558 | if (yDir->grayPostShift) |
|---|
| 559 | { |
|---|
| 560 | int i; |
|---|
| 561 | for (i=0; i<task->rootGlyph.nPoint; i++) |
|---|
| 562 | { |
|---|
| 563 | task->rootGlyph.y[i] <<= yDir->grayPostShift; |
|---|
| 564 | } |
|---|
| 565 | } |
|---|
| 566 | if (xDir->subPixelScale) |
|---|
| 567 | { |
|---|
| 568 | int i; |
|---|
| 569 | for (i=0; i<task->rootGlyph.nPoint; i++) |
|---|
| 570 | { |
|---|
| 571 | task->rootGlyph.x[i] *= 3; |
|---|
| 572 | } |
|---|
| 573 | } |
|---|
| 574 | if (yDir->subPixelScale) |
|---|
| 575 | { |
|---|
| 576 | int i; |
|---|
| 577 | for (i=0; i<task->rootGlyph.nPoint; i++) |
|---|
| 578 | { |
|---|
| 579 | task->rootGlyph.y[i] *= 3; |
|---|
| 580 | } |
|---|
| 581 | } |
|---|
| 582 | result = ut_PrepareOutlineGlyphImage(fc, image); |
|---|
| 583 | UT_TRACE_TAB_DEC(); |
|---|
| 584 | return result; |
|---|
| 585 | } |
|---|
| 586 | |
|---|
| 587 | UT_BOOL utm_MakeImageOfOutlineFont(UT_FC* fc, UT_IMAGE* image) |
|---|
| 588 | { |
|---|
| 589 | UT_FONT_TASK* task = fc->task; |
|---|
| 590 | UT_TRACE1("ut_MakeOutlineGlyphImage()"); |
|---|
| 591 | if (image->type == _UT_IMAGE_TYPE_NULL_GLYPH) return _UT_TRUE; |
|---|
| 592 | if (image->type == _UT_IMAGE_TYPE_NULL) return _UT_TRUE; |
|---|
| 593 | if (image->type == _UT_RASTER_TYPE_OUTLINE) return _UT_TRUE; |
|---|
| 594 | UT_TRACE_TAB_INC(); |
|---|
| 595 | if (fc->task->glyph->cmap->isStroke) |
|---|
| 596 | { |
|---|
| 597 | task->LineTo = ut_LineTo_Stroke; |
|---|
| 598 | task->image = (UT_U32*)ut_AllocScanBuffer(task, image, task->i_lSize<<2); |
|---|
| 599 | UT_MEMSET(task->image, 0, task->i_lSize<<2); |
|---|
| 600 | ut_ScanGlyph(task, _UT_FALSE); |
|---|
| 601 | ut_SwapImage(task); |
|---|
| 602 | ut_CompleteImage(task, image); |
|---|
| 603 | } |
|---|
| 604 | else |
|---|
| 605 | { |
|---|
| 606 | // ##### |
|---|
| 607 | } |
|---|
| 608 | UT_TRACE_TAB_DEC(); |
|---|
| 609 | return _UT_TRUE; |
|---|
| 610 | } |
|---|
| 611 | |
|---|
| 612 | /***************************************************************************/ |
|---|
| 613 | |
|---|
| 614 | UT_BOOL utm_PrepareCharImageFromOutlineFont(UT_FC* fc, UT_CODE code, UT_IMAGE* image) |
|---|
| 615 | { |
|---|
| 616 | UT_BOOL result; |
|---|
| 617 | UT_TRACE2("utm_PrepareCharImageFromOutlineFont() code = %d", code); |
|---|
| 618 | UT_TRACE_TAB_INC(); |
|---|
| 619 | if (code == _UT_INVALID_CODE) |
|---|
| 620 | { |
|---|
| 621 | image->type = _UT_IMAGE_TYPE_NULL_GLYPH; |
|---|
| 622 | UT_TRACE_TAB_DEC(); |
|---|
| 623 | return _UT_FALSE; |
|---|
| 624 | } |
|---|
| 625 | if (!utm_GetGlyph(fc, code, fc->task->glyph)) |
|---|
| 626 | { |
|---|
| 627 | image->type = _UT_IMAGE_TYPE_NULL_GLYPH; |
|---|
| 628 | UT_TRACE_TAB_DEC(); |
|---|
| 629 | return _UT_FALSE; |
|---|
| 630 | } |
|---|
| 631 | result = ut_PrepareRasterGlyphOutline(fc, image); |
|---|
| 632 | UT_TRACE_TAB_DEC(); |
|---|
| 633 | return result; |
|---|
| 634 | } |
|---|
| 635 | |
|---|
| 636 | UT_BOOL utm_GetCharImageFromOutlineFont(UT_FC* fc, UT_CODE code, UT_IMAGE* image) |
|---|
| 637 | { |
|---|
| 638 | #if defined(_UT_USE_CACHE) && defined(_UT_USE_MALLOC_FREE) |
|---|
| 639 | if (utm_CacheHit(fc, code, image)) return _UT_TRUE; |
|---|
| 640 | #endif /*#if defined(_UT_USE_CACHE) && defined(_UT_USE_MALLOC_FREE)*/ |
|---|
| 641 | if (!utm_PrepareCharImageFromOutlineFont(fc, code, image)) return _UT_FALSE; |
|---|
| 642 | if (!utm_MakeImageOfOutlineFont(fc, image)) return _UT_FALSE; |
|---|
| 643 | #if defined(_UT_USE_CACHE) && defined(_UT_USE_MALLOC_FREE) |
|---|
| 644 | utm_CacheAdd(fc, code, image); |
|---|
| 645 | #endif /*#if defined(_UT_USE_CACHE) && defined(_UT_USE_MALLOC_FREE)*/ |
|---|
| 646 | return _UT_TRUE; |
|---|
| 647 | } |
|---|
| 648 | |
|---|
| 649 | UT_BOOL utm_PrepareCharImage(UT_FC* fc, UT_CODE code, UT_IMAGE* image) |
|---|
| 650 | { |
|---|
| 651 | UT_FONT_TASK* task = fc->task; |
|---|
| 652 | UT_TRACE2("utm_PrepareCharImage() code = %d", code); |
|---|
| 653 | UT_TRACE_TAB_INC(); |
|---|
| 654 | if (code == _UT_INVALID_CODE) |
|---|
| 655 | { |
|---|
| 656 | UT_TRACE1("image->type = _UT_INVALID_CODE"); |
|---|
| 657 | image->type = _UT_IMAGE_TYPE_NULL_GLYPH; |
|---|
| 658 | UT_TRACE_TAB_DEC(); |
|---|
| 659 | return _UT_FALSE; |
|---|
| 660 | } |
|---|
| 661 | if (!utm_GetGlyph(fc, code, fc->task->glyph)) |
|---|
| 662 | { |
|---|
| 663 | UT_TRACE1("image->type = _UT_IMAGE_TYPE_NULL_GLYPH"); |
|---|
| 664 | image->type = _UT_IMAGE_TYPE_NULL_GLYPH; |
|---|
| 665 | UT_TRACE_TAB_DEC(); |
|---|
| 666 | return _UT_FALSE; |
|---|
| 667 | } |
|---|
| 668 | task->emulItalic = fc->isItalic && !fc->fontItalic; |
|---|
| 669 | task->emulBold = fc->isBold && (fc->fontWeight < _UT_FONT_WEIGHT_BOLD); |
|---|
| 670 | #ifdef _UT_USE_BITMAP_EFFECT |
|---|
| 671 | task->emulEdge = fc->edgeType; |
|---|
| 672 | task->emulSmooth = (fc->rasterType == _UT_RASTER_TYPE_GRAY_2) ? fc->smoothType : 0; |
|---|
| 673 | if ((fc->edgeType == _UT_EDGE_TYPE_OUTLINE) || (fc->edgeType == _UT_EDGE_TYPE_OUTLINE1)) task->emulOutline = 1; |
|---|
| 674 | else if (fc->edgeType == _UT_EDGE_TYPE_INLINE) task->emulOutline = -1; |
|---|
| 675 | else task->emulOutline = 0; |
|---|
| 676 | #endif |
|---|
| 677 | if (fc->task->glyph->cmap->glyphType < 0) |
|---|
| 678 | { |
|---|
| 679 | UT_BOOL result = ut_PrepareRasterGlyphOutline(fc, image); |
|---|
| 680 | UT_TRACE_TAB_DEC(); |
|---|
| 681 | return result; |
|---|
| 682 | } |
|---|
| 683 | else |
|---|
| 684 | { |
|---|
| 685 | #ifdef _UT_USE_BITMAP_FONT |
|---|
| 686 | UT_BOOL result = ut_PrepareRasterGlyphBitmap(fc, image); |
|---|
| 687 | UT_TRACE_TAB_DEC(); |
|---|
| 688 | return result; |
|---|
| 689 | #else /*#ifdef _UT_USE_BITMAP_FONT*/ |
|---|
| 690 | UT_TRACE_TAB_DEC(); |
|---|
| 691 | return _UT_FALSE; |
|---|
| 692 | #endif /*#ifdef _UT_USE_BITMAP_FONT*/ |
|---|
| 693 | } |
|---|
| 694 | } |
|---|
| 695 | |
|---|
| 696 | UT_BOOL utm_MakeCharImage(UT_FC* fc, UT_IMAGE* image) |
|---|
| 697 | { |
|---|
| 698 | if (fc->task->glyph->cmap->glyphType < 0) |
|---|
| 699 | { |
|---|
| 700 | return utm_MakeImageOfOutlineFont(fc, image); |
|---|
| 701 | } |
|---|
| 702 | else |
|---|
| 703 | { |
|---|
| 704 | #ifdef _UT_USE_BITMAP_FONT |
|---|
| 705 | return utm_MakeImageOfBitmapFont(fc, image); |
|---|
| 706 | #else /*#ifdef _UT_USE_BITMAP_FONT*/ |
|---|
| 707 | UT_TRACE_TAB_DEC(); |
|---|
| 708 | return _UT_FALSE; |
|---|
| 709 | #endif /*#ifdef _UT_USE_BITMAP_FONT*/ |
|---|
| 710 | } |
|---|
| 711 | } |
|---|
| 712 | |
|---|
| 713 | UT_BOOL utm_GetCharImage(UT_FC* fc, UT_CODE code, UT_IMAGE* image) |
|---|
| 714 | { |
|---|
| 715 | #if defined(_UT_USE_CACHE) && defined(_UT_USE_MALLOC_FREE) |
|---|
| 716 | if (utm_CacheHit(fc, code, image)) return _UT_TRUE; |
|---|
| 717 | #endif /*#if defined(_UT_USE_CACHE) && defined(_UT_USE_MALLOC_FREE)*/ |
|---|
| 718 | if (!utm_PrepareCharImage(fc, code, image)) return _UT_FALSE; |
|---|
| 719 | if (fc->task->glyph->cmap->glyphType < 0) |
|---|
| 720 | { |
|---|
| 721 | if (!utm_MakeImageOfOutlineFont(fc, image)) return _UT_FALSE;; |
|---|
| 722 | #if defined(_UT_USE_CACHE) && defined(_UT_USE_MALLOC_FREE) |
|---|
| 723 | utm_CacheAdd(fc, code, image); |
|---|
| 724 | #endif /*#if defined(_UT_USE_CACHE) && defined(_UT_USE_MALLOC_FREE)*/ |
|---|
| 725 | return _UT_TRUE; |
|---|
| 726 | } |
|---|
| 727 | else |
|---|
| 728 | { |
|---|
| 729 | #ifdef _UT_USE_BITMAP_FONT |
|---|
| 730 | return utm_MakeImageOfBitmapFont(fc, image); |
|---|
| 731 | #else /*#ifdef _UT_USE_BITMAP_FONT*/ |
|---|
| 732 | UT_TRACE_TAB_DEC(); |
|---|
| 733 | return _UT_FALSE; |
|---|
| 734 | #endif /*#ifdef _UT_USE_BITMAP_FONT*/ |
|---|
| 735 | } |
|---|
| 736 | } |
|---|
| 737 | |
|---|
| 738 | /***************************************************************************/ |
|---|