| 345 | |
| 346 | template<bool processR, bool processG, bool processB, bool processA> |
| 347 | void process(const OfxRectI& procWindow, const OfxPointD& rs) |
| 348 | { |
| 349 | assert( (!processR && !processG && !processB) || (nComponents == 3 || nComponents == 4) ); |
| 350 | assert( !processA || (nComponents == 1 || nComponents == 4) ); |
| 351 | |
| 352 | float tmpPix[4] = {0.f, 0.f, 0.f, 0.f}; |
| 353 | double par = _dstImg->getPixelAspectRatio(); |
| 354 | if (par <= 0.) { |
| 355 | par = 1.; |
| 356 | } |
| 357 | OfxPointD btmLeft_canonical = { _btmLeft.x, _btmLeft.y }; |
| 358 | OfxPointD topRight_canonical = { _btmLeft.x + _size.x, _btmLeft.y + _size.y }; |
| 359 | OfxPointD btmLeft; // btmLeft position in pixel |
| 360 | Coords::toPixelSub(btmLeft_canonical, rs, par, &btmLeft); |
| 361 | OfxPointD topRight; // topRight position in pixel |
| 362 | Coords::toPixelSub(topRight_canonical, rs, par, &topRight); |
| 363 | OfxPointD softness; // softness value in pixel |
| 364 | softness.x = _softness * rs.x / par; |
| 365 | softness.y = _softness * rs.y; |
| 366 | OfxPointD r; // cornerRadius value in pixel |
| 367 | r.x = _cornerRadius.x * rs.x / par; |
| 368 | r.y = _cornerRadius.y * rs.y; |
| 369 | |
| 370 | for (int y = procWindow.y1; y < procWindow.y2; ++y) { |
| 371 | if ( _effect.abort() ) { |
| 372 | break; |
| 373 | } |
| 374 | |
| 375 | PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y); |
| 376 | |
| 377 | for (int x = procWindow.x1; x < procWindow.x2; ++x, dstPix += nComponents) { |
| 378 | const PIX *srcPix = (const PIX *) (_srcImg ? _srcImg->getPixelAddress(x, y) : 0); |
| 379 | double dx = (std::min)(x - btmLeft.x, topRight.x - x); |
| 380 | double dy = (std::min)(y - btmLeft.y, topRight.y - y); |
| 381 | |
| 382 | if ( (dx <= -0.5) || (dy <= -0.5) ) { |
| 383 | // outside of the rectangle |
| 384 | tmpPix[0] = (float)_color0.r; |
| 385 | tmpPix[1] = (float)_color0.g; |
| 386 | tmpPix[2] = (float)_color0.b; |
| 387 | tmpPix[3] = (float)_color0.a; |
| 388 | } else { |
| 389 | float a = 1.; // mix factor with the outside |
| 390 | // test if the center of the pixel is within one of the rounded corners |
| 391 | if ( (r.x > 0) && (r.y > 0) && |
| 392 | ( ( x < (btmLeft.x + r.x) ) || ( x > (topRight.x - r.x) ) ) && |
| 393 | ( ( y < (btmLeft.y + r.y) ) || ( y > (topRight.y - r.y) ) ) ) { |
| 394 | // CORNERS |
| 395 | |
| 396 | // compute the corresponding ellipse center (in pixel coordinates |
| 397 | OfxPointD c; // center position in pixel |
| 398 | c.x = x < (btmLeft.x + r.x) ? (btmLeft.x + r.x) : (topRight.x - r.x); |
| 399 | c.y = y < (btmLeft.y + r.y) ? (btmLeft.y + r.y) : (topRight.y - r.y); |
| 400 | |
| 401 | // The following is the ellipse drawing code from the Radial plugin |
| 402 | |
| 403 | // approximate subpixel rendering of the disc: |
| 404 | // - test the pixel corner closer to the center. if it is outside, the pixel is fully outside |
no test coverage detected