Files
ppsspp/Common/Render/TextureAtlas.h
T
Henrik RydgårdandClaude Opus 5.5 110fb7fd6a UI: Rounded rectangles from precomputed atlas corners
UIAtlas generates an antialiased white corner for each radius in
ROUND_RECT_RADII (8, 16, 24, 32 UI units) and each style (filled, and
thin/medium/thick outlines from ROUND_RECT_THICKNESS) at the atlas DPI.
DrawBuffer::DrawRoundRect mirrors the corner into all four corners and
stretches the corner's last texel row/column along the edges, so a
round rect is 9 quads (8 for outlines).

Other radii use the nearest corner, scaled. The LogoScreen temporarily
draws some for testing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 01:52:34 +02:00

155 lines
2.6 KiB
C++

#pragma once
#include <cstdint>
#include <cstring>
#include <string_view>
#define ATLAS_MAGIC ('A' | ('T' << 8) | ('L' << 16) | ('A' << 24))
// Metadata file structure v0:
//
// AtlasHeader
// For each image:
// AtlasImage
// For each font:
// AtlasFontHeader
// For each range:
// AtlasRange
// For each char:
// AtlasChar
struct Atlas;
struct ImageID {
public:
ImageID() {}
explicit ImageID(std::string_view _id) : id(_id) {}
static inline ImageID invalid() {
return ImageID{""};
}
bool isValid() const {
return !id.empty();
}
bool isInvalid() const {
return id.empty();
}
bool operator ==(const ImageID &other) {
return id == other.id;
}
bool operator !=(const ImageID &other) {
return id != other.id;
}
private:
std::string_view id;
friend struct Atlas;
};
struct FontID {
public:
explicit FontID(const char *_id) : id(_id) {}
static inline FontID invalid() {
return FontID{ nullptr };
}
bool isInvalid() const {
return id == nullptr;
}
private:
const char *id;
friend struct Atlas;
};
struct AtlasChar {
// texcoords
float sx, sy, ex, ey;
// offset from the origin
float ox, oy;
// distance to move the origin forward
float wx;
// size in pixels
unsigned short pw, ph;
};
struct AtlasCharRange {
int start;
int end;
int result_index;
};
struct AtlasFontHeader {
float padding;
float height;
float ascend;
float distslope;
int numRanges;
int numChars;
char name[32];
};
struct AtlasFont {
AtlasFont() = default;
AtlasFont(const AtlasFont &) = delete;
AtlasFont &operator=(const AtlasFont &) = delete;
~AtlasFont();
float padding;
float height;
float ascend;
float distslope;
const AtlasChar *charData;
const AtlasCharRange *ranges;
int numRanges;
int numChars;
char name[32];
// Returns 0 on no match.
const AtlasChar *getChar(int utf32) const;
};
struct AtlasImage {
float u1, v1, u2, v2;
int w, h;
char name[32];
};
struct AtlasHeader {
int magic;
int version;
int numFonts;
int numImages;
};
struct Atlas {
Atlas() = default;
Atlas(const Atlas &) = delete;
Atlas &operator=(const Atlas &) = delete;
~Atlas();
bool LoadMeta(const uint8_t *data, size_t data_size);
bool IsMetadataLoaded() const {
return images != nullptr;
}
void Clear();
AtlasFont *fonts = nullptr;
int num_fonts = 0;
AtlasImage *images = nullptr;
int num_images = 0;
// Texels per UI unit that generated images were rasterized at. Not stored in metadata.
float dpiScale = 1.0f;
// These are inefficient linear searches, try not to call every frame.
const AtlasFont *getFont(FontID id) const;
const AtlasImage *getImage(ImageID id) const;
bool measureImage(ImageID id, float *w, float *h) const;
};