* @brief Builds the (2r+1)^2 9-slice atlas: corner tiles + 1px edge gradients + transparent center. */
| 121 | * @brief Builds the (2r+1)^2 9-slice atlas: corner tiles + 1px edge gradients + transparent center. |
| 122 | */ |
| 123 | QImage buildShadowAtlas(int radius) |
| 124 | { |
| 125 | const int n = 2 * radius + 1; |
| 126 | QImage atlas(n, n, QImage::Format_ARGB32_Premultiplied); |
| 127 | atlas.fill(Qt::transparent); |
| 128 | |
| 129 | const QImage corner = generateShadowCorner(radius); |
| 130 | const qreal inv = radius > 0 ? 1.0 / radius : 0.0; |
| 131 | |
| 132 | QImage hEdge(1, radius, QImage::Format_ARGB32_Premultiplied); |
| 133 | hEdge.fill(Qt::transparent); |
| 134 | for (int y = 0; y < radius; ++y) { |
| 135 | qreal a = 1.0 - static_cast<qreal>(radius - y - 1) * inv; |
| 136 | a = a * a * (3.0 - 2.0 * a) * CSD::ShadowOpacity; |
| 137 | hEdge.setPixelColor(0, y, QColor(0, 0, 0, qRound(a * 255))); |
| 138 | } |
| 139 | |
| 140 | QImage vEdge(radius, 1, QImage::Format_ARGB32_Premultiplied); |
| 141 | vEdge.fill(Qt::transparent); |
| 142 | for (int x = 0; x < radius; ++x) { |
| 143 | qreal a = 1.0 - static_cast<qreal>(x) * inv; |
| 144 | a = a * a * (3.0 - 2.0 * a) * CSD::ShadowOpacity; |
| 145 | vEdge.setPixelColor(x, 0, QColor(0, 0, 0, qRound(a * 255))); |
| 146 | } |
| 147 | |
| 148 | QPainter p(&atlas); |
| 149 | p.setCompositionMode(QPainter::CompositionMode_Source); |
| 150 | p.drawImage(0, 0, corner); |
| 151 | p.drawImage(radius + 1, 0, corner.flipped(Qt::Horizontal)); |
| 152 | p.drawImage(0, radius + 1, corner.flipped(Qt::Vertical)); |
| 153 | p.drawImage(radius + 1, radius + 1, corner.flipped(Qt::Horizontal | Qt::Vertical)); |
| 154 | p.drawImage(radius, 0, hEdge); |
| 155 | p.drawImage(radius, radius + 1, hEdge.flipped(Qt::Vertical)); |
| 156 | p.drawImage(0, radius, vEdge.flipped(Qt::Horizontal)); |
| 157 | p.drawImage(radius + 1, radius, vEdge); |
| 158 | p.end(); |
| 159 | |
| 160 | return atlas; |
| 161 | } |
| 162 | |
| 163 | /** |
| 164 | * @brief Serves the shadow 9-slice atlas to BorderImage; "image://csdshadow/<radius>". |
no test coverage detected