mirror of
				https://github.com/NoelFB/blah.git
				synced 2025-11-04 01:41:34 +08:00 
			
		
		
		
	various memory cleanup, move/copy simplifications
This commit is contained in:
		@ -14,14 +14,6 @@ SpriteFont::CharRange::CharRange(Codepoint from, Codepoint to)
 | 
			
		||||
 | 
			
		||||
const SpriteFont::CharSet SpriteFont::CharRange::ASCII = SpriteFont::CharSet({ CharRange(32, 128) });
 | 
			
		||||
 | 
			
		||||
SpriteFont::SpriteFont()
 | 
			
		||||
{
 | 
			
		||||
	size = 0;
 | 
			
		||||
	ascent = 0;
 | 
			
		||||
	descent = 0;
 | 
			
		||||
	line_gap = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SpriteFont::SpriteFont(const FilePath& file, float size)
 | 
			
		||||
{
 | 
			
		||||
	rebuild(file, size, CharRange::ASCII);
 | 
			
		||||
@ -32,52 +24,22 @@ SpriteFont::SpriteFont(const FilePath& file, float size, const CharSet& charset)
 | 
			
		||||
	rebuild(file, size, charset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SpriteFont::SpriteFont(const Font& font, float size)
 | 
			
		||||
SpriteFont::SpriteFont(const FontRef& font, float size)
 | 
			
		||||
{
 | 
			
		||||
	rebuild(font, size, CharRange::ASCII);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SpriteFont::SpriteFont(const Font& font, float size, const CharSet& charset)
 | 
			
		||||
SpriteFont::SpriteFont(const FontRef& font, float size, const CharSet& charset)
 | 
			
		||||
{
 | 
			
		||||
	rebuild(font, size, charset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SpriteFont::SpriteFont(SpriteFont&& src) noexcept
 | 
			
		||||
{
 | 
			
		||||
	name = src.name;
 | 
			
		||||
	size = src.size;
 | 
			
		||||
	ascent = src.ascent;
 | 
			
		||||
	descent = src.descent;
 | 
			
		||||
	line_gap = src.line_gap;
 | 
			
		||||
	m_characters = std::move(src.m_characters);
 | 
			
		||||
	m_kerning = std::move(src.m_kerning);
 | 
			
		||||
	m_atlas = std::move(src.m_atlas);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SpriteFont::~SpriteFont()
 | 
			
		||||
{
 | 
			
		||||
	dispose();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SpriteFont::dispose()
 | 
			
		||||
void SpriteFont::clear()
 | 
			
		||||
{
 | 
			
		||||
	m_atlas.clear();
 | 
			
		||||
	m_characters.clear();
 | 
			
		||||
	m_kerning.clear();
 | 
			
		||||
	name.dispose();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SpriteFont& SpriteFont::operator=(SpriteFont && src) noexcept
 | 
			
		||||
{
 | 
			
		||||
	name = src.name;
 | 
			
		||||
	size = src.size;
 | 
			
		||||
	ascent = src.ascent;
 | 
			
		||||
	descent = src.descent;
 | 
			
		||||
	line_gap = src.line_gap;
 | 
			
		||||
	m_characters = std::move(src.m_characters);
 | 
			
		||||
	m_kerning = std::move(src.m_kerning);
 | 
			
		||||
	m_atlas = std::move(src.m_atlas);
 | 
			
		||||
	return *this;
 | 
			
		||||
	name.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float SpriteFont::width_of(const String& text) const
 | 
			
		||||
@ -86,7 +48,7 @@ float SpriteFont::width_of(const String& text) const
 | 
			
		||||
	float line_width = 0;
 | 
			
		||||
 | 
			
		||||
	Codepoint last = 0;
 | 
			
		||||
	for (int i = 0; i < text.length(); i ++)
 | 
			
		||||
	for (int i = 0; i < text.length(); i += text.utf8_length(i))
 | 
			
		||||
	{
 | 
			
		||||
		if (text[i] == '\n')
 | 
			
		||||
		{
 | 
			
		||||
@ -94,21 +56,12 @@ float SpriteFont::width_of(const String& text) const
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// get codepoint
 | 
			
		||||
		auto next = text.utf8_at(i);
 | 
			
		||||
 | 
			
		||||
		// increment length
 | 
			
		||||
		line_width += this->operator[](next).advance;
 | 
			
		||||
		
 | 
			
		||||
		// add kerning
 | 
			
		||||
		line_width += get_character(next).advance;
 | 
			
		||||
		if (i > 0)
 | 
			
		||||
			line_width += get_kerning(last, next);
 | 
			
		||||
 | 
			
		||||
		if (line_width > width)
 | 
			
		||||
			width = line_width;
 | 
			
		||||
 | 
			
		||||
		// move to thext utf8 character
 | 
			
		||||
		i += text.utf8_length(i) - 1;
 | 
			
		||||
		last = next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -123,26 +76,15 @@ float SpriteFont::width_of_line(const String& text, int start) const
 | 
			
		||||
	float width = 0;
 | 
			
		||||
 | 
			
		||||
	Codepoint last = 0;
 | 
			
		||||
	for (auto i = start; i < text.length(); i ++)
 | 
			
		||||
	for (auto i = start; i < text.length(); i += text.utf8_length(i))
 | 
			
		||||
	{
 | 
			
		||||
		if (text[i] == '\n')
 | 
			
		||||
			return width;
 | 
			
		||||
 | 
			
		||||
		// get codepoint
 | 
			
		||||
		auto next = text.utf8_at(i);
 | 
			
		||||
 | 
			
		||||
		// increment length
 | 
			
		||||
		width += this->operator[](next).advance;
 | 
			
		||||
		
 | 
			
		||||
		// add kerning
 | 
			
		||||
		width += get_character(next).advance;
 | 
			
		||||
		if (i > 0)
 | 
			
		||||
			width += get_kerning(last, next);
 | 
			
		||||
 | 
			
		||||
		// move to thext utf8 character
 | 
			
		||||
		auto len = text.utf8_length(i);
 | 
			
		||||
		if (len > 0)
 | 
			
		||||
			i += len - 1;
 | 
			
		||||
 | 
			
		||||
		last = next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -155,11 +97,10 @@ float SpriteFont::height_of(const String& text) const
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	float height = line_height();
 | 
			
		||||
	for (auto i = 0; i < text.length(); i ++)
 | 
			
		||||
	for (auto i = 0; i < text.length(); i += text.utf8_length(i))
 | 
			
		||||
	{
 | 
			
		||||
		if (text[i] == '\n')
 | 
			
		||||
			height += line_height();
 | 
			
		||||
		i += text.utf8_length(i) - 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return height - line_gap;
 | 
			
		||||
@ -167,23 +108,24 @@ float SpriteFont::height_of(const String& text) const
 | 
			
		||||
 | 
			
		||||
void SpriteFont::rebuild(const FilePath& file, float sz, const CharSet& charset)
 | 
			
		||||
{
 | 
			
		||||
	dispose();
 | 
			
		||||
	clear();
 | 
			
		||||
 | 
			
		||||
	Font font(file);
 | 
			
		||||
	if (font.is_valid())
 | 
			
		||||
	if (auto font = Font::create(file))
 | 
			
		||||
		rebuild(font, sz, charset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SpriteFont::rebuild(const Font& font, float size, const CharSet& charset)
 | 
			
		||||
void SpriteFont::rebuild(const FontRef& font, float size, const CharSet& charset)
 | 
			
		||||
{
 | 
			
		||||
	dispose();
 | 
			
		||||
	clear();
 | 
			
		||||
	if (!font)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	float scale = font.get_scale(size);
 | 
			
		||||
	float scale = font->get_scale(size);
 | 
			
		||||
 | 
			
		||||
	name = font.family_name();
 | 
			
		||||
	ascent = font.ascent() * scale;
 | 
			
		||||
	descent = font.descent() * scale;
 | 
			
		||||
	line_gap = font.line_gap() * scale;
 | 
			
		||||
	name = font->family_name();
 | 
			
		||||
	ascent = font->ascent() * scale;
 | 
			
		||||
	descent = font->descent() * scale;
 | 
			
		||||
	line_gap = font->line_gap() * scale;
 | 
			
		||||
	this->size = size;
 | 
			
		||||
 | 
			
		||||
	Packer packer;
 | 
			
		||||
@ -203,12 +145,12 @@ void SpriteFont::rebuild(const Font& font, float size, const CharSet& charset)
 | 
			
		||||
 | 
			
		||||
		for (auto i = from; i < to; i++)
 | 
			
		||||
		{
 | 
			
		||||
			auto glyph = font.get_glyph(i);
 | 
			
		||||
			auto glyph = font->get_glyph(i);
 | 
			
		||||
			if (glyph <= 0)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			// add character
 | 
			
		||||
			auto ch = font.get_character(glyph, scale);
 | 
			
		||||
			auto ch = font->get_character(glyph, scale);
 | 
			
		||||
			auto& sfch = get_character(i);
 | 
			
		||||
			sfch.codepoint = i;
 | 
			
		||||
			sfch.advance = ch.advance;
 | 
			
		||||
@ -220,7 +162,7 @@ void SpriteFont::rebuild(const Font& font, float size, const CharSet& charset)
 | 
			
		||||
				if (buffer.size() < ch.width * ch.height)
 | 
			
		||||
					buffer.resize(ch.width * ch.height);
 | 
			
		||||
 | 
			
		||||
				if (font.get_image(ch, buffer.data()))
 | 
			
		||||
				if (font->get_image(ch, buffer.data()))
 | 
			
		||||
					packer.add(i, ch.width, ch.height, buffer.data());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@ -242,7 +184,7 @@ void SpriteFont::rebuild(const Font& font, float size, const CharSet& charset)
 | 
			
		||||
	{
 | 
			
		||||
		for (auto& b : m_characters)
 | 
			
		||||
		{
 | 
			
		||||
			auto kerning_value = font.get_kerning(a.glyph, b.glyph, scale);
 | 
			
		||||
			auto kerning_value = font->get_kerning(a.glyph, b.glyph, scale);
 | 
			
		||||
			if (kerning_value != 0)
 | 
			
		||||
				set_kerning(a.codepoint, b.codepoint, kerning_value);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -32,105 +32,44 @@ namespace
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Font::Font()
 | 
			
		||||
FontRef Font::create(Stream& stream)
 | 
			
		||||
{
 | 
			
		||||
	m_font = nullptr;
 | 
			
		||||
	m_data = nullptr;
 | 
			
		||||
	m_ascent = 0;
 | 
			
		||||
	m_descent = 0;
 | 
			
		||||
	m_line_gap = 0;
 | 
			
		||||
	m_valid = false;
 | 
			
		||||
	if (!stream.is_readable())
 | 
			
		||||
	{
 | 
			
		||||
		Log::error("Unable to load a font as the Stream was not readable");
 | 
			
		||||
		return FontRef();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// read into buffer
 | 
			
		||||
	Vector<u8> buffer;
 | 
			
		||||
	buffer.reserve(stream.length());
 | 
			
		||||
	stream.read(buffer.data(), stream.length());
 | 
			
		||||
 | 
			
		||||
	// init font
 | 
			
		||||
	auto stbtt = Ref<stbtt_fontinfo>(new stbtt_fontinfo());
 | 
			
		||||
	auto fn = (stbtt_fontinfo*)stbtt.get();
 | 
			
		||||
	if (stbtt_InitFont(fn, buffer.data(), 0) == 0)
 | 
			
		||||
	{
 | 
			
		||||
		Log::error("Unable to parse Font file");
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// setup
 | 
			
		||||
	auto font = FontRef(new Font());
 | 
			
		||||
	font->m_font = stbtt;
 | 
			
		||||
	font->m_buffer = std::move(buffer);
 | 
			
		||||
	font->m_family_name = get_font_name(fn, 1);
 | 
			
		||||
	font->m_style_name = get_font_name(fn, 2);
 | 
			
		||||
	stbtt_GetFontVMetrics(fn, &font->m_ascent, &font->m_descent, &font->m_line_gap);
 | 
			
		||||
	return font;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Font::Font(Stream& stream) : Font()
 | 
			
		||||
{
 | 
			
		||||
	load(stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Font::Font(const FilePath& path) : Font()
 | 
			
		||||
FontRef Font::create(const FilePath& path)
 | 
			
		||||
{
 | 
			
		||||
	FileStream fs(path, FileMode::OpenRead);
 | 
			
		||||
	if (fs.is_readable())
 | 
			
		||||
		load(fs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Font::Font(Font&& src) noexcept
 | 
			
		||||
{
 | 
			
		||||
	m_font = src.m_font;
 | 
			
		||||
	m_data = src.m_data;
 | 
			
		||||
	m_family_name = src.m_family_name;
 | 
			
		||||
	m_style_name = src.m_style_name;
 | 
			
		||||
	m_ascent = src.m_ascent;
 | 
			
		||||
	m_descent = src.m_descent;
 | 
			
		||||
	m_line_gap = src.m_line_gap;
 | 
			
		||||
	m_valid = src.m_valid;
 | 
			
		||||
 | 
			
		||||
	src.m_family_name.clear();
 | 
			
		||||
	src.m_style_name.clear();
 | 
			
		||||
	src.m_valid = false;
 | 
			
		||||
	src.m_font = nullptr;
 | 
			
		||||
	src.m_data = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Font& Font::operator=(Font&& src) noexcept
 | 
			
		||||
{
 | 
			
		||||
	m_font = src.m_font;
 | 
			
		||||
	m_data = src.m_data;
 | 
			
		||||
	m_family_name = src.m_family_name;
 | 
			
		||||
	m_style_name = src.m_style_name;
 | 
			
		||||
	m_ascent = src.m_ascent;
 | 
			
		||||
	m_descent = src.m_descent;
 | 
			
		||||
	m_line_gap = src.m_line_gap;
 | 
			
		||||
	m_valid = src.m_valid;
 | 
			
		||||
 | 
			
		||||
	src.m_family_name.clear();
 | 
			
		||||
	src.m_style_name.clear();
 | 
			
		||||
	src.m_valid = false;
 | 
			
		||||
	src.m_font = nullptr;
 | 
			
		||||
	src.m_data = nullptr;
 | 
			
		||||
	return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Font::~Font()
 | 
			
		||||
{
 | 
			
		||||
	dispose();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Font::load(Stream& stream)
 | 
			
		||||
{
 | 
			
		||||
	dispose();
 | 
			
		||||
 | 
			
		||||
	if (!stream.is_readable())
 | 
			
		||||
	{
 | 
			
		||||
		BLAH_ASSERT(false, "Unable to load a font as the Stream was not readable");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// create data buffer
 | 
			
		||||
	auto size = stream.length();
 | 
			
		||||
	m_data = new unsigned char[size];
 | 
			
		||||
	stream.read(m_data, size);
 | 
			
		||||
 | 
			
		||||
	// init font
 | 
			
		||||
	m_font = new stbtt_fontinfo();
 | 
			
		||||
	auto fn = (stbtt_fontinfo*)m_font;
 | 
			
		||||
	stbtt_InitFont(fn, m_data, 0);
 | 
			
		||||
	m_family_name = get_font_name(fn, 1);
 | 
			
		||||
	m_style_name = get_font_name(fn, 2);
 | 
			
		||||
	
 | 
			
		||||
	// properties
 | 
			
		||||
	stbtt_GetFontVMetrics(fn, &m_ascent, &m_descent, &m_line_gap);
 | 
			
		||||
	m_valid = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Font::dispose()
 | 
			
		||||
{
 | 
			
		||||
	delete (stbtt_fontinfo*)m_font;
 | 
			
		||||
	delete[] m_data;
 | 
			
		||||
	m_font = nullptr;
 | 
			
		||||
	m_data = nullptr;
 | 
			
		||||
	m_family_name.dispose();
 | 
			
		||||
	m_style_name.dispose();
 | 
			
		||||
		return create(fs);
 | 
			
		||||
	return FontRef();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const String& Font::family_name() const
 | 
			
		||||
@ -172,7 +111,7 @@ int Font::get_glyph(Codepoint codepoint) const
 | 
			
		||||
{
 | 
			
		||||
	if (!m_font)
 | 
			
		||||
		return 0;
 | 
			
		||||
	return stbtt_FindGlyphIndex((stbtt_fontinfo*)m_font, codepoint);
 | 
			
		||||
	return stbtt_FindGlyphIndex((stbtt_fontinfo*)m_font.get(), codepoint);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float Font::get_scale(float size) const
 | 
			
		||||
@ -180,14 +119,14 @@ float Font::get_scale(float size) const
 | 
			
		||||
	if (!m_font)
 | 
			
		||||
		return 0;
 | 
			
		||||
	
 | 
			
		||||
	return stbtt_ScaleForMappingEmToPixels((stbtt_fontinfo*)m_font, size);
 | 
			
		||||
	return stbtt_ScaleForMappingEmToPixels((stbtt_fontinfo*)m_font.get(), size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float Font::get_kerning(int glyph1, int glyph2, float scale) const
 | 
			
		||||
{
 | 
			
		||||
	if (!m_font)
 | 
			
		||||
		return 0;
 | 
			
		||||
	return stbtt_GetGlyphKernAdvance((stbtt_fontinfo*)m_font, glyph1, glyph2) * scale;
 | 
			
		||||
	return stbtt_GetGlyphKernAdvance((stbtt_fontinfo*)m_font.get(), glyph1, glyph2) * scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Font::Character Font::get_character(int glyph, float scale) const
 | 
			
		||||
@ -199,8 +138,8 @@ Font::Character Font::get_character(int glyph, float scale) const
 | 
			
		||||
 | 
			
		||||
	int advance, offsetX, x0, y0, x1, y1;
 | 
			
		||||
 | 
			
		||||
	stbtt_GetGlyphHMetrics((stbtt_fontinfo*)m_font, glyph, &advance, &offsetX);
 | 
			
		||||
	stbtt_GetGlyphBitmapBox((stbtt_fontinfo*)m_font, glyph, scale, scale, &x0, &y0, &x1, &y1);
 | 
			
		||||
	stbtt_GetGlyphHMetrics((stbtt_fontinfo*)m_font.get(), glyph, &advance, &offsetX);
 | 
			
		||||
	stbtt_GetGlyphBitmapBox((stbtt_fontinfo*)m_font.get(), glyph, scale, scale, &x0, &y0, &x1, &y1);
 | 
			
		||||
 | 
			
		||||
	int w = (x1 - x0);
 | 
			
		||||
	int h = (y1 - y0);
 | 
			
		||||
@ -213,7 +152,7 @@ Font::Character Font::get_character(int glyph, float scale) const
 | 
			
		||||
	ch.offset_x = offsetX * scale;
 | 
			
		||||
	ch.offset_y = (float)y0;
 | 
			
		||||
	ch.scale = scale;
 | 
			
		||||
	ch.has_glyph = (w > 0 && h > 0 && stbtt_IsGlyphEmpty((stbtt_fontinfo*)m_font, glyph) == 0);
 | 
			
		||||
	ch.has_glyph = (w > 0 && h > 0 && stbtt_IsGlyphEmpty((stbtt_fontinfo*)m_font.get(), glyph) == 0);
 | 
			
		||||
 | 
			
		||||
	return ch;
 | 
			
		||||
}
 | 
			
		||||
@ -225,7 +164,7 @@ bool Font::get_image(const Font::Character& ch, Color* pixels) const
 | 
			
		||||
		// we actually use the image buffer as our temporary buffer, and fill the pixels out backwards after
 | 
			
		||||
		// kinda weird but it works & saves creating more memory
 | 
			
		||||
		auto* src = (unsigned char*)pixels;
 | 
			
		||||
		stbtt_MakeGlyphBitmap((stbtt_fontinfo*)m_font, src, ch.width, ch.height, ch.width, ch.scale, ch.scale, ch.glyph);
 | 
			
		||||
		stbtt_MakeGlyphBitmap((stbtt_fontinfo*)m_font.get(), src, ch.width, ch.height, ch.width, ch.scale, ch.scale, ch.glyph);
 | 
			
		||||
 | 
			
		||||
		int len = ch.width * ch.height;
 | 
			
		||||
		for (int a = (len - 1) * 4, b = (len - 1); b >= 0; a -= 4, b -= 1)
 | 
			
		||||
@ -250,9 +189,4 @@ Image Font::get_image(const Font::Character& ch) const
 | 
			
		||||
		return img;
 | 
			
		||||
 | 
			
		||||
	return Image();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Font::is_valid() const
 | 
			
		||||
{
 | 
			
		||||
	return m_valid;
 | 
			
		||||
}
 | 
			
		||||
@ -11,36 +11,6 @@ Packer::Packer()
 | 
			
		||||
Packer::Packer(int max_size, int spacing, bool power_of_two)
 | 
			
		||||
	: max_size(max_size), power_of_two(power_of_two), spacing(spacing), padding(1), m_dirty(false) { }
 | 
			
		||||
 | 
			
		||||
Packer::Packer(Packer&& src) noexcept
 | 
			
		||||
{
 | 
			
		||||
	max_size = src.max_size;
 | 
			
		||||
	power_of_two = src.power_of_two;
 | 
			
		||||
	spacing = src.spacing;
 | 
			
		||||
	padding = src.padding;
 | 
			
		||||
	m_dirty = src.m_dirty;
 | 
			
		||||
	pages = std::move(src.pages);
 | 
			
		||||
	m_entries = std::move(src.m_entries);
 | 
			
		||||
	m_buffer = std::move(src.m_buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Packer& Packer::operator=(Packer&& src) noexcept
 | 
			
		||||
{
 | 
			
		||||
	max_size = src.max_size;
 | 
			
		||||
	power_of_two = src.power_of_two;
 | 
			
		||||
	spacing = src.spacing;
 | 
			
		||||
	padding = src.padding;
 | 
			
		||||
	m_dirty = src.m_dirty;
 | 
			
		||||
	pages = std::move(src.pages);
 | 
			
		||||
	m_entries = std::move(src.m_entries);
 | 
			
		||||
	m_buffer = std::move(src.m_buffer);
 | 
			
		||||
	return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Packer::~Packer()
 | 
			
		||||
{
 | 
			
		||||
	dispose();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Packer::add(u64 id, int width, int height, const Color* pixels)
 | 
			
		||||
{
 | 
			
		||||
	add_entry(id, width, height, pixels, Recti(0, 0, width, height));
 | 
			
		||||
@ -308,17 +278,7 @@ void Packer::clear()
 | 
			
		||||
{
 | 
			
		||||
	pages.clear();
 | 
			
		||||
	m_entries.clear();
 | 
			
		||||
	m_dirty = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Packer::dispose()
 | 
			
		||||
{
 | 
			
		||||
	pages.clear();
 | 
			
		||||
	m_entries.clear();
 | 
			
		||||
	m_buffer.close();
 | 
			
		||||
	max_size = 0;
 | 
			
		||||
	power_of_two = 0;
 | 
			
		||||
	spacing = 0;
 | 
			
		||||
	m_buffer.clear();
 | 
			
		||||
	m_dirty = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,51 +3,14 @@
 | 
			
		||||
 | 
			
		||||
using namespace Blah;
 | 
			
		||||
 | 
			
		||||
BufferStream::BufferStream()
 | 
			
		||||
	: m_buffer(nullptr), m_capacity(0), m_length(0), m_position(0) {}
 | 
			
		||||
 | 
			
		||||
BufferStream::BufferStream(int capacity)
 | 
			
		||||
	: m_buffer(nullptr), m_capacity(0), m_length(0), m_position(0)
 | 
			
		||||
{
 | 
			
		||||
	if (capacity > 0)
 | 
			
		||||
	{
 | 
			
		||||
		m_buffer = new char[capacity];
 | 
			
		||||
		m_capacity = capacity;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BufferStream::BufferStream(BufferStream&& src) noexcept
 | 
			
		||||
{
 | 
			
		||||
	m_buffer = src.m_buffer;
 | 
			
		||||
	m_length = src.m_length;
 | 
			
		||||
	m_capacity = src.m_capacity;
 | 
			
		||||
	m_position = src.m_position;
 | 
			
		||||
	src.m_buffer = nullptr;
 | 
			
		||||
	src.m_position = src.m_length = src.m_capacity = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BufferStream& BufferStream::operator=(BufferStream&& src) noexcept
 | 
			
		||||
{
 | 
			
		||||
	close();
 | 
			
		||||
 | 
			
		||||
	m_buffer = src.m_buffer;
 | 
			
		||||
	m_length = src.m_length;
 | 
			
		||||
	m_capacity = src.m_capacity;
 | 
			
		||||
	m_position = src.m_position;
 | 
			
		||||
	src.m_buffer = nullptr;
 | 
			
		||||
	src.m_position = src.m_length = src.m_capacity = 0;
 | 
			
		||||
 | 
			
		||||
	return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BufferStream::~BufferStream()
 | 
			
		||||
{
 | 
			
		||||
	delete[] m_buffer;
 | 
			
		||||
	m_buffer.resize(capacity);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t BufferStream::length() const
 | 
			
		||||
{
 | 
			
		||||
	return m_length;
 | 
			
		||||
	return m_buffer.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t BufferStream::position() const
 | 
			
		||||
@ -55,23 +18,20 @@ size_t BufferStream::position() const
 | 
			
		||||
	return m_position;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t BufferStream::seek(size_t seekTo)
 | 
			
		||||
size_t BufferStream::seek(size_t seek_to)
 | 
			
		||||
{
 | 
			
		||||
	return m_position = (seekTo < 0 ? 0 : (seekTo > m_length ? m_length : seekTo));
 | 
			
		||||
	return m_position = (seek_to < 0 ? 0 : (seek_to > m_buffer.size() ? m_buffer.size() : seek_to));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t BufferStream::read_data(void* ptr, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	if (m_buffer == nullptr || ptr == nullptr)
 | 
			
		||||
	if (ptr == nullptr || len <= 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (len < 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
	if (len > m_buffer.size() - m_position)
 | 
			
		||||
		len = m_buffer.size() - m_position;
 | 
			
		||||
 | 
			
		||||
	if (len > m_length - m_position)
 | 
			
		||||
		len = m_length - m_position;
 | 
			
		||||
 | 
			
		||||
	memcpy(ptr, m_buffer + m_position, (size_t)len);
 | 
			
		||||
	memcpy(ptr, m_buffer.data() + m_position, (size_t)len);
 | 
			
		||||
	m_position += len;
 | 
			
		||||
	return len;
 | 
			
		||||
}
 | 
			
		||||
@ -82,12 +42,12 @@ size_t BufferStream::write_data(const void* ptr, size_t len)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	// resize
 | 
			
		||||
	if (m_position + len > m_length)
 | 
			
		||||
	if (m_position + len > m_buffer.size())
 | 
			
		||||
		resize(m_position + len);
 | 
			
		||||
 | 
			
		||||
	// copy data
 | 
			
		||||
	if (ptr != nullptr)
 | 
			
		||||
		memcpy(m_buffer + m_position, ptr, (size_t)len);
 | 
			
		||||
		memcpy(m_buffer.data() + m_position, ptr, (size_t)len);
 | 
			
		||||
 | 
			
		||||
	// increment position
 | 
			
		||||
	m_position += len;
 | 
			
		||||
@ -96,70 +56,27 @@ size_t BufferStream::write_data(const void* ptr, size_t len)
 | 
			
		||||
	return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BufferStream::is_open() const
 | 
			
		||||
{
 | 
			
		||||
	return m_buffer != nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BufferStream::is_readable() const
 | 
			
		||||
{
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BufferStream::is_writable() const
 | 
			
		||||
{
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
bool BufferStream::is_open() const { return true; }
 | 
			
		||||
bool BufferStream::is_readable() const { return true; }
 | 
			
		||||
bool BufferStream::is_writable() const { return true; }
 | 
			
		||||
 | 
			
		||||
void BufferStream::resize(size_t length)
 | 
			
		||||
{
 | 
			
		||||
	if (m_capacity > length)
 | 
			
		||||
	{
 | 
			
		||||
		m_length = length;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		auto last_capacity = m_capacity;
 | 
			
		||||
 | 
			
		||||
		if (m_capacity <= 0)
 | 
			
		||||
			m_capacity = 16;
 | 
			
		||||
		while (length >= m_capacity)
 | 
			
		||||
			m_capacity *= 2;
 | 
			
		||||
 | 
			
		||||
		char* new_buffer = new char[m_capacity];
 | 
			
		||||
 | 
			
		||||
		if (m_buffer != nullptr)
 | 
			
		||||
		{
 | 
			
		||||
			memcpy(new_buffer, m_buffer, last_capacity);
 | 
			
		||||
			delete[] m_buffer;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		m_buffer = new_buffer;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_length = length;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BufferStream::close()
 | 
			
		||||
{
 | 
			
		||||
	delete[] m_buffer;
 | 
			
		||||
	m_buffer = nullptr;
 | 
			
		||||
	m_position = 0;
 | 
			
		||||
	m_length = 0;
 | 
			
		||||
	m_capacity = 0;
 | 
			
		||||
	m_buffer.resize(length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BufferStream::clear()
 | 
			
		||||
{
 | 
			
		||||
	m_length = m_position = 0;
 | 
			
		||||
	m_buffer.clear();
 | 
			
		||||
	m_position = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char* BufferStream::data()
 | 
			
		||||
u8* BufferStream::data()
 | 
			
		||||
{
 | 
			
		||||
	return m_buffer;
 | 
			
		||||
	return m_buffer.data();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char* BufferStream::data() const
 | 
			
		||||
const u8* BufferStream::data() const
 | 
			
		||||
{
 | 
			
		||||
	return m_buffer;
 | 
			
		||||
	return m_buffer.data();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,11 +5,6 @@
 | 
			
		||||
 | 
			
		||||
using namespace Blah;
 | 
			
		||||
 | 
			
		||||
FileStream::FileStream()
 | 
			
		||||
{
 | 
			
		||||
	m_mode = FileMode::OpenRead;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FileStream::FileStream(const FilePath& path, FileMode mode)
 | 
			
		||||
	: m_mode(mode)
 | 
			
		||||
	, m_file(File::open(path, mode))
 | 
			
		||||
@ -58,8 +53,6 @@ size_t FileStream::read_data(void* ptr, size_t length)
 | 
			
		||||
 | 
			
		||||
	if (m_file)
 | 
			
		||||
		return m_file->read((unsigned char*)ptr, length);
 | 
			
		||||
 | 
			
		||||
	BLAH_ASSERT(false, "Unable to read from Stream");
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -70,8 +63,6 @@ size_t FileStream::write_data(const void* ptr, size_t length)
 | 
			
		||||
 | 
			
		||||
	if (m_file)
 | 
			
		||||
		return m_file->write((const unsigned char*)ptr, length);
 | 
			
		||||
 | 
			
		||||
	BLAH_ASSERT(false, "Unable to write to Stream");
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -88,9 +79,4 @@ bool FileStream::is_readable() const
 | 
			
		||||
bool FileStream::is_writable() const
 | 
			
		||||
{
 | 
			
		||||
	return m_file.get() && (m_mode != FileMode::OpenRead);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FileStream::close()
 | 
			
		||||
{
 | 
			
		||||
	m_file.reset();
 | 
			
		||||
}
 | 
			
		||||
@ -3,30 +3,11 @@
 | 
			
		||||
 | 
			
		||||
using namespace Blah;
 | 
			
		||||
 | 
			
		||||
MemoryStream::MemoryStream()
 | 
			
		||||
	: m_data(nullptr), m_length(0), m_position(0) {}
 | 
			
		||||
MemoryStream::MemoryStream(u8* data, size_t length)
 | 
			
		||||
	: m_data(data), m_const_data(nullptr), m_length(length), m_position(0) {}
 | 
			
		||||
 | 
			
		||||
MemoryStream::MemoryStream(unsigned char* data, size_t length)
 | 
			
		||||
	: m_data(data), m_length(length), m_position(0) {}
 | 
			
		||||
 | 
			
		||||
MemoryStream::MemoryStream(MemoryStream&& src) noexcept
 | 
			
		||||
{
 | 
			
		||||
	m_data = src.m_data;
 | 
			
		||||
	m_position = src.m_position;
 | 
			
		||||
	m_length = src.m_length;
 | 
			
		||||
	src.m_data = nullptr;
 | 
			
		||||
	src.m_length = src.m_position = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MemoryStream& MemoryStream::operator=(MemoryStream&& src) noexcept
 | 
			
		||||
{
 | 
			
		||||
	m_data = src.m_data;
 | 
			
		||||
	m_position = src.m_position;
 | 
			
		||||
	m_length = src.m_length;
 | 
			
		||||
	src.m_data = nullptr;
 | 
			
		||||
	src.m_length = src.m_position = 0;
 | 
			
		||||
	return *this;
 | 
			
		||||
}
 | 
			
		||||
MemoryStream::MemoryStream(const u8* data, size_t length)
 | 
			
		||||
	: m_data(nullptr), m_const_data(data), m_length(length), m_position(0) {}
 | 
			
		||||
 | 
			
		||||
size_t MemoryStream::length() const
 | 
			
		||||
{
 | 
			
		||||
@ -38,63 +19,60 @@ size_t MemoryStream::position() const
 | 
			
		||||
	return m_position;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t MemoryStream::seek(size_t seekTo)
 | 
			
		||||
size_t MemoryStream::seek(size_t seek_to)
 | 
			
		||||
{
 | 
			
		||||
	return m_position = (seekTo < 0 ? 0 : (seekTo > m_length ? m_length : seekTo));
 | 
			
		||||
	return m_position = (seek_to < 0 ? 0 : (seek_to > m_length ? m_length : seek_to));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t MemoryStream::read_data(void* ptr, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	if (len < 0 || ptr == nullptr)
 | 
			
		||||
	const u8* src = (m_data ? m_data : m_const_data);
 | 
			
		||||
 | 
			
		||||
	if (src == nullptr || ptr == nullptr || len <= 0 || m_length <= 0 || m_position >= m_length)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (len > m_length - m_position)
 | 
			
		||||
		len = m_length - m_position;
 | 
			
		||||
 | 
			
		||||
	memcpy(ptr, m_data + m_position, (size_t)len);
 | 
			
		||||
	memcpy(ptr, src + m_position, len);
 | 
			
		||||
	m_position += len;
 | 
			
		||||
	return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t MemoryStream::write_data(const void* ptr, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	if (len < 0 || ptr == nullptr)
 | 
			
		||||
	if (m_data == nullptr || ptr == nullptr || len <= 0 || m_length <= 0 || m_position >= m_length)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (len > m_length - m_position)
 | 
			
		||||
		len = m_length - m_position;
 | 
			
		||||
 | 
			
		||||
	memcpy(m_data + m_position, ptr, (size_t)len);
 | 
			
		||||
	memcpy(m_data + m_position, ptr, len);
 | 
			
		||||
	m_position += len;
 | 
			
		||||
	return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MemoryStream::is_open() const
 | 
			
		||||
{
 | 
			
		||||
	return m_data != nullptr;
 | 
			
		||||
	return (m_data || m_const_data) && m_length > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MemoryStream::is_readable() const
 | 
			
		||||
{
 | 
			
		||||
	return true;
 | 
			
		||||
	return (m_data || m_const_data) && m_length > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MemoryStream::is_writable() const
 | 
			
		||||
{
 | 
			
		||||
	return true;
 | 
			
		||||
	return m_data != nullptr && m_length > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MemoryStream::close()
 | 
			
		||||
{
 | 
			
		||||
	m_data = nullptr; m_length = m_position = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned char* MemoryStream::data()
 | 
			
		||||
u8* MemoryStream::data()
 | 
			
		||||
{
 | 
			
		||||
	return m_data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const unsigned char* MemoryStream::data() const
 | 
			
		||||
const u8* MemoryStream::data() const
 | 
			
		||||
{
 | 
			
		||||
	return m_data;
 | 
			
		||||
	return (m_data ? m_data : m_const_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user