Changeset - r24899:e3ddcc7e16c9
[Not reviewed]
master
0 6 0
Michael Lutz - 4 years ago 2021-01-16 15:43:30
michi@icosahedron.de
Codechange: Give sprite encoders a hint which colour components of a sprite are filled with useful information.
6 files changed with 21 insertions and 10 deletions:
0 comments (0 inline, 0 general)
src/fontcache.cpp
Show inline comments
 
@@ -348,12 +348,13 @@ const Sprite *TrueTypeFontCache::GetGlyp
 
			static const SpriteLoader::Sprite builtin_questionmark = {
 
				10, // height
 
				8,  // width
 
				0,  // x_offs
 
				0,  // y_offs
 
				ST_FONT,
 
				SCC_PAL,
 
				builtin_questionmark_data
 
			};
 

	
 
			Sprite *spr = BlitterFactory::GetCurrentBlitter()->Encode(&builtin_questionmark, AllocateFont);
 
			assert(spr != nullptr);
 
			GlyphEntry new_glyph;
 
@@ -611,12 +612,13 @@ const Sprite *FreeTypeFontCache::Interna
 
	if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) usererror("Font glyph is too large");
 

	
 
	/* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */
 
	SpriteLoader::Sprite sprite;
 
	sprite.AllocateData(ZOOM_LVL_NORMAL, width * height);
 
	sprite.type = ST_FONT;
 
	sprite.colours = (aa ? SCC_PAL | SCC_ALPHA : SCC_PAL);
 
	sprite.width = width;
 
	sprite.height = height;
 
	sprite.x_offs = slot->bitmap_left;
 
	sprite.y_offs = this->ascender - slot->bitmap_top;
 

	
 
	/* Draw shadow for medium size */
 
@@ -673,13 +675,12 @@ const void *FreeTypeFontCache::InternalG
 
		FT_Load_Sfnt_Table(this->face, tag, 0, result, &len);
 
	}
 

	
 
	length = len;
 
	return result;
 
}
 

	
 
#endif /* WITH_FREETYPE */
 

	
 

	
 
/**
 
 * (Re)initialize the freetype related things, i.e. load the non-sprite fonts.
 
 * @param monospace Whether to initialise the monospace or regular fonts.
src/os/macosx/font_osx.cpp
Show inline comments
 
@@ -283,12 +283,13 @@ const Sprite *CoreTextFontCache::Interna
 
	/* Limit glyph size to prevent overflows later on. */
 
	if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) usererror("Font glyph is too large");
 

	
 
	SpriteLoader::Sprite sprite;
 
	sprite.AllocateData(ZOOM_LVL_NORMAL, width * height);
 
	sprite.type = ST_FONT;
 
	sprite.colours = (use_aa ? SCC_PAL | SCC_ALPHA : SCC_PAL);
 
	sprite.width = width;
 
	sprite.height = height;
 
	sprite.x_offs = (int16)std::round(CGRectGetMinX(bounds));
 
	sprite.y_offs = this->ascender - (int16)std::ceil(CGRectGetMaxY(bounds));
 

	
 
	if (bounds.size.width > 0) {
src/os/windows/font_win32.cpp
Show inline comments
 
@@ -492,12 +492,13 @@ void Win32FontCache::ClearFontCache()
 
	if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) usererror("Font glyph is too large");
 

	
 
	/* GDI has rendered the glyph, now we allocate a sprite and copy the image into it. */
 
	SpriteLoader::Sprite sprite;
 
	sprite.AllocateData(ZOOM_LVL_NORMAL, width * height);
 
	sprite.type = ST_FONT;
 
	sprite.colours = (aa ? SCC_PAL | SCC_ALPHA : SCC_PAL);
 
	sprite.width = width;
 
	sprite.height = height;
 
	sprite.x_offs = gm.gmptGlyphOrigin.x;
 
	sprite.y_offs = this->ascender - gm.gmptGlyphOrigin.y;
 

	
 
	if (size > 0) {
src/spritecache.cpp
Show inline comments
 
@@ -196,12 +196,13 @@ static bool ResizeSpriteIn(SpriteLoader:
 
	if (sprite[src].width * scaled_1 > UINT16_MAX || sprite[src].height * scaled_1 > UINT16_MAX) return false;
 

	
 
	sprite[tgt].width  = sprite[src].width  * scaled_1;
 
	sprite[tgt].height = sprite[src].height * scaled_1;
 
	sprite[tgt].x_offs = sprite[src].x_offs * scaled_1;
 
	sprite[tgt].y_offs = sprite[src].y_offs * scaled_1;
 
	sprite[tgt].colours = sprite[src].colours;
 

	
 
	sprite[tgt].AllocateData(tgt, sprite[tgt].width * sprite[tgt].height);
 

	
 
	SpriteLoader::CommonPixel *dst = sprite[tgt].data;
 
	for (int y = 0; y < sprite[tgt].height; y++) {
 
		const SpriteLoader::CommonPixel *src_ln = &sprite[src].data[y / scaled_1 * sprite[src].width];
 
@@ -218,12 +219,13 @@ static void ResizeSpriteOut(SpriteLoader
 
{
 
	/* Algorithm based on 32bpp_Optimized::ResizeSprite() */
 
	sprite[zoom].width  = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].width,  zoom);
 
	sprite[zoom].height = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].height, zoom);
 
	sprite[zoom].x_offs = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].x_offs, zoom);
 
	sprite[zoom].y_offs = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].y_offs, zoom);
 
	sprite[zoom].colours = sprite[ZOOM_LVL_NORMAL].colours;
 

	
 
	sprite[zoom].AllocateData(zoom, sprite[zoom].height * sprite[zoom].width);
 

	
 
	SpriteLoader::CommonPixel *dst = sprite[zoom].data;
 
	const SpriteLoader::CommonPixel *src = sprite[zoom - 1].data;
 
	const SpriteLoader::CommonPixel *src_end = src + sprite[zoom - 1].height * sprite[zoom - 1].width;
 
@@ -484,12 +486,13 @@ static void *ReadSprite(const SpriteCach
 
		/* Make ZOOM_LVL_NORMAL be ZOOM_LVL_FONT */
 
		sprite[ZOOM_LVL_NORMAL].width  = sprite[ZOOM_LVL_FONT].width;
 
		sprite[ZOOM_LVL_NORMAL].height = sprite[ZOOM_LVL_FONT].height;
 
		sprite[ZOOM_LVL_NORMAL].x_offs = sprite[ZOOM_LVL_FONT].x_offs;
 
		sprite[ZOOM_LVL_NORMAL].y_offs = sprite[ZOOM_LVL_FONT].y_offs;
 
		sprite[ZOOM_LVL_NORMAL].data   = sprite[ZOOM_LVL_FONT].data;
 
		sprite[ZOOM_LVL_NORMAL].colours = sprite[ZOOM_LVL_FONT].colours;
 
	}
 

	
 
	return encoder->Encode(sprite, allocator);
 
}
 

	
 

	
src/spriteloader/grf.cpp
Show inline comments
 
@@ -20,21 +20,12 @@
 
#include "grf.hpp"
 

	
 
#include "../safeguards.h"
 

	
 
extern const byte _palmap_w2d[];
 

	
 
/** The different colour components a sprite can have. */
 
enum SpriteColourComponent {
 
	SCC_RGB   = 1 << 0, ///< Sprite has RGB.
 
	SCC_ALPHA = 1 << 1, ///< Sprite has alpha.
 
	SCC_PAL   = 1 << 2, ///< Sprite has palette data.
 
	SCC_MASK  = SCC_RGB | SCC_ALPHA | SCC_PAL, ///< Mask of valid colour bits.
 
};
 
DECLARE_ENUM_AS_BIT_SET(SpriteColourComponent)
 

	
 
/**
 
 * We found a corrupted sprite. This means that the sprite itself
 
 * contains invalid data or is too small for the given dimensions.
 
 * @param file_slot the file the errored sprite is in
 
 * @param file_pos the location in the file of the errored sprite
 
 * @param line the line where the error occurs.
 
@@ -231,12 +222,13 @@ uint8 LoadSpriteV1(SpriteLoader::Sprite 
 
	ZoomLevel zoom_lvl = (sprite_type != ST_MAPGEN) ? ZOOM_LVL_OUT_4X : ZOOM_LVL_NORMAL;
 

	
 
	sprite[zoom_lvl].height = FioReadByte();
 
	sprite[zoom_lvl].width  = FioReadWord();
 
	sprite[zoom_lvl].x_offs = FioReadWord();
 
	sprite[zoom_lvl].y_offs = FioReadWord();
 
	sprite[zoom_lvl].colours = SCC_PAL;
 

	
 
	if (sprite[zoom_lvl].width > INT16_MAX) {
 
		WarnCorruptSprite(file_slot, file_pos, __LINE__);
 
		return 0;
 
	}
 

	
 
@@ -299,12 +291,14 @@ uint8 LoadSpriteV2(SpriteLoader::Sprite 
 
			/* Convert colour depth to pixel size. */
 
			int bpp = 0;
 
			if (colour & SCC_RGB)   bpp += 3; // Has RGB data.
 
			if (colour & SCC_ALPHA) bpp++;    // Has alpha data.
 
			if (colour & SCC_PAL)   bpp++;    // Has palette data.
 

	
 
			sprite[zoom_lvl].colours = (SpriteColourComponent)colour;
 

	
 
			/* For chunked encoding we store the decompressed size in the file,
 
			 * otherwise we can calculate it from the image dimensions. */
 
			uint decomp_size = (type & 0x08) ? FioReadDword() : sprite[zoom_lvl].width * sprite[zoom_lvl].height * bpp;
 

	
 
			bool valid = DecodeSingleSprite(&sprite[zoom_lvl], file_slot, file_pos, sprite_type, decomp_size, type, zoom_lvl, colour, 2);
 
			if (FioGetPos() != start_pos + num) {
src/spriteloader/spriteloader.hpp
Show inline comments
 
@@ -8,17 +8,27 @@
 
/** @file spriteloader.hpp Base for loading sprites. */
 

	
 
#ifndef SPRITELOADER_HPP
 
#define SPRITELOADER_HPP
 

	
 
#include "../core/alloc_type.hpp"
 
#include "../core/enum_type.hpp"
 
#include "../gfx_type.h"
 

	
 
struct Sprite;
 
typedef void *AllocatorProc(size_t size);
 

	
 
/** The different colour components a sprite can have. */
 
enum SpriteColourComponent {
 
	SCC_RGB   = 1 << 0, ///< Sprite has RGB.
 
	SCC_ALPHA = 1 << 1, ///< Sprite has alpha.
 
	SCC_PAL   = 1 << 2, ///< Sprite has palette data.
 
	SCC_MASK  = SCC_RGB | SCC_ALPHA | SCC_PAL, ///< Mask of valid colour bits.
 
};
 
DECLARE_ENUM_AS_BIT_SET(SpriteColourComponent)
 

	
 
/** Interface for the loader of our sprites. */
 
class SpriteLoader {
 
public:
 
	/** Definition of a common pixel in OpenTTD's realm. */
 
	struct CommonPixel {
 
		uint8 r;  ///< Red-channel
 
@@ -37,12 +47,13 @@ public:
 
	struct Sprite {
 
		uint16 height;                   ///< Height of the sprite
 
		uint16 width;                    ///< Width of the sprite
 
		int16 x_offs;                    ///< The x-offset of where the sprite will be drawn
 
		int16 y_offs;                    ///< The y-offset of where the sprite will be drawn
 
		SpriteType type;                 ///< The sprite type
 
		SpriteColourComponent colours;   ///< The colour components of the sprite with useful information.
 
		SpriteLoader::CommonPixel *data; ///< The sprite itself
 

	
 
		/**
 
		 * Allocate the sprite data of this sprite.
 
		 * @param zoom Zoom level to allocate the data for.
 
		 * @param size the minimum size of the data field.
0 comments (0 inline, 0 general)