| 198 | } |
| 199 | |
| 200 | void GuillotineImageAtlas::ProcessGlyphQueue(Layer& layer) const |
| 201 | { |
| 202 | std::vector<UInt8> pixelBuffer; |
| 203 | |
| 204 | for (QueuedGlyph& glyph : layer.queuedGlyphs) |
| 205 | { |
| 206 | unsigned int glyphWidth = glyph.image.GetWidth(); |
| 207 | unsigned int glyphHeight = glyph.image.GetHeight(); |
| 208 | |
| 209 | // Calcul de l'éventuel padding (pixels de contour) |
| 210 | unsigned int paddingX; |
| 211 | unsigned int paddingY; |
| 212 | if (glyph.flipped) |
| 213 | { |
| 214 | paddingX = (glyph.rect.height - glyphWidth)/2; |
| 215 | paddingY = (glyph.rect.width - glyphHeight)/2; |
| 216 | } |
| 217 | else |
| 218 | { |
| 219 | paddingX = (glyph.rect.width - glyphWidth)/2; |
| 220 | paddingY = (glyph.rect.height - glyphHeight)/2; |
| 221 | } |
| 222 | |
| 223 | if (paddingX > 0 || paddingY > 0) |
| 224 | { |
| 225 | // On remplit les contours |
| 226 | pixelBuffer.resize(glyph.rect.width * glyph.rect.height); |
| 227 | std::memset(pixelBuffer.data(), 0, glyph.rect.width*glyph.rect.height*sizeof(UInt8)); |
| 228 | |
| 229 | layer.image->Update(pixelBuffer.data(), glyph.rect); |
| 230 | } |
| 231 | |
| 232 | const UInt8* pixels; |
| 233 | // On copie le glyphe dans l'atlas |
| 234 | if (glyph.flipped) |
| 235 | { |
| 236 | pixelBuffer.resize(glyphHeight * glyphWidth); |
| 237 | |
| 238 | // On tourne le glyphe pour qu'il rentre dans le rectangle |
| 239 | const UInt8* src = glyph.image.GetConstPixels(); |
| 240 | UInt8* ptr = pixelBuffer.data(); |
| 241 | |
| 242 | unsigned int lineStride = glyphWidth*sizeof(UInt8); // BPP = 1 |
| 243 | src += lineStride-1; // Départ en haut à droite |
| 244 | for (unsigned int x = 0; x < glyphWidth; ++x) |
| 245 | { |
| 246 | for (unsigned int y = 0; y < glyphHeight; ++y) |
| 247 | { |
| 248 | *ptr++ = *src; |
| 249 | src += lineStride; |
| 250 | } |
| 251 | |
| 252 | src -= glyphHeight*lineStride + 1; |
| 253 | } |
| 254 | |
| 255 | pixels = pixelBuffer.data(); |
| 256 | std::swap(glyphWidth, glyphHeight); |
| 257 | } |