mirror of
https://github.com/NoelFB/blah.git
synced 2025-06-27 19:01:29 +08:00
Lots of documentation & commenting
This commit is contained in:
parent
9b42bba16e
commit
088851b43f
@ -5,27 +5,68 @@
|
|||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
// Application Event Functions
|
||||||
using AppEventFn = std::function<void()>;
|
using AppEventFn = std::function<void()>;
|
||||||
|
|
||||||
|
// Application Logging Functions
|
||||||
using AppLogFn = std::function<void(const char* message, Log::Category category)>;
|
using AppLogFn = std::function<void(const char* message, Log::Category category)>;
|
||||||
|
|
||||||
|
// Application Configuration
|
||||||
struct Config
|
struct Config
|
||||||
{
|
{
|
||||||
|
// Application name.
|
||||||
|
// This has no default and must be set.
|
||||||
const char* name;
|
const char* name;
|
||||||
|
|
||||||
|
// Starting width, in pixels.
|
||||||
|
// Depending on the OS DPI, the true window size may be a multiple of this.
|
||||||
|
// This has no default and must be set.
|
||||||
int width;
|
int width;
|
||||||
|
|
||||||
|
// Starting height, in pixels.
|
||||||
|
// Depending on the OS DPI, the true window size may be a multiple of this.
|
||||||
|
// This has no default and must be set.
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
|
// maximum updates to run before "giving up" and reducing frame rate.
|
||||||
|
// this avoids the 'spiral of death'.
|
||||||
|
// defaults to 5.
|
||||||
int max_updates;
|
int max_updates;
|
||||||
|
|
||||||
|
// target framerate.
|
||||||
|
// defaults to 60.
|
||||||
int target_framerate;
|
int target_framerate;
|
||||||
|
|
||||||
|
// Callback on application startup
|
||||||
|
// Defaults to nothing.
|
||||||
AppEventFn on_startup;
|
AppEventFn on_startup;
|
||||||
|
|
||||||
|
// Callback on application shutdown
|
||||||
|
// Defaults to nothing.
|
||||||
AppEventFn on_shutdown;
|
AppEventFn on_shutdown;
|
||||||
|
|
||||||
|
// Callback on application update
|
||||||
|
// Defaults to nothing.
|
||||||
AppEventFn on_update;
|
AppEventFn on_update;
|
||||||
|
|
||||||
|
// Callback on application render
|
||||||
|
// Defaults to nothing.
|
||||||
AppEventFn on_render;
|
AppEventFn on_render;
|
||||||
|
|
||||||
|
// Callback when the user has requested the application close.
|
||||||
|
// For example, pressing the Close button
|
||||||
|
// By default this calls `App::exit()`
|
||||||
AppEventFn on_exit_request;
|
AppEventFn on_exit_request;
|
||||||
|
|
||||||
|
// Callback when the application logs info/warning/errors
|
||||||
|
// Defaults to printf.
|
||||||
AppLogFn on_log;
|
AppLogFn on_log;
|
||||||
|
|
||||||
|
// Default config setup
|
||||||
Config();
|
Config();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Renderer the Application is using
|
||||||
enum class Renderer
|
enum class Renderer
|
||||||
{
|
{
|
||||||
None = -1,
|
None = -1,
|
||||||
@ -35,16 +76,24 @@ namespace Blah
|
|||||||
Count
|
Count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Features available on the current Renderer
|
||||||
struct RendererFeatures
|
struct RendererFeatures
|
||||||
{
|
{
|
||||||
|
// Whether Mesh Instancing is available
|
||||||
bool instancing = false;
|
bool instancing = false;
|
||||||
|
|
||||||
|
// Whether the Texture origin is the bottom left.
|
||||||
|
// This is true for OpenGL.
|
||||||
bool origin_bottom_left = false;
|
bool origin_bottom_left = false;
|
||||||
|
|
||||||
|
// Maximum Texture Size available
|
||||||
int max_texture_size = 0;
|
int max_texture_size = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FrameBuffer;
|
class FrameBuffer;
|
||||||
using FrameBufferRef = std::shared_ptr<FrameBuffer>;
|
using FrameBufferRef = std::shared_ptr<FrameBuffer>;
|
||||||
|
|
||||||
|
// Application
|
||||||
namespace App
|
namespace App
|
||||||
{
|
{
|
||||||
// Runs the application
|
// Runs the application
|
||||||
|
@ -5,40 +5,71 @@
|
|||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
using FilePath = StrOf<265>;
|
using FilePath = StrOf<265>;
|
||||||
|
class FileStream;
|
||||||
|
|
||||||
enum class FileMode
|
enum class FileMode
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
Read = 1 << 1,
|
Read = 1 << 0,
|
||||||
Write = 1 << 2,
|
Write = 1 << 1,
|
||||||
ReadWrite = Read | Write,
|
ReadWrite = Read | Write,
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Directory
|
namespace Directory
|
||||||
{
|
{
|
||||||
|
// Creates a new directory at the given location.
|
||||||
|
// Returns false if unable to create the directory.
|
||||||
bool create(const FilePath& path);
|
bool create(const FilePath& path);
|
||||||
|
|
||||||
|
// Returns whether the given directory exists
|
||||||
bool exists(const FilePath& path);
|
bool exists(const FilePath& path);
|
||||||
|
|
||||||
|
// Tries to delete a path and returns whether it was successful
|
||||||
bool remove(const FilePath& path);
|
bool remove(const FilePath& path);
|
||||||
Vector<FilePath> enumerate(const FilePath& str, bool recursive = true);
|
|
||||||
|
// Enumerates over a directory and returns a list of files & directories
|
||||||
|
Vector<FilePath> enumerate(const FilePath& path, bool recursive = true);
|
||||||
|
|
||||||
|
// Opens the path in the File Explorer / Finder
|
||||||
void explore(const FilePath& path);
|
void explore(const FilePath& path);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace File
|
namespace File
|
||||||
{
|
{
|
||||||
|
// Checks if the given file exists
|
||||||
bool exists(const FilePath& path);
|
bool exists(const FilePath& path);
|
||||||
|
|
||||||
|
// Tries to delete a file and returns whether it was successful
|
||||||
bool remove(const FilePath& path);
|
bool remove(const FilePath& path);
|
||||||
|
|
||||||
|
// Opens the given file and returns a stream
|
||||||
|
FileStream open(const FilePath& path, FileMode mode = FileMode::ReadWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Path
|
namespace Path
|
||||||
{
|
{
|
||||||
|
// Returns the file name of the path
|
||||||
FilePath get_file_name(const FilePath& path);
|
FilePath get_file_name(const FilePath& path);
|
||||||
|
|
||||||
|
// Returns the file name of the path, without the file extension
|
||||||
FilePath get_file_name_no_ext(const FilePath& path);
|
FilePath get_file_name_no_ext(const FilePath& path);
|
||||||
|
|
||||||
|
// Returns the path without any file extensions
|
||||||
FilePath get_path_no_ext(const FilePath& path);
|
FilePath get_path_no_ext(const FilePath& path);
|
||||||
|
|
||||||
|
// Returns relative path
|
||||||
FilePath get_path_after(const FilePath& path, const FilePath& after);
|
FilePath get_path_after(const FilePath& path, const FilePath& after);
|
||||||
|
|
||||||
|
// Gets the top directory name from the path
|
||||||
FilePath get_directory_name(const FilePath& path);
|
FilePath get_directory_name(const FilePath& path);
|
||||||
|
|
||||||
|
// Normalizes a path (removes ../, changes \\ to /, removes redundant slashes, etc)
|
||||||
FilePath normalize(const FilePath& path);
|
FilePath normalize(const FilePath& path);
|
||||||
|
|
||||||
|
// Joins two paths together
|
||||||
FilePath join(const FilePath& a, const FilePath& b);
|
FilePath join(const FilePath& a, const FilePath& b);
|
||||||
|
|
||||||
|
// Joins two paths together
|
||||||
template<typename ... Args>
|
template<typename ... Args>
|
||||||
FilePath join(const FilePath& a, const FilePath& b, const Args&... args)
|
FilePath join(const FilePath& a, const FilePath& b, const Args&... args)
|
||||||
{
|
{
|
||||||
|
@ -4,84 +4,129 @@
|
|||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
#include <blah/drawing/subtexture.h>
|
#include <blah/drawing/subtexture.h>
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/math/vec2.h>
|
||||||
|
#include <blah/core/filesystem.h>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
class Font;
|
class Font;
|
||||||
|
|
||||||
struct CharacterRange;
|
// Sprite Font is a bitmap font implementation for font rendering.
|
||||||
using CharacterSet = Vector<CharacterRange>;
|
// It can be constructed from a Font (ttf) and will automatically create
|
||||||
|
// texture atlases for rendering. You can add your own characters
|
||||||
struct CharacterRange
|
// and textures to it.
|
||||||
{
|
|
||||||
u32 from;
|
|
||||||
u32 to;
|
|
||||||
|
|
||||||
CharacterRange();
|
|
||||||
CharacterRange(u32 single);
|
|
||||||
CharacterRange(u32 from, u32 to);
|
|
||||||
|
|
||||||
static const CharacterSet ASCII;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SpriteFont
|
class SpriteFont
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// Spritefont uses u32 codepoints
|
||||||
|
using Codepoint = u32;
|
||||||
|
|
||||||
|
// CharSet is a Vector of Character Ranges
|
||||||
|
struct CharRange;
|
||||||
|
using CharSet = Vector<CharRange>;
|
||||||
|
|
||||||
|
// Character range, used for building the Sprite Font
|
||||||
|
struct CharRange
|
||||||
|
{
|
||||||
|
Codepoint from;
|
||||||
|
Codepoint to;
|
||||||
|
|
||||||
|
CharRange();
|
||||||
|
CharRange(Codepoint single);
|
||||||
|
CharRange(Codepoint from, Codepoint to);
|
||||||
|
|
||||||
|
static const CharSet ASCII;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Character Entry
|
||||||
struct Character
|
struct Character
|
||||||
{
|
{
|
||||||
Subtexture subtexture;
|
Subtexture subtexture;
|
||||||
float advance = 0;
|
float advance = 0;
|
||||||
Vec2 offset;
|
Vec2 offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// SpriteFont name
|
||||||
|
String name;
|
||||||
|
|
||||||
|
// Height, in pixels
|
||||||
|
float size;
|
||||||
|
|
||||||
|
// Ascent, in pixels
|
||||||
|
float ascent;
|
||||||
|
|
||||||
|
// Descent, in pixels
|
||||||
|
float descent;
|
||||||
|
|
||||||
|
// Line Gap, in pixels
|
||||||
|
float line_gap;
|
||||||
|
|
||||||
|
SpriteFont();
|
||||||
|
SpriteFont(const FilePath& file, float size);
|
||||||
|
SpriteFont(const FilePath& file, float size, const CharSet& charset);
|
||||||
|
SpriteFont(const Font& font, float size);
|
||||||
|
SpriteFont(const Font& font, float size, const CharSet& charset);
|
||||||
|
SpriteFont(const SpriteFont&) = delete;
|
||||||
|
SpriteFont& operator=(const SpriteFont&) = delete;
|
||||||
|
SpriteFont(SpriteFont&& src) noexcept;
|
||||||
|
SpriteFont& operator=(SpriteFont&& src) noexcept;
|
||||||
|
~SpriteFont();
|
||||||
|
|
||||||
|
// releases all assets used by the spritefont
|
||||||
|
void dispose();
|
||||||
|
|
||||||
|
// gets the height of the sprite font
|
||||||
|
float height() const { return ascent - descent; }
|
||||||
|
|
||||||
|
// gets the line height of the sprite font (height + line gap)
|
||||||
|
float line_height() const { return ascent - descent + line_gap; }
|
||||||
|
|
||||||
|
// returns a list of all texture atlases
|
||||||
|
const Vector<TextureRef>& textures() { return m_atlas; }
|
||||||
|
|
||||||
|
// calculates the width of the given string
|
||||||
|
float width_of(const String& text) const;
|
||||||
|
|
||||||
|
// calculates the width of the next line
|
||||||
|
float width_of_line(const String& text, int start = 0) const;
|
||||||
|
|
||||||
|
// calculates the height of the given string
|
||||||
|
float height_of(const String& text) const;
|
||||||
|
|
||||||
|
// disposes the existing spritefont data and rebuilds from the given font file
|
||||||
|
void rebuild(const FilePath& file, float size, const CharSet& charset);
|
||||||
|
|
||||||
|
// disposes the existing spritefont data and rebuilds from the given font
|
||||||
|
void rebuild(const Font& font, float size, const CharSet& charset);
|
||||||
|
|
||||||
|
// gets the kerning between two characters
|
||||||
|
float get_kerning(Codepoint codepoint0, Codepoint codepoint1) const;
|
||||||
|
|
||||||
|
// sets the kerning between two characters
|
||||||
|
void set_kerning(Codepoint codepoint0, Codepoint codepoint1, float kerning);
|
||||||
|
|
||||||
|
// gets the character at the given codepoint
|
||||||
|
Character& get_character(Codepoint codepoint);
|
||||||
|
|
||||||
|
// gets the character at the given codepoint
|
||||||
|
const Character& get_character(Codepoint codepoint) const;
|
||||||
|
|
||||||
|
// gets the character at the given codepoint
|
||||||
|
Character& operator[](Codepoint codepoint);
|
||||||
|
|
||||||
|
// gets the character at the given codepoint
|
||||||
|
const Character& operator[](Codepoint codepoint) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// charset & kerning maps
|
// character set
|
||||||
std::unordered_map<u32, Character> m_characters;
|
std::unordered_map<Codepoint, Character> m_characters;
|
||||||
|
|
||||||
|
// kerning
|
||||||
|
// key is 2 codepoints combined ((first << 32) | second)
|
||||||
std::unordered_map<u64, float> m_kerning;
|
std::unordered_map<u64, float> m_kerning;
|
||||||
|
|
||||||
// built texture
|
// built texture
|
||||||
Vector<TextureRef> m_atlas;
|
Vector<TextureRef> m_atlas;
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
String name;
|
|
||||||
float size;
|
|
||||||
float ascent;
|
|
||||||
float descent;
|
|
||||||
float line_gap;
|
|
||||||
|
|
||||||
SpriteFont();
|
|
||||||
SpriteFont(const char* file, float size);
|
|
||||||
SpriteFont(const char* file, float size, const CharacterSet& charset);
|
|
||||||
SpriteFont(const Font& font, float size);
|
|
||||||
SpriteFont(const Font& font, float size, const CharacterSet& charset);
|
|
||||||
SpriteFont(const SpriteFont&) = delete;
|
|
||||||
SpriteFont(SpriteFont&& src) noexcept;
|
|
||||||
~SpriteFont();
|
|
||||||
|
|
||||||
void dispose();
|
|
||||||
|
|
||||||
SpriteFont& operator=(const SpriteFont&) = delete;
|
|
||||||
SpriteFont& operator=(SpriteFont&& src) noexcept;
|
|
||||||
|
|
||||||
float height() const { return ascent - descent; }
|
|
||||||
float line_height() const { return ascent - descent + line_gap; }
|
|
||||||
|
|
||||||
const Vector<TextureRef>& textures() { return m_atlas; }
|
|
||||||
|
|
||||||
float width_of(const String& text) const;
|
|
||||||
float width_of_line(const String& text, int start = 0) const;
|
|
||||||
float height_of(const String& text) const;
|
|
||||||
|
|
||||||
void build(const char* file, float size, const CharacterSet& charset);
|
|
||||||
void build(const Font& font, float size, const CharacterSet& charset);
|
|
||||||
|
|
||||||
float get_kerning(u32 codepoint0, u32 codepoint1) const;
|
|
||||||
void set_kerning(u32 codepoint0, u32 codepoint1, float kerning);
|
|
||||||
|
|
||||||
Character& get_character(u32 codepoint) { return m_characters[codepoint]; }
|
|
||||||
const Character& get_character(u32 codepoint) const;
|
|
||||||
Character& operator[](u32 codepoint) { return m_characters[codepoint]; }
|
|
||||||
const Character& operator[](u32 codepoint) const;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -21,6 +21,8 @@ namespace Blah
|
|||||||
class FrameBuffer;
|
class FrameBuffer;
|
||||||
using FrameBufferRef = std::shared_ptr<FrameBuffer>;
|
using FrameBufferRef = std::shared_ptr<FrameBuffer>;
|
||||||
|
|
||||||
|
// FrameBuffer is a 2D Buffer that can be drawn to.
|
||||||
|
// It can hold up to 4 color Textures, and 1 Depth/Stencil Texture.
|
||||||
class FrameBuffer
|
class FrameBuffer
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -10,6 +10,7 @@ namespace Blah
|
|||||||
class Material;
|
class Material;
|
||||||
typedef std::shared_ptr<Material> MaterialRef;
|
typedef std::shared_ptr<Material> MaterialRef;
|
||||||
|
|
||||||
|
// Materials hold values that can be assigned to a shader during rendering
|
||||||
class Material final
|
class Material final
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -53,6 +53,7 @@ namespace Blah
|
|||||||
class Mesh;
|
class Mesh;
|
||||||
typedef std::shared_ptr<Mesh> MeshRef;
|
typedef std::shared_ptr<Mesh> MeshRef;
|
||||||
|
|
||||||
|
// A Mesh is a set of Indices and Vertices which are used for drawing
|
||||||
class Mesh
|
class Mesh
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -31,6 +31,7 @@ namespace Blah
|
|||||||
Back = 2,
|
Back = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A single draw call
|
||||||
struct RenderPass
|
struct RenderPass
|
||||||
{
|
{
|
||||||
// Framebuffer to draw to
|
// Framebuffer to draw to
|
||||||
|
@ -18,6 +18,7 @@ namespace Blah
|
|||||||
class Texture;
|
class Texture;
|
||||||
typedef std::shared_ptr<Texture> TextureRef;
|
typedef std::shared_ptr<Texture> TextureRef;
|
||||||
|
|
||||||
|
// A 2D Texture held by the GPU to be used during rendering
|
||||||
class Texture
|
class Texture
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -3,12 +3,13 @@
|
|||||||
#include <blah/images/image.h>
|
#include <blah/images/image.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/streams/stream.h>
|
#include <blah/streams/stream.h>
|
||||||
|
#include <blah/core/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
// A simple Aseprite file parser.
|
// A simple Aseprite file parser.
|
||||||
// This implementation does not support Aseprite blendmodes,
|
// This implementation does not support Aseprite blendmodes,
|
||||||
// besides the default blend mode.
|
// aside from the default blend mode.
|
||||||
class Aseprite
|
class Aseprite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -125,12 +126,12 @@ namespace Blah
|
|||||||
|
|
||||||
Vector<Layer> layers;
|
Vector<Layer> layers;
|
||||||
Vector<Frame> frames;
|
Vector<Frame> frames;
|
||||||
Vector<Tag> tags;
|
Vector<Tag> tags;
|
||||||
Vector<Slice> slices;
|
Vector<Slice> slices;
|
||||||
Vector<Color> palette;
|
Vector<Color> palette;
|
||||||
|
|
||||||
Aseprite();
|
Aseprite();
|
||||||
Aseprite(const char* path);
|
Aseprite(const FilePath& path);
|
||||||
Aseprite(Stream& stream);
|
Aseprite(Stream& stream);
|
||||||
Aseprite(const Aseprite& src);
|
Aseprite(const Aseprite& src);
|
||||||
Aseprite(Aseprite&& src) noexcept;
|
Aseprite(Aseprite&& src) noexcept;
|
||||||
|
@ -2,50 +2,102 @@
|
|||||||
#include <blah/streams/stream.h>
|
#include <blah/streams/stream.h>
|
||||||
#include <blah/images/image.h>
|
#include <blah/images/image.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
|
#include <blah/core/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
typedef u32 Codepoint;
|
// Loads fonts from file and can blit individual characters to images
|
||||||
|
|
||||||
class Font
|
class Font
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct Char
|
|
||||||
|
// Font uses u32 Codepoints
|
||||||
|
using Codepoint = u32;
|
||||||
|
|
||||||
|
// Information provided for a single Character
|
||||||
|
struct Character
|
||||||
{
|
{
|
||||||
|
// character's glyph index
|
||||||
int glyph = 0;
|
int glyph = 0;
|
||||||
|
|
||||||
|
// width of the character, in pixels
|
||||||
int width = 0;
|
int width = 0;
|
||||||
|
|
||||||
|
// height of the character, in pixels
|
||||||
int height = 0;
|
int height = 0;
|
||||||
|
|
||||||
|
// advance (how much to move horizontally)
|
||||||
float advance = 0;
|
float advance = 0;
|
||||||
|
|
||||||
|
// render x-offset
|
||||||
float offset_x = 0;
|
float offset_x = 0;
|
||||||
|
|
||||||
|
// render y-offset
|
||||||
float offset_y = 0;
|
float offset_y = 0;
|
||||||
|
|
||||||
|
// scale the character was created at
|
||||||
float scale = 0;
|
float scale = 0;
|
||||||
|
|
||||||
|
// whether the character has a visible glyph
|
||||||
bool has_glyph = false;
|
bool has_glyph = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
Font();
|
Font();
|
||||||
Font(Stream& stream);
|
Font(Stream& stream);
|
||||||
Font(const char* path);
|
Font(const FilePath& path);
|
||||||
Font(const Font&) = delete;
|
Font(const Font&) = delete;
|
||||||
Font& operator=(const Font&) = delete;
|
Font& operator=(const Font&) = delete;
|
||||||
Font(Font&& src) noexcept;
|
Font(Font&& src) noexcept;
|
||||||
Font& operator=(Font&& src) noexcept;
|
Font& operator=(Font&& src) noexcept;
|
||||||
~Font();
|
~Font();
|
||||||
|
|
||||||
|
// Releases all Font resources
|
||||||
|
// Note that after doing this various properties may become invalid (ex. font name)
|
||||||
void dispose();
|
void dispose();
|
||||||
|
|
||||||
const char* family_name() const;
|
// returns the font family name
|
||||||
const char* style_name() const;
|
const String& family_name() const;
|
||||||
|
|
||||||
|
// returns the font style name
|
||||||
|
const String& style_name() const;
|
||||||
|
|
||||||
|
// the font ascent
|
||||||
int ascent() const;
|
int ascent() const;
|
||||||
|
|
||||||
|
// the font descent
|
||||||
int descent() const;
|
int descent() const;
|
||||||
|
|
||||||
|
// the font line gap (space between lines)
|
||||||
int line_gap() const;
|
int line_gap() const;
|
||||||
|
|
||||||
|
// the height of the font
|
||||||
int height() const;
|
int height() const;
|
||||||
|
|
||||||
|
// the height of the line, including line gap
|
||||||
int line_height() const;
|
int line_height() const;
|
||||||
|
|
||||||
|
// gets the glyph index for the given codepoint
|
||||||
int get_glyph(Codepoint codepoint) const;
|
int get_glyph(Codepoint codepoint) const;
|
||||||
|
|
||||||
|
// gets the font scale for the given font size in pixels
|
||||||
float get_scale(float size) const;
|
float get_scale(float size) const;
|
||||||
|
|
||||||
|
// gets the font kerning between 2 glyphs
|
||||||
float get_kerning(int glyph1, int glyph2, float scale) const;
|
float get_kerning(int glyph1, int glyph2, float scale) const;
|
||||||
Char get_character(int glyph, float scale) const;
|
|
||||||
bool get_image(const Char& ch, Color* pixels) const;
|
// gets character data for the given glyph, at the provided scale
|
||||||
|
Character get_character(int glyph, float scale) const;
|
||||||
|
|
||||||
|
// Blits a character to the provided pixel array.
|
||||||
|
// The pixel array must be at least ch.width * ch.height in size!
|
||||||
|
// If the character doesn't exist, this will do nothing and return false.
|
||||||
|
bool get_image(const Character& ch, Color* pixels) const;
|
||||||
|
|
||||||
|
// Returns an image of the provided character.
|
||||||
|
// If the character doesn't exist, this will return an empty image.
|
||||||
|
Image get_image(const Character& ch) const;
|
||||||
|
|
||||||
|
// checks if the Font is valid
|
||||||
bool is_valid() const;
|
bool is_valid() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -2,21 +2,30 @@
|
|||||||
#include <blah/math/color.h>
|
#include <blah/math/color.h>
|
||||||
#include <blah/math/rectI.h>
|
#include <blah/math/rectI.h>
|
||||||
#include <blah/math/point.h>
|
#include <blah/math/point.h>
|
||||||
|
#include <blah/core/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
class Stream;
|
class Stream;
|
||||||
|
|
||||||
|
// A simple 2D Bitmap
|
||||||
class Image
|
class Image
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// width of the image, in pixels.
|
||||||
int width = 0;
|
int width = 0;
|
||||||
|
|
||||||
|
// height of the image, in pixels.
|
||||||
int height = 0;
|
int height = 0;
|
||||||
|
|
||||||
|
// pixel data of the image.
|
||||||
|
// this can be nullptr if the image is never assigned to anything.
|
||||||
Color* pixels = nullptr;
|
Color* pixels = nullptr;
|
||||||
|
|
||||||
Image();
|
Image();
|
||||||
Image(Stream& stream);
|
Image(Stream& stream);
|
||||||
Image(const char* file);
|
Image(const FilePath& file);
|
||||||
Image(int width, int height);
|
Image(int width, int height);
|
||||||
Image(const Image& src);
|
Image(const Image& src);
|
||||||
Image& operator=(const Image& src);
|
Image& operator=(const Image& src);
|
||||||
@ -24,19 +33,41 @@ namespace Blah
|
|||||||
Image& operator=(Image&& src) noexcept;
|
Image& operator=(Image&& src) noexcept;
|
||||||
~Image();
|
~Image();
|
||||||
|
|
||||||
|
// disposes the existing image and recreates it from a stream
|
||||||
void from_stream(Stream& stream);
|
void from_stream(Stream& stream);
|
||||||
|
|
||||||
|
// disposes the image and resets its values to defaults
|
||||||
void dispose();
|
void dispose();
|
||||||
|
|
||||||
|
// applies alpha premultiplication to the image data
|
||||||
void premultiply();
|
void premultiply();
|
||||||
|
|
||||||
|
// sets the pixels at the provided rectangle to the given data
|
||||||
|
// data must be at least rect.w * rect.h in size!
|
||||||
void set_pixels(const RectI& rect, Color* data);
|
void set_pixels(const RectI& rect, Color* data);
|
||||||
bool save_png(const char* file) const;
|
|
||||||
|
// saves the image to a png file
|
||||||
|
bool save_png(const FilePath& file) const;
|
||||||
|
|
||||||
|
// saves the image to a png file
|
||||||
bool save_png(Stream& stream) const;
|
bool save_png(Stream& stream) const;
|
||||||
bool save_jpg(const char* file, int quality) const;
|
|
||||||
|
// saves the image to a jpg file
|
||||||
|
bool save_jpg(const FilePath& file, int quality) const;
|
||||||
|
|
||||||
|
// saves the image to a jpg file
|
||||||
bool save_jpg(Stream& stream, int quality) const;
|
bool save_jpg(Stream& stream, int quality) const;
|
||||||
void get_pixels(Color* dest, const Point& destPos, const Point& destSize, RectI sourceRect);
|
|
||||||
Image get_sub_image(const RectI& sourceRect);
|
// gets the pixels from the given source rectangle
|
||||||
|
void get_pixels(Color* dest, const Point& dest_pos, const Point& dest_size, RectI source_rect);
|
||||||
|
|
||||||
|
// gets a sub image from this image
|
||||||
|
Image get_sub_image(const RectI& source_rect);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
// whether the stbi library owns the image data.
|
||||||
|
// we should let it free the data if it created it.
|
||||||
bool m_stbi_ownership;
|
bool m_stbi_ownership;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -6,6 +6,7 @@
|
|||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
#include <blah/streams/bufferstream.h>
|
#include <blah/streams/bufferstream.h>
|
||||||
|
#include <blah/core/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
@ -14,29 +15,58 @@ namespace Blah
|
|||||||
class Packer
|
class Packer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// Packer Entry, which stores information about the resulting packed texture
|
||||||
class Entry
|
class Entry
|
||||||
{
|
{
|
||||||
friend class Packer;
|
friend class Packer;
|
||||||
private:
|
private:
|
||||||
i64 memory_index;
|
i64 memory_index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// entry ID
|
||||||
u64 id;
|
u64 id;
|
||||||
|
|
||||||
|
// Texture Page that it was packed into.
|
||||||
|
// This won't be set until after the packer has run.
|
||||||
int page;
|
int page;
|
||||||
|
|
||||||
|
// Whether the entry is empty
|
||||||
bool empty;
|
bool empty;
|
||||||
|
|
||||||
|
// Packed frame rectangle.
|
||||||
|
// This won't be set until after the packer has run.
|
||||||
RectI frame;
|
RectI frame;
|
||||||
|
|
||||||
|
// Packed position and size.
|
||||||
|
// This won't be set until after the packer has run.
|
||||||
RectI packed;
|
RectI packed;
|
||||||
|
|
||||||
Entry(u64 id, const RectI& frame)
|
Entry(u64 id, const RectI& frame)
|
||||||
: memory_index(0), id(id), page(0), empty(true), frame(frame), packed(0, 0, 0, 0) {}
|
: memory_index(0)
|
||||||
|
, id(id)
|
||||||
|
, page(0)
|
||||||
|
, empty(true)
|
||||||
|
, frame(frame)
|
||||||
|
, packed(0, 0, 0, 0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// maximum width / height of the generated texture
|
||||||
int max_size;
|
int max_size;
|
||||||
|
|
||||||
|
// whether the generated texture must be a power of 2
|
||||||
bool power_of_two;
|
bool power_of_two;
|
||||||
|
|
||||||
|
// spacing between each packed subtexture
|
||||||
int spacing;
|
int spacing;
|
||||||
|
|
||||||
|
// padding on each subtexture (extrudes their borders outwards)
|
||||||
int padding;
|
int padding;
|
||||||
|
|
||||||
|
// generated textures. There can be more than one if the packer was
|
||||||
|
// unable to fit all of the provided subtextures into the max_size.
|
||||||
Vector<Image> pages;
|
Vector<Image> pages;
|
||||||
Vector<Entry> entries;
|
|
||||||
|
|
||||||
Packer();
|
Packer();
|
||||||
Packer(int max_size, int spacing, bool power_of_two);
|
Packer(int max_size, int spacing, bool power_of_two);
|
||||||
@ -46,12 +76,25 @@ namespace Blah
|
|||||||
Packer& operator=(Packer&& src) noexcept;
|
Packer& operator=(Packer&& src) noexcept;
|
||||||
~Packer();
|
~Packer();
|
||||||
|
|
||||||
|
// add a new entry
|
||||||
void add(u64 id, int width, int height, const Color* pixels);
|
void add(u64 id, int width, int height, const Color* pixels);
|
||||||
void add(u64 id, const Image& bitmap);
|
|
||||||
void add(u64 id, const String& path);
|
|
||||||
|
|
||||||
|
// add a new entry
|
||||||
|
void add(u64 id, const Image& bitmap);
|
||||||
|
|
||||||
|
// add a new entry
|
||||||
|
void add(u64 id, const FilePath& path);
|
||||||
|
|
||||||
|
// returns a vector of all the resulting entries
|
||||||
|
const Vector<Entry>& entries() const;
|
||||||
|
|
||||||
|
// perform the packing
|
||||||
void pack();
|
void pack();
|
||||||
|
|
||||||
|
// clear the current packer data
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
// dispose all resources used by the packer
|
||||||
void dispose();
|
void dispose();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -67,9 +110,16 @@ namespace Blah
|
|||||||
Node* Reset(const RectI& rect);
|
Node* Reset(const RectI& rect);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// whether the packer has any changes that require it to run again
|
||||||
bool m_dirty;
|
bool m_dirty;
|
||||||
|
|
||||||
|
// buffer of all the image data we will be packing
|
||||||
BufferStream m_buffer;
|
BufferStream m_buffer;
|
||||||
|
|
||||||
|
// Entries to pack & their resulting data
|
||||||
|
Vector<Entry> m_entries;
|
||||||
|
|
||||||
|
// adds a new entry
|
||||||
void add_entry(u64 id, int w, int h, const Color* pixels);
|
void add_entry(u64 id, int w, int h, const Color* pixels);
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
struct Vec3;
|
||||||
struct Vec4;
|
struct Vec4;
|
||||||
|
|
||||||
struct Color
|
struct Color
|
||||||
@ -18,21 +19,23 @@ namespace Blah
|
|||||||
Color(int rgb, float alpha);
|
Color(int rgb, float alpha);
|
||||||
Color(u8 r, u8 g, u8 b);
|
Color(u8 r, u8 g, u8 b);
|
||||||
Color(u8 r, u8 g, u8 b, u8 a);
|
Color(u8 r, u8 g, u8 b, u8 a);
|
||||||
|
Color(const Vec3& vec3);
|
||||||
|
Color(const Vec3& vec3, float alpha);
|
||||||
Color(const Vec4& vec4);
|
Color(const Vec4& vec4);
|
||||||
|
|
||||||
// Parses a Hex string in the format of "#00000000" or "0x00000000" or "00000000"
|
// Parses a Hex string in the format of "#00000000" or "0x00000000" or "00000000"
|
||||||
Color(const char* hexCstr);
|
Color(const String& hex_string);
|
||||||
|
|
||||||
// Premultiplies the Color
|
// Premultiplies the Color
|
||||||
void premultiply();
|
void premultiply();
|
||||||
|
|
||||||
|
// Returns an RGBA hex string of the color
|
||||||
|
String to_hex_rgba() const;
|
||||||
|
|
||||||
// Sets a Hex string to the given buffer, in the format of RRGGBBAA
|
// Sets a Hex string to the given buffer, in the format of RRGGBBAA
|
||||||
// The buffer must be at least 8 bytes long
|
// The buffer must be at least 8 bytes long
|
||||||
void to_hex_rgba(char* buffer) const;
|
void to_hex_rgba(char* buffer) const;
|
||||||
|
|
||||||
// Returns an RGBA hex string of the color
|
|
||||||
String to_hex_rgba() const;
|
|
||||||
|
|
||||||
// Sets a Hex string to the given buffer, in the format of RRGGBB
|
// Sets a Hex string to the given buffer, in the format of RRGGBB
|
||||||
// The buffer must be at least 6 bytes long
|
// The buffer must be at least 6 bytes long
|
||||||
void to_hex_rgb(char* buffer) const;
|
void to_hex_rgb(char* buffer) const;
|
||||||
|
@ -8,6 +8,7 @@ namespace Blah
|
|||||||
|
|
||||||
enum class Easers
|
enum class Easers
|
||||||
{
|
{
|
||||||
|
Linear,
|
||||||
QuadIn, QuadOut, QuadInOut,
|
QuadIn, QuadOut, QuadInOut,
|
||||||
CubeIn, CubeOut, CubeInOut,
|
CubeIn, CubeOut, CubeInOut,
|
||||||
QuartIn, QuartOut, QuartInOut,
|
QuartIn, QuartOut, QuartInOut,
|
||||||
@ -28,43 +29,41 @@ namespace Blah
|
|||||||
For previews go here: https://easings.net/
|
For previews go here: https://easings.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline float linear(float t)
|
constexpr float linear(float t)
|
||||||
{
|
{
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float quad_in(float t)
|
constexpr float quad_in(float t)
|
||||||
{
|
{
|
||||||
return t * t;
|
return t * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float quad_out(float t)
|
constexpr float quad_out(float t)
|
||||||
{
|
{
|
||||||
return -(t * (t - 2));
|
return -(t * (t - 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float quad_in_out(float t)
|
constexpr float quad_in_out(float t)
|
||||||
{
|
{
|
||||||
if (t < 0.5f)
|
if (t < 0.5f)
|
||||||
return 2 * t * t;
|
return 2 * t * t;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return (-2 * t * t) + (4 * t) - 1;
|
return (-2 * t * t) + (4 * t) - 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float cube_in(float t)
|
constexpr float cube_in(float t)
|
||||||
{
|
{
|
||||||
return t * t * t;
|
return t * t * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float cube_out(float t)
|
constexpr float cube_out(float t)
|
||||||
{
|
{
|
||||||
float f = (t - 1);
|
float f = (t - 1);
|
||||||
return f * f * f + 1;
|
return f * f * f + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float cube_in_out(float t)
|
constexpr float cube_in_out(float t)
|
||||||
{
|
{
|
||||||
if (t < 0.5f)
|
if (t < 0.5f)
|
||||||
return 4 * t * t * t;
|
return 4 * t * t * t;
|
||||||
@ -75,18 +74,18 @@ namespace Blah
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float quart_in(float t)
|
constexpr float quart_in(float t)
|
||||||
{
|
{
|
||||||
return t * t * t * t;
|
return t * t * t * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float quart_out(float t)
|
constexpr float quart_out(float t)
|
||||||
{
|
{
|
||||||
float f = (t - 1);
|
float f = (t - 1);
|
||||||
return f * f * f * (1 - t) + 1;
|
return f * f * f * (1 - t) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float quart_in_out(float t)
|
constexpr float quart_in_out(float t)
|
||||||
{
|
{
|
||||||
if (t < 0.5f)
|
if (t < 0.5f)
|
||||||
return 8 * t * t * t * t;
|
return 8 * t * t * t * t;
|
||||||
@ -97,18 +96,18 @@ namespace Blah
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float quint_in(float t)
|
constexpr float quint_in(float t)
|
||||||
{
|
{
|
||||||
return t * t * t * t * t;
|
return t * t * t * t * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float quint_out(float t)
|
constexpr float quint_out(float t)
|
||||||
{
|
{
|
||||||
float f = (t - 1);
|
float f = (t - 1);
|
||||||
return f * f * f * f * f + 1;
|
return f * f * f * f * f + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float quint_in_out(float t)
|
constexpr float quint_in_out(float t)
|
||||||
{
|
{
|
||||||
if (t < 0.5f)
|
if (t < 0.5f)
|
||||||
return 16 * t * t * t * t * t;
|
return 16 * t * t * t * t * t;
|
||||||
@ -216,7 +215,7 @@ namespace Blah
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float bounce_out(float t)
|
constexpr float bounce_out(float t)
|
||||||
{
|
{
|
||||||
if (t < 4 / 11.0f)
|
if (t < 4 / 11.0f)
|
||||||
return (121 * t * t) / 16.0f;
|
return (121 * t * t) / 16.0f;
|
||||||
@ -228,12 +227,12 @@ namespace Blah
|
|||||||
return (54 / 5.0f * t * t) - (513 / 25.0f * t) + 268 / 25.0f;
|
return (54 / 5.0f * t * t) - (513 / 25.0f * t) + 268 / 25.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float bounce_in(float t)
|
constexpr float bounce_in(float t)
|
||||||
{
|
{
|
||||||
return 1 - bounce_out(1 - t);
|
return 1 - bounce_out(1 - t);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float bounce_in_out(float t)
|
constexpr float bounce_in_out(float t)
|
||||||
{
|
{
|
||||||
if (t < 0.5f)
|
if (t < 0.5f)
|
||||||
return 0.5f * bounce_in(t * 2);
|
return 0.5f * bounce_in(t * 2);
|
||||||
@ -245,6 +244,8 @@ namespace Blah
|
|||||||
{
|
{
|
||||||
switch (e)
|
switch (e)
|
||||||
{
|
{
|
||||||
|
case Easers::Linear: return &linear;
|
||||||
|
|
||||||
case Easers::CubeIn: return &cube_in;
|
case Easers::CubeIn: return &cube_in;
|
||||||
case Easers::CubeOut: return &cube_out;
|
case Easers::CubeOut: return &cube_out;
|
||||||
case Easers::CubeInOut: return &cube_in_out;
|
case Easers::CubeInOut: return &cube_in_out;
|
||||||
@ -296,6 +297,7 @@ namespace Blah
|
|||||||
{
|
{
|
||||||
switch (e)
|
switch (e)
|
||||||
{
|
{
|
||||||
|
case Easers::Linear: return "Linear";
|
||||||
case Easers::CubeIn: return "CubeIn";
|
case Easers::CubeIn: return "CubeIn";
|
||||||
case Easers::CubeOut: return "CubeOut";
|
case Easers::CubeOut: return "CubeOut";
|
||||||
case Easers::CubeInOut: return "CubeInOut";
|
case Easers::CubeInOut: return "CubeInOut";
|
||||||
|
@ -10,7 +10,7 @@ namespace Blah
|
|||||||
Vec2 a;
|
Vec2 a;
|
||||||
Vec2 b;
|
Vec2 b;
|
||||||
|
|
||||||
Line() {}
|
Line() = default;
|
||||||
Line(float x0, float y0, float x1, float y1);
|
Line(float x0, float y0, float x1, float y1);
|
||||||
Line(const Vec2& start, const Vec2& end);
|
Line(const Vec2& start, const Vec2& end);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ namespace Blah
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileStream();
|
FileStream();
|
||||||
FileStream(const char* path, FileMode mode = FileMode::ReadWrite);
|
FileStream(const FilePath& path, FileMode mode = FileMode::ReadWrite);
|
||||||
FileStream(FileStream&& fs) noexcept;
|
FileStream(FileStream&& fs) noexcept;
|
||||||
FileStream& operator=(FileStream&& fs) noexcept;
|
FileStream& operator=(FileStream&& fs) noexcept;
|
||||||
~FileStream();
|
~FileStream();
|
||||||
@ -16,9 +16,9 @@ namespace Blah
|
|||||||
virtual i64 length() const override;
|
virtual i64 length() const override;
|
||||||
virtual i64 position() const override;
|
virtual i64 position() const override;
|
||||||
virtual i64 seek(i64 seekTo) override;
|
virtual i64 seek(i64 seekTo) override;
|
||||||
virtual bool is_open() const override { return m_handle != nullptr; }
|
virtual bool is_open() const override;
|
||||||
virtual bool is_readable() const override { return m_handle != nullptr && (m_mode == FileMode::ReadWrite || m_mode == FileMode::Read); }
|
virtual bool is_readable() const override;
|
||||||
virtual bool is_writable() const override { return m_handle != nullptr && (m_mode == FileMode::ReadWrite || m_mode == FileMode::Write); }
|
virtual bool is_writable() const override;
|
||||||
virtual void close() override;
|
virtual void close() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -26,7 +26,7 @@ namespace Blah
|
|||||||
virtual i64 write_from(const void* ptr, i64 length) override;
|
virtual i64 write_from(const void* ptr, i64 length) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileMode m_mode;
|
FileMode m_mode;
|
||||||
void* m_handle;
|
void* m_handle;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -36,7 +36,7 @@ namespace Blah
|
|||||||
// closes the stream
|
// closes the stream
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
|
||||||
// pipes the contents of this tream to another stream
|
// pipes the contents of this stream to another stream
|
||||||
i64 pipe(Stream& to, i64 length);
|
i64 pipe(Stream& to, i64 length);
|
||||||
|
|
||||||
// reads the amount of bytes into the given buffer, and returns the amount read
|
// reads the amount of bytes into the given buffer, and returns the amount read
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <blah/core/filesystem.h>
|
#include <blah/core/filesystem.h>
|
||||||
|
#include <blah/streams/filestream.h>
|
||||||
#include "../internal/platform_backend.h"
|
#include "../internal/platform_backend.h"
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
@ -13,6 +14,11 @@ bool File::remove(const FilePath& path)
|
|||||||
return PlatformBackend::file_delete(path.cstr());
|
return PlatformBackend::file_delete(path.cstr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileStream File::open(const FilePath& path , FileMode mode)
|
||||||
|
{
|
||||||
|
return FileStream(path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
bool Directory::create(const FilePath& path)
|
bool Directory::create(const FilePath& path)
|
||||||
{
|
{
|
||||||
return PlatformBackend::dir_create(path.cstr());
|
return PlatformBackend::dir_create(path.cstr());
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
CharacterRange::CharacterRange()
|
SpriteFont::CharRange::CharRange()
|
||||||
: from(0), to(0) {}
|
: from(0), to(0) {}
|
||||||
CharacterRange::CharacterRange(u32 single)
|
SpriteFont::CharRange::CharRange(Codepoint single)
|
||||||
: from(single), to(single) {}
|
: from(single), to(single) {}
|
||||||
CharacterRange::CharacterRange(u32 from, u32 to)
|
SpriteFont::CharRange::CharRange(Codepoint from, Codepoint to)
|
||||||
: from(from), to(to) {}
|
: from(from), to(to) {}
|
||||||
|
|
||||||
const CharacterSet CharacterRange::ASCII = CharacterSet({ CharacterRange(32, 128) });
|
const SpriteFont::CharSet SpriteFont::CharRange::ASCII = SpriteFont::CharSet({ CharRange(32, 128) });
|
||||||
|
|
||||||
SpriteFont::SpriteFont()
|
SpriteFont::SpriteFont()
|
||||||
{
|
{
|
||||||
@ -22,24 +22,24 @@ SpriteFont::SpriteFont()
|
|||||||
line_gap = 0;
|
line_gap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteFont::SpriteFont(const char* file, float size)
|
SpriteFont::SpriteFont(const FilePath& file, float size)
|
||||||
{
|
{
|
||||||
build(file, size, CharacterRange::ASCII);
|
rebuild(file, size, CharRange::ASCII);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteFont::SpriteFont(const char* file, float size, const CharacterSet& charset)
|
SpriteFont::SpriteFont(const FilePath& file, float size, const CharSet& charset)
|
||||||
{
|
{
|
||||||
build(file, size, charset);
|
rebuild(file, size, charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteFont::SpriteFont(const Font& font, float size)
|
SpriteFont::SpriteFont(const Font& font, float size)
|
||||||
{
|
{
|
||||||
build(font, size, CharacterRange::ASCII);
|
rebuild(font, size, CharRange::ASCII);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteFont::SpriteFont(const Font& font, float size, const CharacterSet& charset)
|
SpriteFont::SpriteFont(const Font& font, float size, const CharSet& charset)
|
||||||
{
|
{
|
||||||
build(font, size, charset);
|
rebuild(font, size, charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteFont::SpriteFont(SpriteFont&& src) noexcept
|
SpriteFont::SpriteFont(SpriteFont&& src) noexcept
|
||||||
@ -85,7 +85,7 @@ float SpriteFont::width_of(const String& text) const
|
|||||||
float width = 0;
|
float width = 0;
|
||||||
float line_width = 0;
|
float line_width = 0;
|
||||||
|
|
||||||
u32 last = 0;
|
Codepoint last = 0;
|
||||||
for (int i = 0; i < text.length(); i ++)
|
for (int i = 0; i < text.length(); i ++)
|
||||||
{
|
{
|
||||||
if (text[i] == '\n')
|
if (text[i] == '\n')
|
||||||
@ -122,7 +122,7 @@ float SpriteFont::width_of_line(const String& text, int start) const
|
|||||||
|
|
||||||
float width = 0;
|
float width = 0;
|
||||||
|
|
||||||
u32 last;
|
Codepoint last = 0;
|
||||||
for (int i = start; i < text.length(); i ++)
|
for (int i = start; i < text.length(); i ++)
|
||||||
{
|
{
|
||||||
if (text[i] == '\n')
|
if (text[i] == '\n')
|
||||||
@ -163,16 +163,16 @@ float SpriteFont::height_of(const String& text) const
|
|||||||
return height - line_gap;
|
return height - line_gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFont::build(const char* file, float sz, const CharacterSet& charset)
|
void SpriteFont::rebuild(const FilePath& file, float sz, const CharSet& charset)
|
||||||
{
|
{
|
||||||
dispose();
|
dispose();
|
||||||
|
|
||||||
Font font(file);
|
Font font(file);
|
||||||
if (font.is_valid())
|
if (font.is_valid())
|
||||||
build(font, sz, charset);
|
rebuild(font, sz, charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFont::build(const Font& font, float size, const CharacterSet& charset)
|
void SpriteFont::rebuild(const Font& font, float size, const CharSet& charset)
|
||||||
{
|
{
|
||||||
dispose();
|
dispose();
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ void SpriteFont::build(const Font& font, float size, const CharacterSet& charset
|
|||||||
packer.max_size = 8192;
|
packer.max_size = 8192;
|
||||||
packer.power_of_two = true;
|
packer.power_of_two = true;
|
||||||
|
|
||||||
std::unordered_map<u32, int> glyphs;
|
std::unordered_map<Codepoint, int> glyphs;
|
||||||
Vector<Color> buffer;
|
Vector<Color> buffer;
|
||||||
|
|
||||||
for (auto& range : charset)
|
for (auto& range : charset)
|
||||||
@ -209,7 +209,7 @@ void SpriteFont::build(const Font& font, float size, const CharacterSet& charset
|
|||||||
glyphs[i] = glyph;
|
glyphs[i] = glyph;
|
||||||
|
|
||||||
// add character
|
// add character
|
||||||
Font::Char ch = font.get_character(glyph, scale);
|
auto ch = font.get_character(glyph, scale);
|
||||||
m_characters[i].advance = ch.advance;
|
m_characters[i].advance = ch.advance;
|
||||||
m_characters[i].offset = Vec2(ch.offset_x, ch.offset_y);
|
m_characters[i].offset = Vec2(ch.offset_x, ch.offset_y);
|
||||||
|
|
||||||
@ -232,9 +232,9 @@ void SpriteFont::build(const Font& font, float size, const CharacterSet& charset
|
|||||||
m_atlas.push_back(Texture::create(it));
|
m_atlas.push_back(Texture::create(it));
|
||||||
|
|
||||||
// add character subtextures
|
// add character subtextures
|
||||||
for (auto& it : packer.entries)
|
for (auto& it : packer.entries())
|
||||||
if (!it.empty)
|
if (!it.empty)
|
||||||
m_characters[(u32)it.id].subtexture = Subtexture(m_atlas[it.page], it.packed, it.frame);
|
m_characters[(Codepoint)it.id].subtexture = Subtexture(m_atlas[it.page], it.packed, it.frame);
|
||||||
|
|
||||||
// add kerning
|
// add kerning
|
||||||
for (auto a = glyphs.begin(); a != glyphs.end(); a++)
|
for (auto a = glyphs.begin(); a != glyphs.end(); a++)
|
||||||
@ -246,7 +246,7 @@ void SpriteFont::build(const Font& font, float size, const CharacterSet& charset
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float SpriteFont::get_kerning(u32 codepoint0, u32 codepoint1) const
|
float SpriteFont::get_kerning(Codepoint codepoint0, Codepoint codepoint1) const
|
||||||
{
|
{
|
||||||
u64 index = ((u64)codepoint0 << 32) | codepoint1;
|
u64 index = ((u64)codepoint0 << 32) | codepoint1;
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ float SpriteFont::get_kerning(u32 codepoint0, u32 codepoint1) const
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFont::set_kerning(u32 codepoint0, u32 codepoint1, float value)
|
void SpriteFont::set_kerning(Codepoint codepoint0, Codepoint codepoint1, float value)
|
||||||
{
|
{
|
||||||
u64 index = ((u64)codepoint0 << 32) | codepoint1;
|
u64 index = ((u64)codepoint0 << 32) | codepoint1;
|
||||||
|
|
||||||
@ -270,7 +270,12 @@ void SpriteFont::set_kerning(u32 codepoint0, u32 codepoint1, float value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const SpriteFont::Character& SpriteFont::get_character(u32 codepoint) const
|
SpriteFont::Character& SpriteFont::get_character(Codepoint codepoint)
|
||||||
|
{
|
||||||
|
return m_characters[codepoint];
|
||||||
|
}
|
||||||
|
|
||||||
|
const SpriteFont::Character& SpriteFont::get_character(Codepoint codepoint) const
|
||||||
{
|
{
|
||||||
static const Character empty;
|
static const Character empty;
|
||||||
auto it = m_characters.find(codepoint);
|
auto it = m_characters.find(codepoint);
|
||||||
@ -279,7 +284,12 @@ const SpriteFont::Character& SpriteFont::get_character(u32 codepoint) const
|
|||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SpriteFont::Character& SpriteFont::operator[](u32 codepoint) const
|
SpriteFont::Character& SpriteFont::operator[](Codepoint codepoint)
|
||||||
|
{
|
||||||
|
return m_characters[codepoint];
|
||||||
|
}
|
||||||
|
|
||||||
|
const SpriteFont::Character& SpriteFont::operator[](Codepoint codepoint) const
|
||||||
{
|
{
|
||||||
static const Character empty;
|
static const Character empty;
|
||||||
auto it = m_characters.find(codepoint);
|
auto it = m_characters.find(codepoint);
|
||||||
|
@ -2,16 +2,12 @@
|
|||||||
#include <blah/streams/filestream.h>
|
#include <blah/streams/filestream.h>
|
||||||
#include <blah/core/filesystem.h>
|
#include <blah/core/filesystem.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/core/common.h>
|
||||||
|
#include <blah/math/calc.h>
|
||||||
|
|
||||||
#define STBI_NO_STDIO
|
#define STBI_NO_STDIO
|
||||||
#define STBI_ONLY_ZLIB
|
#define STBI_ONLY_ZLIB
|
||||||
#include "../third_party/stb_image.h"
|
#include "../third_party/stb_image.h"
|
||||||
|
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
#define MUL_UN8(a, b, t) \
|
|
||||||
((t) = (a) * (u16)(b) + 0x80, ((((t) >> 8) + (t) ) >> 8))
|
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
Aseprite::Aseprite()
|
Aseprite::Aseprite()
|
||||||
@ -19,7 +15,7 @@ Aseprite::Aseprite()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Aseprite::Aseprite(const char* path)
|
Aseprite::Aseprite(const FilePath& path)
|
||||||
{
|
{
|
||||||
FileStream fs(path, FileMode::Read);
|
FileStream fs(path, FileMode::Read);
|
||||||
parse(fs);
|
parse(fs);
|
||||||
@ -406,6 +402,9 @@ void Aseprite::parse_slice(Stream& stream, int frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MUL_UN8(a, b, t) \
|
||||||
|
((t) = (a) * (u16)(b) + 0x80, ((((t) >> 8) + (t) ) >> 8))
|
||||||
|
|
||||||
void Aseprite::render_cel(Cel* cel, Frame* frame)
|
void Aseprite::render_cel(Cel* cel, Frame* frame)
|
||||||
{
|
{
|
||||||
Layer& layer = layers[cel->layer_index];
|
Layer& layer = layers[cel->layer_index];
|
||||||
@ -436,16 +435,16 @@ void Aseprite::render_cel(Cel* cel, Frame* frame)
|
|||||||
auto dstH = frame->image.height;
|
auto dstH = frame->image.height;
|
||||||
|
|
||||||
// blit pixels
|
// blit pixels
|
||||||
int left = MAX(0, srcX);
|
int left = Calc::max(0, srcX);
|
||||||
int right = MIN(dstW, srcX + srcW);
|
int right = Calc::min(dstW, srcX + srcW);
|
||||||
int top = MAX(0, srcY);
|
int top = Calc::max(0, srcY);
|
||||||
int bottom = MIN(dstH, srcY + srcH);
|
int bottom = Calc::min(dstH, srcY + srcH);
|
||||||
|
|
||||||
if (layer.blendmode == 0)
|
if (layer.blendmode == 0)
|
||||||
{
|
{
|
||||||
for (int dx = left, sx = -MIN(srcX, 0); dx < right; dx++, sx++)
|
for (int dx = left, sx = -Calc::min(srcX, 0); dx < right; dx++, sx++)
|
||||||
{
|
{
|
||||||
for (int dy = top, sy = -MIN(srcY, 0); dy < bottom; dy++, sy++)
|
for (int dy = top, sy = -Calc::min(srcY, 0); dy < bottom; dy++, sy++)
|
||||||
{
|
{
|
||||||
Color* srcColor = (src + sx + sy * srcW);
|
Color* srcColor = (src + sx + sy * srcW);
|
||||||
Color* dstColor = (dst + dx + dy * dstW);
|
Color* dstColor = (dst + dx + dy * dstW);
|
||||||
|
@ -56,7 +56,7 @@ Font::Font(Stream& stream) : Font()
|
|||||||
load(stream);
|
load(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::Font(const char* path) : Font()
|
Font::Font(const FilePath& path) : Font()
|
||||||
{
|
{
|
||||||
FileStream fs(path, FileMode::Read);
|
FileStream fs(path, FileMode::Read);
|
||||||
if (fs.is_readable())
|
if (fs.is_readable())
|
||||||
@ -142,14 +142,14 @@ void Font::dispose()
|
|||||||
m_style_name.dispose();
|
m_style_name.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Font::family_name() const
|
const String& Font::family_name() const
|
||||||
{
|
{
|
||||||
return m_family_name.cstr();
|
return m_family_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Font::style_name() const
|
const String& Font::style_name() const
|
||||||
{
|
{
|
||||||
return m_style_name.cstr();
|
return m_style_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Font::ascent() const
|
int Font::ascent() const
|
||||||
@ -199,9 +199,9 @@ float Font::get_kerning(int glyph1, int glyph2, float scale) const
|
|||||||
return stbtt_GetGlyphKernAdvance((stbtt_fontinfo*)m_font, glyph1, glyph2) * scale;
|
return stbtt_GetGlyphKernAdvance((stbtt_fontinfo*)m_font, glyph1, glyph2) * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::Char Font::get_character(int glyph, float scale) const
|
Font::Character Font::get_character(int glyph, float scale) const
|
||||||
{
|
{
|
||||||
Char ch;
|
Character ch;
|
||||||
|
|
||||||
if (!m_font)
|
if (!m_font)
|
||||||
return ch;
|
return ch;
|
||||||
@ -227,7 +227,7 @@ Font::Char Font::get_character(int glyph, float scale) const
|
|||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Font::get_image(const Font::Char& ch, Color* pixels) const
|
bool Font::get_image(const Font::Character& ch, Color* pixels) const
|
||||||
{
|
{
|
||||||
if (ch.has_glyph)
|
if (ch.has_glyph)
|
||||||
{
|
{
|
||||||
@ -251,6 +251,16 @@ bool Font::get_image(const Font::Char& ch, Color* pixels) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image Font::get_image(const Font::Character& ch) const
|
||||||
|
{
|
||||||
|
Image img(ch.width, ch.height);
|
||||||
|
|
||||||
|
if (get_image(ch, img.pixels))
|
||||||
|
return img;
|
||||||
|
|
||||||
|
return Image();
|
||||||
|
}
|
||||||
|
|
||||||
bool Font::is_valid() const
|
bool Font::is_valid() const
|
||||||
{
|
{
|
||||||
return m_valid;
|
return m_valid;
|
||||||
|
@ -8,7 +8,6 @@ using namespace Blah;
|
|||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#define STBI_ONLY_JPEG
|
#define STBI_ONLY_JPEG
|
||||||
#define STBI_ONLY_PNG
|
#define STBI_ONLY_PNG
|
||||||
#define STBI_ONLY_BMP
|
|
||||||
#include "../third_party/stb_image.h"
|
#include "../third_party/stb_image.h"
|
||||||
|
|
||||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
@ -59,7 +58,7 @@ Image::Image(Stream& stream)
|
|||||||
from_stream(stream);
|
from_stream(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::Image(const char* file)
|
Image::Image(const FilePath& file)
|
||||||
{
|
{
|
||||||
width = height = 0;
|
width = height = 0;
|
||||||
pixels = nullptr;
|
pixels = nullptr;
|
||||||
@ -175,6 +174,7 @@ void Image::dispose()
|
|||||||
stbi_image_free(pixels);
|
stbi_image_free(pixels);
|
||||||
else
|
else
|
||||||
delete[] pixels;
|
delete[] pixels;
|
||||||
|
|
||||||
pixels = nullptr;
|
pixels = nullptr;
|
||||||
width = height = 0;
|
width = height = 0;
|
||||||
m_stbi_ownership = false;
|
m_stbi_ownership = false;
|
||||||
@ -203,7 +203,7 @@ void Image::set_pixels(const RectI& rect, Color* data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Image::save_png(const char* file) const
|
bool Image::save_png(const FilePath& file) const
|
||||||
{
|
{
|
||||||
FileStream fs(file, FileMode::Write);
|
FileStream fs(file, FileMode::Write);
|
||||||
return save_png(fs);
|
return save_png(fs);
|
||||||
@ -232,7 +232,7 @@ bool Image::save_png(Stream& stream) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Image::save_jpg(const char* file, int quality) const
|
bool Image::save_jpg(const FilePath& file, int quality) const
|
||||||
{
|
{
|
||||||
FileStream fs(file, FileMode::Write);
|
FileStream fs(file, FileMode::Write);
|
||||||
return save_jpg(fs, quality);
|
return save_jpg(fs, quality);
|
||||||
@ -269,33 +269,31 @@ bool Image::save_jpg(Stream& stream, int quality) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Image::get_pixels(Color* dest, const Point& dest_pos, const Point& dest_size, RectI source_rect)
|
||||||
|
|
||||||
void Image::get_pixels(Color* dest, const Point& destPos, const Point& destSize, RectI sourceRect)
|
|
||||||
{
|
{
|
||||||
// can't be outside of the source image
|
// can't be outside of the source image
|
||||||
if (sourceRect.x < 0) sourceRect.x = 0;
|
if (source_rect.x < 0) source_rect.x = 0;
|
||||||
if (sourceRect.y < 0) sourceRect.y = 0;
|
if (source_rect.y < 0) source_rect.y = 0;
|
||||||
if (sourceRect.x + sourceRect.w > width) sourceRect.w = width - sourceRect.x;
|
if (source_rect.x + source_rect.w > width) source_rect.w = width - source_rect.x;
|
||||||
if (sourceRect.y + sourceRect.h > height) sourceRect.h = height - sourceRect.y;
|
if (source_rect.y + source_rect.h > height) source_rect.h = height - source_rect.y;
|
||||||
|
|
||||||
// can't be larger than our destination
|
// can't be larger than our destination
|
||||||
if (sourceRect.w > destSize.x - destPos.x)
|
if (source_rect.w > dest_size.x - dest_pos.x)
|
||||||
sourceRect.w = destSize.x - destPos.x;
|
source_rect.w = dest_size.x - dest_pos.x;
|
||||||
if (sourceRect.h > destSize.y - destPos.y)
|
if (source_rect.h > dest_size.y - dest_pos.y)
|
||||||
sourceRect.h = destSize.y - destPos.y;
|
source_rect.h = dest_size.y - dest_pos.y;
|
||||||
|
|
||||||
for (int y = 0; y < sourceRect.h; y++)
|
for (int y = 0; y < source_rect.h; y++)
|
||||||
{
|
{
|
||||||
int to = destPos.x + (destPos.y + y) * destSize.x;
|
int to = dest_pos.x + (dest_pos.y + y) * dest_size.x;
|
||||||
int from = sourceRect.x + (sourceRect.y + y) * width;
|
int from = source_rect.x + (source_rect.y + y) * width;
|
||||||
memcpy(dest + to, pixels + from, sizeof(Color) * (int)sourceRect.w);
|
memcpy(dest + to, pixels + from, sizeof(Color) * (int)source_rect.w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Image Image::get_sub_image(const RectI& sourceRect)
|
Image Image::get_sub_image(const RectI& source_rect)
|
||||||
{
|
{
|
||||||
Image img(sourceRect.w, sourceRect.h);
|
Image img(source_rect.w, source_rect.h);
|
||||||
get_pixels(img.pixels, Point::zero, Point(img.width, img.height), sourceRect);
|
get_pixels(img.pixels, Point::zero, Point(img.width, img.height), source_rect);
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ Packer::Packer(Packer&& src) noexcept
|
|||||||
padding = src.padding;
|
padding = src.padding;
|
||||||
m_dirty = src.m_dirty;
|
m_dirty = src.m_dirty;
|
||||||
pages = std::move(src.pages);
|
pages = std::move(src.pages);
|
||||||
entries = std::move(src.entries);
|
m_entries = std::move(src.m_entries);
|
||||||
m_buffer = std::move(src.m_buffer);
|
m_buffer = std::move(src.m_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ Packer& Packer::operator=(Packer&& src) noexcept
|
|||||||
padding = src.padding;
|
padding = src.padding;
|
||||||
m_dirty = src.m_dirty;
|
m_dirty = src.m_dirty;
|
||||||
pages = std::move(src.pages);
|
pages = std::move(src.pages);
|
||||||
entries = std::move(src.entries);
|
m_entries = std::move(src.m_entries);
|
||||||
m_buffer = std::move(src.m_buffer);
|
m_buffer = std::move(src.m_buffer);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ void Packer::add(u64 id, const Image& image)
|
|||||||
add_entry(id, image.width, image.height, image.pixels);
|
add_entry(id, image.width, image.height, image.pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packer::add(u64 id, const String& path)
|
void Packer::add(u64 id, const FilePath& path)
|
||||||
{
|
{
|
||||||
add(id, Image(path.cstr()));
|
add(id, Image(path.cstr()));
|
||||||
}
|
}
|
||||||
@ -125,7 +125,12 @@ void Packer::add_entry(u64 id, int w, int h, const Color* pixels)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entries.push_back(entry);
|
m_entries.push_back(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vector<Packer::Entry>& Packer::entries() const
|
||||||
|
{
|
||||||
|
return m_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packer::pack()
|
void Packer::pack()
|
||||||
@ -137,7 +142,7 @@ void Packer::pack()
|
|||||||
pages.clear();
|
pages.clear();
|
||||||
|
|
||||||
// only if we have stuff to pack
|
// only if we have stuff to pack
|
||||||
auto count = entries.size();
|
auto count = m_entries.size();
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
// get all the sources sorted largest -> smallest
|
// get all the sources sorted largest -> smallest
|
||||||
@ -146,8 +151,8 @@ void Packer::pack()
|
|||||||
sources.resize(count);
|
sources.resize(count);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
for (int i = 0; i < entries.size(); i++)
|
for (int i = 0; i < m_entries.size(); i++)
|
||||||
sources[index++] = &entries[i];
|
sources[index++] = &m_entries[i];
|
||||||
|
|
||||||
std::sort(sources.begin(), sources.end(), [](Packer::Entry* a, Packer::Entry* b)
|
std::sort(sources.begin(), sources.end(), [](Packer::Entry* a, Packer::Entry* b)
|
||||||
{
|
{
|
||||||
@ -292,14 +297,14 @@ void Packer::pack()
|
|||||||
void Packer::clear()
|
void Packer::clear()
|
||||||
{
|
{
|
||||||
pages.clear();
|
pages.clear();
|
||||||
entries.clear();
|
m_entries.clear();
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packer::dispose()
|
void Packer::dispose()
|
||||||
{
|
{
|
||||||
pages.clear();
|
pages.clear();
|
||||||
entries.clear();
|
m_entries.clear();
|
||||||
m_buffer.close();
|
m_buffer.close();
|
||||||
max_size = 0;
|
max_size = 0;
|
||||||
power_of_two = 0;
|
power_of_two = 0;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <blah/math/color.h>
|
#include <blah/math/color.h>
|
||||||
|
#include <blah/math/vec3.h>
|
||||||
#include <blah/math/vec4.h>
|
#include <blah/math/vec4.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
@ -7,45 +8,69 @@ char const hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B
|
|||||||
#define LT_HEX_VALUE(n) ((n >= '0' && n <= '9') ? (n - '0') : ((n >= 'A' && n <= 'F') ? (10 + n - 'A') : ((n >= 'a' && n <= 'f') ? (10 + n - 'a') : 0)))
|
#define LT_HEX_VALUE(n) ((n >= '0' && n <= '9') ? (n - '0') : ((n >= 'A' && n <= 'F') ? (10 + n - 'A') : ((n >= 'a' && n <= 'f') ? (10 + n - 'a') : 0)))
|
||||||
|
|
||||||
Color::Color()
|
Color::Color()
|
||||||
: r(0), g(0), b(0), a(0) {}
|
: r(0)
|
||||||
|
, g(0)
|
||||||
|
, b(0)
|
||||||
|
, a(0) {}
|
||||||
|
|
||||||
Color::Color(int rgb) :
|
Color::Color(int rgb)
|
||||||
r((u8)((rgb & 0xFF0000) >> 16)),
|
: r((u8)((rgb & 0xFF0000) >> 16))
|
||||||
g((u8)((rgb & 0x00FF00) >> 8)),
|
, g((u8)((rgb & 0x00FF00) >> 8))
|
||||||
b((u8)(rgb & 0x0000FF)),
|
, b((u8)(rgb & 0x0000FF))
|
||||||
a(255) {}
|
, a(255) {}
|
||||||
|
|
||||||
Color::Color(int rgb, float alpha) :
|
Color::Color(int rgb, float alpha)
|
||||||
r((int)(((u8)((rgb & 0xFF0000) >> 16)) * alpha)),
|
: r((int)(((u8)((rgb & 0xFF0000) >> 16)) * alpha))
|
||||||
g((int)(((u8)((rgb & 0x00FF00) >> 8)) * alpha)),
|
, g((int)(((u8)((rgb & 0x00FF00) >> 8)) * alpha))
|
||||||
b((int)(((u8)(rgb & 0x0000FF)) * alpha)),
|
, b((int)(((u8)(rgb & 0x0000FF)) * alpha))
|
||||||
a((int)(255 * alpha)) {}
|
, a((int)(255 * alpha)) {}
|
||||||
|
|
||||||
Color::Color(u8 r, u8 g, u8 b)
|
Color::Color(u8 r, u8 g, u8 b)
|
||||||
: r(r), g(g), b(b), a(255) {}
|
: r(r)
|
||||||
|
, g(g)
|
||||||
|
, b(b)
|
||||||
|
, a(255) {}
|
||||||
|
|
||||||
Color::Color(u8 r, u8 g, u8 b, u8 a)
|
Color::Color(u8 r, u8 g, u8 b, u8 a)
|
||||||
: r(r), g(g), b(b), a(a) {}
|
: r(r)
|
||||||
|
, g(g)
|
||||||
|
, b(b)
|
||||||
|
, a(a) {}
|
||||||
|
|
||||||
|
Color::Color(const Vec3& vec3)
|
||||||
|
: r((int)(vec3.x * 255))
|
||||||
|
, g((int)(vec3.y * 255))
|
||||||
|
, b((int)(vec3.z * 255))
|
||||||
|
, a((int)(255)) {}
|
||||||
|
|
||||||
|
Color::Color(const Vec3& vec3, float alpha)
|
||||||
|
: r((int)(vec3.x * alpha * 255))
|
||||||
|
, g((int)(vec3.y* alpha * 255))
|
||||||
|
, b((int)(vec3.z* alpha * 255))
|
||||||
|
, a((int)(alpha * 255)) {}
|
||||||
|
|
||||||
Color::Color(const Vec4& vec4)
|
Color::Color(const Vec4& vec4)
|
||||||
: r((int)(vec4.x * 255)), g((int)(vec4.y * 255)), b((int)(vec4.z * 255)), a((int)(vec4.w * 255)) {}
|
: r((int)(vec4.x * 255))
|
||||||
|
, g((int)(vec4.y * 255))
|
||||||
|
, b((int)(vec4.z * 255))
|
||||||
|
, a((int)(vec4.w * 255)) {}
|
||||||
|
|
||||||
Color::Color(const char* value) : r(0), g(0), b(0), a(255)
|
Color::Color(const String& value)
|
||||||
|
: r(0)
|
||||||
|
, g(0)
|
||||||
|
, b(0)
|
||||||
|
, a(255)
|
||||||
{
|
{
|
||||||
int length = 0;
|
|
||||||
while (value[length] != '\0' && length < 10)
|
|
||||||
length ++;
|
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
if (length > 0 && value[0] == '#')
|
if (value.length() > 0 && value[0] == '#')
|
||||||
offset = 1;
|
offset = 1;
|
||||||
else if (length >= 1 && value[0] == '0' && (value[1] == 'x' || value[1] == 'X'))
|
else if (value.length() >= 1 && value[0] == '0' && (value[1] == 'x' || value[1] == 'X'))
|
||||||
offset = 2;
|
offset = 2;
|
||||||
|
|
||||||
if (length - offset >= 8)
|
if (value.length() - offset >= 8)
|
||||||
a = (LT_HEX_VALUE(value[offset + 6]) << 4) + LT_HEX_VALUE(value[offset + 7]);
|
a = (LT_HEX_VALUE(value[offset + 6]) << 4) + LT_HEX_VALUE(value[offset + 7]);
|
||||||
|
|
||||||
if (length - offset >= 6)
|
if (value.length() - offset >= 6)
|
||||||
{
|
{
|
||||||
r = (LT_HEX_VALUE(value[offset + 0]) << 4) + LT_HEX_VALUE(value[offset + 1]);
|
r = (LT_HEX_VALUE(value[offset + 0]) << 4) + LT_HEX_VALUE(value[offset + 1]);
|
||||||
g = (LT_HEX_VALUE(value[offset + 2]) << 4) + LT_HEX_VALUE(value[offset + 3]);
|
g = (LT_HEX_VALUE(value[offset + 2]) << 4) + LT_HEX_VALUE(value[offset + 3]);
|
||||||
|
@ -11,7 +11,7 @@ FileStream::FileStream()
|
|||||||
m_mode = FileMode::None;
|
m_mode = FileMode::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream::FileStream(const char* path, FileMode mode)
|
FileStream::FileStream(const FilePath& path, FileMode mode)
|
||||||
: m_mode(mode)
|
: m_mode(mode)
|
||||||
{
|
{
|
||||||
if (!PlatformBackend::file_open(path, &m_handle, mode))
|
if (!PlatformBackend::file_open(path, &m_handle, mode))
|
||||||
@ -63,6 +63,21 @@ i64 FileStream::seek(i64 seek_to)
|
|||||||
return PlatformBackend::file_seek(m_handle, seek_to);
|
return PlatformBackend::file_seek(m_handle, seek_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FileStream::is_open() const
|
||||||
|
{
|
||||||
|
return m_handle != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileStream::is_readable() const
|
||||||
|
{
|
||||||
|
return m_handle != nullptr && (m_mode == FileMode::ReadWrite || m_mode == FileMode::Read);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileStream::is_writable() const
|
||||||
|
{
|
||||||
|
return m_handle != nullptr && (m_mode == FileMode::ReadWrite || m_mode == FileMode::Write);
|
||||||
|
}
|
||||||
|
|
||||||
i64 FileStream::read_into(void* ptr, i64 length)
|
i64 FileStream::read_into(void* ptr, i64 length)
|
||||||
{
|
{
|
||||||
if (m_handle == nullptr)
|
if (m_handle == nullptr)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user