GlyphData *BMFontRasterizer::getGlyphData(uint32 glyph) const { auto it = characters.find(glyph); // Return an empty GlyphData if we don't have the glyph character. if (it == characters.end()) return new GlyphData(glyph, GlyphMetrics(), GlyphData::FORMAT_RGBA); const BMFontCharacter &c = it->second; GlyphData *g = new GlyphData(glyph, c.metrics, GlyphData::FORMAT_RGBA); const auto &imagepair = images.find(c.page); if (imagepair == images.end()) { g->release(); return new GlyphData(glyph, GlyphMetrics(), GlyphData::FORMAT_RGBA); } image::ImageData *imagedata = imagepair->second.get(); image::pixel *pixels = (image::pixel *) g->getData(); const image::pixel *ipixels = (const image::pixel *) imagedata->getData(); love::thread::Lock lock(imagedata->getMutex()); // Copy the subsection of the texture from the ImageData to the GlyphData. for (int y = 0; y < c.metrics.height; y++) { size_t idindex = (c.y + y) * imagedata->getWidth() + c.x; memcpy(&pixels[y * c.metrics.width], &ipixels[idindex], sizeof(image::pixel) * c.metrics.width); } return g; }
GlyphData * ImageRasterizer::getGlyphData(unsigned short glyph) const { GlyphMetrics gm; gm.height = metrics.height; gm.width = widths[glyph]; gm.advance = spacing[glyph] + widths[glyph]; gm.bearingX = 0; gm.bearingY = 0; GlyphData * g = new GlyphData(glyph, gm, GlyphData::FORMAT_RGBA); if (gm.width == 0) return g; unsigned char * gd = (unsigned char*)g->getData(); love::image::pixel * pixels = (love::image::pixel *)(imageData->getData()); for (unsigned int i = 0; i < widths[glyph]*getHeight(); i++) { love::image::pixel p = pixels[ positions[glyph] + (i % widths[glyph]) + (imageData->getWidth() * (i / widths[glyph])) ]; gd[i*4] = p.r; gd[i*4+1] = p.g; gd[i*4+2] = p.b; gd[i*4+3] = p.a; } return g; }
GlyphData *ImageRasterizer::getGlyphData(uint32 glyph) const { GlyphMetrics gm = {}; // Set relevant glyph metrics if the glyph is in this ImageFont std::map<uint32, ImageGlyphData>::const_iterator it = imageGlyphs.find(glyph); if (it != imageGlyphs.end()) { gm.width = it->second.width; gm.advance = it->second.width + extraSpacing; } gm.height = metrics.height; GlyphData *g = new GlyphData(glyph, gm, GlyphData::FORMAT_RGBA); if (gm.width == 0) return g; // We don't want another thread modifying our ImageData mid-copy. love::thread::Lock lock(imageData->getMutex()); love::image::pixel *gdpixels = (love::image::pixel *) g->getData(); love::image::pixel *imagepixels = (love::image::pixel *) imageData->getData(); // copy glyph pixels from imagedata to glyphdata for (int i = 0; i < g->getWidth() * g->getHeight(); i++) { love::image::pixel p = imagepixels[it->second.x + (i % gm.width) + (imageData->getWidth() * (i / gm.width))]; // Use transparency instead of the spacer color if (equal(p, spacer)) gdpixels[i].r = gdpixels[i].g = gdpixels[i].b = gdpixels[i].a = 0; else gdpixels[i] = p; } return g; }