| 87 | sp<Palette> BitmapFont::getPalette() const { return this->palette; } |
| 88 | |
| 89 | sp<BitmapFont> BitmapFont::loadFont(const std::map<char32_t, UString> &glyphMap, int spaceWidth, |
| 90 | int fontHeight, int kerning, UString fontName, |
| 91 | sp<Palette> defaultPalette) |
| 92 | { |
| 93 | auto font = mksp<BitmapFont>(); |
| 94 | |
| 95 | font->spacewidth = spaceWidth; |
| 96 | font->fontheight = fontHeight; |
| 97 | font->kerning = kerning; |
| 98 | font->averagecharacterwidth = 0; |
| 99 | font->name = fontName; |
| 100 | font->palette = defaultPalette; |
| 101 | |
| 102 | size_t totalGlyphWidth = 0; |
| 103 | |
| 104 | for (auto &p : glyphMap) |
| 105 | { |
| 106 | auto fontImage = fw().data->loadImage(p.second); |
| 107 | if (!fontImage) |
| 108 | { |
| 109 | LogError("Failed to read glyph image \"%s\"", p.second); |
| 110 | continue; |
| 111 | } |
| 112 | auto paletteImage = std::dynamic_pointer_cast<PaletteImage>(fontImage); |
| 113 | if (!paletteImage) |
| 114 | { |
| 115 | LogError("Glyph image \"%s\" doesn't look like a PaletteImage", p.second); |
| 116 | continue; |
| 117 | } |
| 118 | unsigned int maxWidth = 0; |
| 119 | |
| 120 | // FIXME: Proper kerning |
| 121 | // First find the widest non-transparent part of the glyph |
| 122 | { |
| 123 | PaletteImageLock imgLock(paletteImage, ImageLockUse::Read); |
| 124 | for (unsigned int y = 0; y < paletteImage->size.y; y++) |
| 125 | { |
| 126 | for (unsigned int x = 0; x < paletteImage->size.x; x++) |
| 127 | { |
| 128 | if (imgLock.get({x, y}) != 0) |
| 129 | { |
| 130 | if (x > maxWidth) |
| 131 | maxWidth = x; |
| 132 | } |
| 133 | } |
| 134 | } |
| 135 | } |
| 136 | // Trim the glyph to the max non-transparent width |
| 137 | auto trimmedGlyph = mksp<PaletteImage>(Vec2<int>{maxWidth + kerning, fontHeight}); |
| 138 | PaletteImage::blit(paletteImage, trimmedGlyph); |
| 139 | |
| 140 | font->fontbitmaps[p.first] = trimmedGlyph; |
| 141 | totalGlyphWidth += trimmedGlyph->size.x; |
| 142 | } |
| 143 | |
| 144 | font->averagecharacterwidth = totalGlyphWidth / font->fontbitmaps.size(); |
| 145 | |
| 146 | // Always add a 'space' image: |