📄 qdrawhelper.cpp
字号:
if (ipos < 0) ipos = 0; else if (ipos >= GRADIENT_STOPTABLE_SIZE) ipos = GRADIENT_STOPTABLE_SIZE-1; } } Q_ASSERT(ipos >= 0); Q_ASSERT(ipos < GRADIENT_STOPTABLE_SIZE); return data->colorTable[ipos];}#endifstatic void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const QSpanData *data){ v->dx = data->gradient.linear.end.x - data->gradient.linear.origin.x; v->dy = data->gradient.linear.end.y - data->gradient.linear.origin.y; v->l = v->dx * v->dx + v->dy * v->dy; v->off = 0; if (v->l != 0) { v->dx /= v->l; v->dy /= v->l; v->off = -v->dx * data->gradient.linear.origin.x - v->dy * data->gradient.linear.origin.y; }}#ifdef Q_WS_QWSstatic const uint * QT_FASTCALL fetchLinearGradient(uint *buffer, const Operator *op, const QSpanData *data, int y, int x, int length){ const uint *b = buffer; qreal t, inc; bool affine = true; qreal rx=0, ry=0; if (op->linear.l == 0) { t = inc = 0; } else { rx = data->m21 * y + data->m11 * x + data->dx; ry = data->m22 * y + data->m12 * x + data->dy; t = op->linear.dx*rx + op->linear.dy*ry + op->linear.off; inc = op->linear.dx * data->m11 + op->linear.dy * data->m12; affine = !data->m13 && !data->m23; if (affine) { t *= GRADIENT_STOPTABLE_SIZE; inc *= GRADIENT_STOPTABLE_SIZE; } } const uint *end = buffer + length; if (affine) { if (inc > -1e-5 && inc < 1e-5) { QT_MEMFILL_UINT(buffer, length, qt_gradient_pixel_fixed(&data->gradient, int(t * FIXPT_SIZE))); } else { if (t+inc*length < qreal(INT_MAX >> (FIXPT_BITS + 1)) && t+inc*length > qreal(INT_MIN >> (FIXPT_BITS + 1))) { // we can use fixed point math int t_fixed = int(t * FIXPT_SIZE); int inc_fixed = int(inc * FIXPT_SIZE); while (buffer < end) { *buffer = qt_gradient_pixel_fixed(&data->gradient, t_fixed); t_fixed += inc_fixed; ++buffer; } } else { // we have to fall back to float math while (buffer < end) { *buffer = qt_gradient_pixel(&data->gradient, t/GRADIENT_STOPTABLE_SIZE); t += inc; ++buffer; } } } } else { // fall back to float math here as well qreal rw = data->m23 * y + data->m13 * x + 1.; while (buffer < end) { qreal x = rx/rw; qreal y = ry/rw; t = (op->linear.dx*x + op->linear.dy *y) + op->linear.off; *buffer = qt_gradient_pixel(&data->gradient, t); rx += data->m11; ry += data->m12; rw += data->m13; if (!rw) { rw += data->m13; } ++buffer; } } return b;}#elsestatic const uint * QT_FASTCALL fetchLinearGradient(uint *buffer, const Operator *op, const QSpanData *data, int y, int x, int length){ const uint *b = buffer; qreal t, inc; bool affine = true; qreal rx=0, ry=0; if (op->linear.l == 0) { t = inc = 0; } else { rx = data->m21 * y + data->m11 * x + data->dx; ry = data->m22 * y + data->m12 * x + data->dy; t = op->linear.dx*rx + op->linear.dy*ry + op->linear.off; inc = op->linear.dx * data->m11 + op->linear.dy * data->m12; affine = !data->m13 && !data->m23; } const uint *end = buffer + length; if (affine) { if (inc > -1e-6 && inc < 1e-6) { QT_MEMFILL_UINT(buffer, length, qt_gradient_pixel(&data->gradient, t)); } else { while (buffer < end) { *buffer = qt_gradient_pixel(&data->gradient, t); t += inc; ++buffer; } } } else { qreal rw = data->m23 * y + data->m13 * x + 1.; while (buffer < end) { qreal x = rx/rw; qreal y = ry/rw; t = (op->linear.dx*x + op->linear.dy *y) + op->linear.off; *buffer = qt_gradient_pixel(&data->gradient, t); rx += data->m11; ry += data->m12; rw += data->m13; if (!rw) { rw += data->m13; } ++buffer; } } return b;}#endifstatic inline qreal determinant(qreal a, qreal b, qreal c){ return (b * b) - (4 * a * c);}// function to evaluate real rootsstatic inline qreal realRoots(qreal a, qreal b, qreal detSqrt){ return (-b + detSqrt)/(2 * a);}static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v, const QSpanData *data){ v->dx = data->gradient.radial.center.x - data->gradient.radial.focal.x; v->dy = data->gradient.radial.center.y - data->gradient.radial.focal.y; v->a = data->gradient.radial.radius*data->gradient.radial.radius - v->dx*v->dx - v->dy*v->dy;}static const uint * QT_FASTCALL fetchRadialGradient(uint *buffer, const Operator *op, const QSpanData *data, int y, int x, int length){ const uint *b = buffer; qreal rx = data->m21 * (y + 0.5) + data->dx + data->m11 * (x + 0.5); qreal ry = data->m22 * (y + 0.5) + data->dy + data->m12 * (x + 0.5); bool affine = !data->m13 && !data->m23; //qreal r = data->gradient.radial.radius; const uint *end = buffer + length; if (affine) { rx -= data->gradient.radial.focal.x; ry -= data->gradient.radial.focal.y; while (buffer < end) { qreal b = 2*(rx*op->radial.dx + ry*op->radial.dy); qreal det = determinant(op->radial.a, b , -(rx*rx + ry*ry)); qreal s = realRoots(op->radial.a, b, qSqrt(det)); *buffer = qt_gradient_pixel(&data->gradient, s); rx += data->m11; ry += data->m12; ++buffer; } } else { qreal rw = data->m23 * (y + 0.5) + 1. + data->m13 * (x + 0.5); if (!rw) rw = 1; while (buffer < end) { qreal gx = rx/rw - data->gradient.radial.focal.x; qreal gy = ry/rw - data->gradient.radial.focal.y; qreal b = 2*(gx*op->radial.dx + gy*op->radial.dy); qreal det = determinant(op->radial.a, b , -(gx*gx + gy*gy)); qreal s = realRoots(op->radial.a, b, qSqrt(det)); *buffer = qt_gradient_pixel(&data->gradient, s); rx += data->m11; ry += data->m12; rw += data->m13; if (!rw) { rw += data->m13; } ++buffer; } } return b;}static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operator *, const QSpanData *data, int y, int x, int length){ const uint *b = buffer; qreal rx = data->m21 * (y + 0.5) + data->dx + data->m11 * (x + 0.5); qreal ry = data->m22 * (y + 0.5) + data->dy + data->m12 * (x + 0.5); bool affine = !data->m13 && !data->m23; const uint *end = buffer + length; if (affine) { rx -= data->gradient.conical.center.x; ry -= data->gradient.conical.center.y; while (buffer < end) { qreal angle = atan2(ry, rx) + data->gradient.conical.angle; *buffer = qt_gradient_pixel(&data->gradient, 1. - angle / (2*Q_PI)); rx += data->m11; ry += data->m12; ++buffer; } } else { qreal rw = data->m23 * (y + 0.5) + 1. + data->m13 * (x + 0.5); if (!rw) rw = 1; while (buffer < end) { qreal angle = atan2(ry/rw - data->gradient.conical.center.x, rx/rw - data->gradient.conical.center.y) + data->gradient.conical.angle; *buffer = qt_gradient_pixel(&data->gradient, 1. - angle / (2*Q_PI)); rx += data->m11; ry += data->m12; rw += data->m13; if (!rw) { rw += data->m13; } ++buffer; } } return b;}/* The constant alpha factor describes an alpha factor that gets applied to the result of the composition operation combining it with the destination. The intent is that if const_alpha == 0. we get back dest, and if const_alpha == 1. we get the unmodified operation result = src op dest dest = result * const_alpha + dest * (1. - const_alpha) This means that in the comments below, the first line is the const_alpha==255 case, the second line the general one. In the lines below: s == src, sa == alpha(src), sia = 1 - alpha(src) d == dest, da == alpha(dest), dia = 1 - alpha(dest) ca = const_alpha, cia = 1 - const_alpha The methods exist in two variants. One where we have a constant source, the other where the source is an array of pixels.*//* result = 0 d = d * cia*/static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha){ if (const_alpha == 255) { QT_MEMFILL_UINT(dest, length, 0); } else { int ialpha = 255 - const_alpha; for (int i = 0; i < length; ++i) dest[i] = BYTE_MUL(dest[i], ialpha); }}static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha){ if (const_alpha == 255) { QT_MEMFILL_UINT(dest, length, 0); } else { int ialpha = 255 - const_alpha; for (int i = 0; i < length; ++i) dest[i] = BYTE_MUL(dest[i], ialpha); }}/* result = s dest = s * ca + d * cia*/static void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha){ if (const_alpha == 255) { QT_MEMFILL_UINT(dest, length, color); } else { int ialpha = 255 - const_alpha; color = BYTE_MUL(color, const_alpha); for (int i = 0; i < length; ++i) dest[i] = color + BYTE_MUL(dest[i], ialpha); }}static void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha){ if (const_alpha == 255) { ::memcpy(dest, src, length * sizeof(uint)); } else { int ialpha = 255 - const_alpha; for (int i = 0; i < length; ++i) dest[i] = INTERPOLATE_PIXEL_255(src[i], const_alpha, dest[i], ialpha); }}/* result = s + d * sia dest = (s + d * sia) * ca + d * cia = s * ca + d * (sia * ca + cia) = s * ca + d * (1 - sa*ca)*/static void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha){ if ((const_alpha & qAlpha(color)) == 255) { QT_MEMFILL_UINT(dest, length, color); } else { if (const_alpha != 255) color = BYTE_MUL(color, const_alpha); for (int i = 0; i < length; ++i) dest[i] = color + BYTE_MUL(dest[i], qAlpha(~color)); }}static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha){ if (const_alpha == 255) { for (int i = 0; i < length; ++i) { uint s = src[i]; dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s)); } } else { for (int i = 0; i < length; ++i) { uint s = BYTE_MUL(src[i], const_alpha); dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s)); } }}/* result = d + s * dia dest = (d + s * dia) * ca + d * cia = d + s * dia * ca*/static void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha){ if (const_alpha != 255) color = BYTE_MUL(color, const_alpha); for (int i = 0; i < length; ++i) { uint d = dest[i]; dest[i] = d + BYTE_MUL(color, qAlpha(~d)); }}static void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha){ if (const_alpha == 255) { for (int i = 0; i < length; ++i) { uint d = dest[i]; dest[i] = d + BYTE_MUL(src[i], qAlpha(~d)); } } else { for (int i = 0; i < length; ++i) { uint d = dest[i]; uint s = BYTE_MUL(src[i], const_alpha); dest[i] = d + BYTE_MUL(s, qAlpha(~d)); } }}/* result = s * da dest = s * da * ca + d * cia*/static void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha){ if (const_alpha == 255) { for (int i = 0; i < length; ++i) dest[i] = BYTE_MUL(color, qAlpha(dest[i])); } else { color = BYTE_MUL(color, const_alpha); uint cia = 255 - const_alpha; for (int i = 0; i < length; ++i) { uint d = dest[i]; dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(d), d, cia); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -