mirror of
https://github.com/enduro2d/enduro2d.git
synced 2026-01-06 11:51:00 +07:00
@@ -11,6 +11,7 @@
|
||||
#include "assets/atlas_asset.hpp"
|
||||
#include "assets/binary_asset.hpp"
|
||||
#include "assets/flipbook_asset.hpp"
|
||||
#include "assets/font_asset.hpp"
|
||||
#include "assets/image_asset.hpp"
|
||||
#include "assets/json_asset.hpp"
|
||||
#include "assets/material_asset.hpp"
|
||||
@@ -29,12 +30,14 @@
|
||||
#include "components/camera.hpp"
|
||||
#include "components/flipbook_player.hpp"
|
||||
#include "components/flipbook_source.hpp"
|
||||
#include "components/label.hpp"
|
||||
#include "components/model_renderer.hpp"
|
||||
#include "components/renderer.hpp"
|
||||
#include "components/scene.hpp"
|
||||
#include "components/sprite_renderer.hpp"
|
||||
|
||||
#include "systems/flipbook_system.hpp"
|
||||
#include "systems/label_system.hpp"
|
||||
#include "systems/render_system.hpp"
|
||||
|
||||
#include "address.hpp"
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace e2d
|
||||
class atlas_asset;
|
||||
class binary_asset;
|
||||
class flipbook_asset;
|
||||
class font_asset;
|
||||
class image_asset;
|
||||
class json_asset;
|
||||
class material_asset;
|
||||
@@ -41,12 +42,14 @@ namespace e2d
|
||||
class camera;
|
||||
class flipbook_player;
|
||||
class flipbook_source;
|
||||
class label;
|
||||
class model_renderer;
|
||||
class renderer;
|
||||
class scene;
|
||||
class sprite_renderer;
|
||||
|
||||
class flipbook_system;
|
||||
class label_system;
|
||||
class render_system;
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
|
||||
20
headers/enduro2d/high/assets/font_asset.hpp
Normal file
20
headers/enduro2d/high/assets/font_asset.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../library.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class font_asset final : public content_asset<font_asset, font> {
|
||||
public:
|
||||
static const char* type_name() noexcept { return "font_asset"; }
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
281
headers/enduro2d/high/components/label.hpp
Normal file
281
headers/enduro2d/high/components/label.hpp
Normal file
@@ -0,0 +1,281 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../factory.hpp"
|
||||
#include "../assets/font_asset.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class label final {
|
||||
public:
|
||||
class dirty final {
|
||||
};
|
||||
public:
|
||||
enum class haligns {
|
||||
left,
|
||||
center,
|
||||
right
|
||||
};
|
||||
|
||||
enum class valigns {
|
||||
top,
|
||||
center,
|
||||
bottom,
|
||||
baseline
|
||||
};
|
||||
public:
|
||||
label() = default;
|
||||
label(const font_asset::ptr& font);
|
||||
|
||||
label(label&& other) noexcept;
|
||||
label& operator=(label&& other) noexcept;
|
||||
|
||||
label(const label& other);
|
||||
label& operator=(const label& other);
|
||||
|
||||
label& text(str value) noexcept;
|
||||
[[nodiscard]] const str& text() const noexcept;
|
||||
|
||||
label& font(const font_asset::ptr& value) noexcept;
|
||||
[[nodiscard]] const font_asset::ptr& font() const noexcept;
|
||||
|
||||
label& tint(const color32& value) noexcept;
|
||||
[[nodiscard]] const color32& tint() const noexcept;
|
||||
|
||||
label& haligh(haligns value) noexcept;
|
||||
[[nodiscard]] haligns halign() const noexcept;
|
||||
|
||||
label& valigh(valigns value) noexcept;
|
||||
[[nodiscard]] valigns valign() const noexcept;
|
||||
|
||||
label& leading(f32 value) noexcept;
|
||||
[[nodiscard]] f32 leading() const noexcept;
|
||||
|
||||
label& tracking(f32 value) noexcept;
|
||||
[[nodiscard]] f32 tracking() const noexcept;
|
||||
|
||||
label& text_width(f32 value) noexcept;
|
||||
[[nodiscard]] f32 text_width() const noexcept;
|
||||
|
||||
label& glyph_dilate(f32 value) noexcept;
|
||||
[[nodiscard]] f32 glyph_dilate() const noexcept;
|
||||
|
||||
label& outline_width(f32 value) noexcept;
|
||||
[[nodiscard]] f32 outline_width() const noexcept;
|
||||
|
||||
label& outline_color(const color32& value) noexcept;
|
||||
[[nodiscard]] const color32& outline_color() const noexcept;
|
||||
private:
|
||||
str text_;
|
||||
font_asset::ptr font_;
|
||||
color32 tint_ = color32::white();
|
||||
haligns halign_ = haligns::center;
|
||||
valigns valign_ = valigns::baseline;
|
||||
f32 leading_ = 1.f;
|
||||
f32 tracking_ = 0.f;
|
||||
f32 text_width_ = 0.f;
|
||||
f32 glyph_dilate_ = 0.f;
|
||||
f32 outline_width_ = 0.f;
|
||||
color32 outline_color_ = color32::white();
|
||||
};
|
||||
|
||||
template <>
|
||||
class factory_loader<label> final : factory_loader<> {
|
||||
public:
|
||||
static const char* schema_source;
|
||||
|
||||
bool operator()(
|
||||
label& component,
|
||||
const fill_context& ctx) const;
|
||||
|
||||
bool operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
class factory_loader<label::dirty> final : factory_loader<> {
|
||||
public:
|
||||
static const char* schema_source;
|
||||
|
||||
bool operator()(
|
||||
label::dirty& component,
|
||||
const fill_context& ctx) const;
|
||||
|
||||
bool operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const;
|
||||
};
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
inline label::label(const font_asset::ptr& value)
|
||||
: font_(value) {}
|
||||
|
||||
inline label::label(label&& other) noexcept
|
||||
: text_(std::move(other.text_))
|
||||
, font_(std::move(other.font_))
|
||||
, tint_(other.tint_)
|
||||
, halign_(other.halign_)
|
||||
, valign_(other.valign_)
|
||||
, leading_(other.leading_)
|
||||
, tracking_(other.tracking_)
|
||||
, text_width_(other.text_width_)
|
||||
, glyph_dilate_(other.glyph_dilate_)
|
||||
, outline_width_(other.outline_width_)
|
||||
, outline_color_(other.outline_color_) {}
|
||||
|
||||
inline label& label::operator=(label&& other) noexcept {
|
||||
if ( this != &other ) {
|
||||
text_ = std::move(other.text_);
|
||||
font_ = std::move(other.font_);
|
||||
tint_ = other.tint_;
|
||||
halign_ = other.halign_;
|
||||
valign_ = other.valign_;
|
||||
leading_ = other.leading_;
|
||||
tracking_ = other.tracking_;
|
||||
text_width_ = other.text_width_;
|
||||
glyph_dilate_ = other.glyph_dilate_;
|
||||
outline_width_ = other.outline_width_;
|
||||
outline_color_ = other.outline_color_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline label::label(const label& other)
|
||||
: text_(other.text_)
|
||||
, font_(other.font_)
|
||||
, tint_(other.tint_)
|
||||
, halign_(other.halign_)
|
||||
, valign_(other.valign_)
|
||||
, leading_(other.leading_)
|
||||
, tracking_(other.tracking_)
|
||||
, text_width_(other.text_width_)
|
||||
, glyph_dilate_(other.glyph_dilate_)
|
||||
, outline_width_(other.outline_width_)
|
||||
, outline_color_(other.outline_color_) {}
|
||||
|
||||
inline label& label::operator=(const label& other) {
|
||||
if ( this != &other ) {
|
||||
text_ = other.text_;
|
||||
font_ = other.font_;
|
||||
tint_ = other.tint_;
|
||||
halign_ = other.halign_;
|
||||
valign_ = other.valign_;
|
||||
leading_ = other.leading_;
|
||||
tracking_ = other.tracking_;
|
||||
text_width_ = other.text_width_;
|
||||
glyph_dilate_ = other.glyph_dilate_;
|
||||
outline_width_ = other.outline_width_;
|
||||
outline_color_ = other.outline_color_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline label& label::text(str value) noexcept {
|
||||
text_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const str& label::text() const noexcept {
|
||||
return text_;
|
||||
}
|
||||
|
||||
inline label& label::font(const font_asset::ptr& value) noexcept {
|
||||
font_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const font_asset::ptr& label::font() const noexcept {
|
||||
return font_;
|
||||
}
|
||||
|
||||
inline label& label::tint(const color32& value) noexcept {
|
||||
tint_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const color32& label::tint() const noexcept {
|
||||
return tint_;
|
||||
}
|
||||
|
||||
inline label& label::haligh(haligns value) noexcept {
|
||||
halign_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline label::haligns label::halign() const noexcept {
|
||||
return halign_;
|
||||
}
|
||||
|
||||
inline label& label::valigh(valigns value) noexcept {
|
||||
valign_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline label::valigns label::valign() const noexcept {
|
||||
return valign_;
|
||||
}
|
||||
|
||||
inline label& label::leading(f32 value) noexcept {
|
||||
leading_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline f32 label::leading() const noexcept {
|
||||
return leading_;
|
||||
}
|
||||
|
||||
inline label& label::tracking(f32 value) noexcept {
|
||||
tracking_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline f32 label::tracking() const noexcept {
|
||||
return tracking_;
|
||||
}
|
||||
|
||||
inline label& label::text_width(f32 value) noexcept {
|
||||
text_width_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline f32 label::text_width() const noexcept {
|
||||
return text_width_;
|
||||
}
|
||||
|
||||
inline label& label::glyph_dilate(f32 value) noexcept {
|
||||
glyph_dilate_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline f32 label::glyph_dilate() const noexcept {
|
||||
return glyph_dilate_;
|
||||
}
|
||||
|
||||
inline label& label::outline_width(f32 value) noexcept {
|
||||
outline_width_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline f32 label::outline_width() const noexcept {
|
||||
return outline_width_;
|
||||
}
|
||||
|
||||
inline label& label::outline_color(const color32& value) noexcept {
|
||||
outline_color_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const color32& label::outline_color() const noexcept {
|
||||
return outline_color_;
|
||||
}
|
||||
}
|
||||
22
headers/enduro2d/high/systems/label_system.hpp
Normal file
22
headers/enduro2d/high/systems/label_system.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class label_system final : public ecs::system {
|
||||
public:
|
||||
label_system();
|
||||
~label_system() noexcept final;
|
||||
void process(ecs::registry& owner) override;
|
||||
private:
|
||||
class internal_state;
|
||||
std::unique_ptr<internal_state> state_;
|
||||
};
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "color32.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "filesystem.inl"
|
||||
#include "font.hpp"
|
||||
#include "image.hpp"
|
||||
#include "intrusive_list.hpp"
|
||||
#include "intrusive_ptr.hpp"
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace e2d
|
||||
class color32;
|
||||
class read_file;
|
||||
class write_file;
|
||||
class font;
|
||||
class image;
|
||||
class mesh;
|
||||
class shape;
|
||||
@@ -66,7 +67,7 @@ namespace e2d
|
||||
using milliseconds = unit<T, milliseconds_tag>;
|
||||
template < typename T >
|
||||
using microseconds = unit<T, microseconds_tag>;
|
||||
|
||||
|
||||
using secf = seconds<f32>;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,9 @@ namespace e2d
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
vec3<f32> make_vec3(const color& c) noexcept;
|
||||
vec4<f32> make_vec4(const color& c) noexcept;
|
||||
|
||||
bool operator<(const color& l, const color& r) noexcept;
|
||||
bool operator==(const color& l, const color& r) noexcept;
|
||||
bool operator!=(const color& l, const color& r) noexcept;
|
||||
|
||||
@@ -55,6 +55,9 @@ namespace e2d
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
vec3<u8> make_vec3(const color32& c) noexcept;
|
||||
vec4<u8> make_vec4(const color32& c) noexcept;
|
||||
|
||||
bool operator<(const color32& l, const color32& r) noexcept;
|
||||
bool operator==(const color32& l, const color32& r) noexcept;
|
||||
bool operator!=(const color32& l, const color32& r) noexcept;
|
||||
|
||||
88
headers/enduro2d/utils/font.hpp
Normal file
88
headers/enduro2d/utils/font.hpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "_utils.hpp"
|
||||
|
||||
#include "buffer.hpp"
|
||||
#include "buffer_view.hpp"
|
||||
#include "streams.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class font final {
|
||||
public:
|
||||
struct font_info {
|
||||
str atlas_file;
|
||||
v2u atlas_size;
|
||||
u32 font_size{0};
|
||||
u32 line_height{0};
|
||||
u32 glyph_ascent{0};
|
||||
};
|
||||
|
||||
struct glyph_info {
|
||||
v2i offset;
|
||||
b2u tex_rect;
|
||||
i32 advance{0};
|
||||
};
|
||||
|
||||
struct content {
|
||||
font_info info;
|
||||
flat_map<u64, i32> kernings;
|
||||
flat_map<u32, glyph_info> glyphs;
|
||||
};
|
||||
public:
|
||||
font() = default;
|
||||
|
||||
font(font&& other) noexcept;
|
||||
font& operator=(font&& other) noexcept;
|
||||
|
||||
font(const font& other);
|
||||
font& operator=(const font& other);
|
||||
|
||||
font(content&& content) noexcept;
|
||||
font(const content& content);
|
||||
|
||||
font& assign(font&& other) noexcept;
|
||||
font& assign(const font& other);
|
||||
|
||||
font& assign(content&& content) noexcept;
|
||||
font& assign(const content& content);
|
||||
|
||||
void swap(font& other) noexcept;
|
||||
void clear() noexcept;
|
||||
bool empty() const noexcept;
|
||||
|
||||
const font_info& info() const noexcept;
|
||||
const flat_map<u64, i32>& kernings() const noexcept;
|
||||
const flat_map<u32, glyph_info>& glyphs() const noexcept;
|
||||
|
||||
i32 get_kerning(u32 first, u32 second) const noexcept;
|
||||
const glyph_info* find_glyph(u32 code_point) const noexcept;
|
||||
private:
|
||||
content content_;
|
||||
};
|
||||
|
||||
void swap(font& l, font& r) noexcept;
|
||||
bool operator==(const font& l, const font& r) noexcept;
|
||||
bool operator!=(const font& l, const font& r) noexcept;
|
||||
|
||||
bool operator==(const font::font_info& l, const font::font_info& r) noexcept;
|
||||
bool operator==(const font::glyph_info& l, const font::glyph_info& r) noexcept;
|
||||
bool operator==(const font::content& l, const font::content& r) noexcept;
|
||||
}
|
||||
|
||||
namespace e2d::fonts
|
||||
{
|
||||
bool try_load_font(
|
||||
font& dst,
|
||||
buffer_view src) noexcept;
|
||||
|
||||
bool try_load_font(
|
||||
font& dst,
|
||||
const input_stream_uptr& src) noexcept;
|
||||
}
|
||||
Submodule modules/catch2 updated: 0c27554af5...f0b7b0ca11
Submodule modules/ecs.hpp updated: f10e0767fa...d32f438684
Submodule modules/glew updated: 2545ef4e02...8c42082242
Submodule modules/glfw updated: 3a5e99e59a...d834f01ca4
Submodule modules/imgui updated: 71d20abbc3...a8eb64fc54
Submodule modules/miniz updated: e0c964c4a3...e71344bdd7
Submodule modules/promise.hpp updated: b550f83099...c7aeff3710
Submodule modules/pugixml updated: 5a867cb1e3...fcb7c8d3e5
Submodule modules/rapidjson updated: d87b698d0f...4b3d7c2f42
Submodule modules/stb updated: c72a95d766...1034f5e5c4
Submodule modules/utfcpp updated: 2370b95a86...088dd3ad77
@@ -36,3 +36,4 @@ add_e2d_sample(02)
|
||||
add_e2d_sample(03)
|
||||
add_e2d_sample(04)
|
||||
add_e2d_sample(05)
|
||||
|
||||
|
||||
713
samples/bin/library/arial_bm.fnt
Normal file
713
samples/bin/library/arial_bm.fnt
Normal file
@@ -0,0 +1,713 @@
|
||||
info face="Arial" size=50 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=1,1,1,1 spacing=1,1 outline=3
|
||||
common lineHeight=50 base=40 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=0 redChnl=1 greenChnl=3 blueChnl=3
|
||||
page id=0 file="arial_bm.png"
|
||||
chars count=161
|
||||
char id=32 x=0 y=395 width=11 height=9 xoffset=-5 yoffset=45 xadvance=12 page=0 chnl=15
|
||||
char id=33 x=350 y=255 width=14 height=40 xoffset=0 yoffset=4 xadvance=14 page=0 chnl=15
|
||||
char id=34 x=343 y=361 width=21 height=19 xoffset=-3 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=35 x=68 y=216 width=33 height=40 xoffset=-5 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=36 x=446 y=0 width=30 height=46 xoffset=-3 yoffset=2 xadvance=24 page=0 chnl=15
|
||||
char id=37 x=347 y=49 width=43 height=40 xoffset=-2 yoffset=4 xadvance=39 page=0 chnl=15
|
||||
char id=38 x=229 y=132 width=36 height=40 xoffset=-3 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=39 x=494 y=323 width=14 height=19 xoffset=-3 yoffset=4 xadvance=8 page=0 chnl=15
|
||||
char id=40 x=225 y=0 width=20 height=49 xoffset=-2 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=41 x=246 y=0 width=20 height=49 xoffset=-2 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=42 x=319 y=361 width=23 height=21 xoffset=-3 yoffset=4 xadvance=17 page=0 chnl=15
|
||||
char id=43 x=167 y=363 width=30 height=30 xoffset=-2 yoffset=10 xadvance=26 page=0 chnl=15
|
||||
char id=44 x=365 y=361 width=14 height=19 xoffset=-1 yoffset=32 xadvance=12 page=0 chnl=15
|
||||
char id=45 x=466 y=358 width=21 height=12 xoffset=-3 yoffset=23 xadvance=15 page=0 chnl=15
|
||||
char id=46 x=488 y=358 width=14 height=12 xoffset=-1 yoffset=32 xadvance=12 page=0 chnl=15
|
||||
char id=47 x=267 y=255 width=22 height=40 xoffset=-5 yoffset=4 xadvance=12 page=0 chnl=15
|
||||
char id=48 x=326 y=214 width=30 height=40 xoffset=-3 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=49 x=313 y=255 width=21 height=40 xoffset=0 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=50 x=93 y=257 width=29 height=40 xoffset=-3 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=51 x=295 y=214 width=30 height=40 xoffset=-3 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=52 x=168 y=215 width=31 height=40 xoffset=-4 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=53 x=357 y=214 width=30 height=40 xoffset=-3 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=54 x=419 y=212 width=30 height=40 xoffset=-3 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=55 x=450 y=212 width=30 height=40 xoffset=-3 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=56 x=481 y=211 width=30 height=40 xoffset=-3 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=57 x=0 y=257 width=30 height=40 xoffset=-3 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=58 x=497 y=252 width=14 height=31 xoffset=-1 yoffset=13 xadvance=12 page=0 chnl=15
|
||||
char id=59 x=447 y=253 width=14 height=38 xoffset=-1 yoffset=13 xadvance=12 page=0 chnl=15
|
||||
char id=60 x=198 y=362 width=30 height=29 xoffset=-2 yoffset=10 xadvance=26 page=0 chnl=15
|
||||
char id=61 x=288 y=361 width=30 height=21 xoffset=-2 yoffset=14 xadvance=26 page=0 chnl=15
|
||||
char id=62 x=229 y=362 width=30 height=29 xoffset=-2 yoffset=10 xadvance=26 page=0 chnl=15
|
||||
char id=63 x=388 y=213 width=30 height=40 xoffset=-3 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=64 x=0 y=0 width=50 height=49 xoffset=-2 yoffset=4 xadvance=45 page=0 chnl=15
|
||||
char id=65 x=286 y=91 width=39 height=40 xoffset=-5 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=66 x=315 y=173 width=33 height=40 xoffset=-2 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=67 x=444 y=88 width=38 height=40 xoffset=-3 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=68 x=376 y=131 width=35 height=40 xoffset=-1 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=69 x=102 y=216 width=32 height=40 xoffset=-1 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=70 x=232 y=215 width=31 height=40 xoffset=-1 yoffset=4 xadvance=27 page=0 chnl=15
|
||||
char id=71 x=405 y=89 width=38 height=40 xoffset=-2 yoffset=4 xadvance=34 page=0 chnl=15
|
||||
char id=72 x=245 y=173 width=34 height=40 xoffset=-1 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=73 x=335 y=255 width=14 height=40 xoffset=-1 yoffset=4 xadvance=12 page=0 chnl=15
|
||||
char id=74 x=485 y=165 width=26 height=40 xoffset=-3 yoffset=4 xadvance=22 page=0 chnl=15
|
||||
char id=75 x=340 y=132 width=35 height=40 xoffset=-2 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=76 x=123 y=257 width=29 height=40 xoffset=-2 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=77 x=166 y=92 width=39 height=40 xoffset=-1 yoffset=4 xadvance=37 page=0 chnl=15
|
||||
char id=78 x=140 y=174 width=34 height=40 xoffset=-1 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=79 x=84 y=92 width=40 height=40 xoffset=-3 yoffset=4 xadvance=34 page=0 chnl=15
|
||||
char id=80 x=0 y=216 width=33 height=40 xoffset=-1 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=81 x=0 y=50 width=40 height=42 xoffset=-3 yoffset=4 xadvance=34 page=0 chnl=15
|
||||
char id=82 x=115 y=133 width=37 height=40 xoffset=-1 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=83 x=448 y=129 width=34 height=40 xoffset=-3 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=84 x=0 y=175 width=34 height=40 xoffset=-4 yoffset=4 xadvance=26 page=0 chnl=15
|
||||
char id=85 x=35 y=175 width=34 height=40 xoffset=-1 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=86 x=0 y=134 width=38 height=40 xoffset=-4 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=87 x=194 y=50 width=52 height=40 xoffset=-4 yoffset=4 xadvance=44 page=0 chnl=15
|
||||
char id=88 x=39 y=134 width=37 height=40 xoffset=-4 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=89 x=303 y=132 width=36 height=40 xoffset=-4 yoffset=4 xadvance=28 page=0 chnl=15
|
||||
char id=90 x=412 y=130 width=35 height=40 xoffset=-4 yoffset=4 xadvance=27 page=0 chnl=15
|
||||
char id=91 x=306 y=0 width=18 height=49 xoffset=-2 yoffset=4 xadvance=12 page=0 chnl=15
|
||||
char id=92 x=290 y=255 width=22 height=40 xoffset=-5 yoffset=4 xadvance=12 page=0 chnl=15
|
||||
char id=93 x=287 y=0 width=18 height=49 xoffset=-4 yoffset=4 xadvance=12 page=0 chnl=15
|
||||
char id=94 x=260 y=362 width=27 height=25 xoffset=-4 yoffset=4 xadvance=19 page=0 chnl=15
|
||||
char id=95 x=431 y=361 width=34 height=12 xoffset=-5 yoffset=41 xadvance=24 page=0 chnl=15
|
||||
char id=96 x=413 y=361 width=17 height=14 xoffset=-2 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=97 x=144 y=298 width=30 height=32 xoffset=-3 yoffset=12 xadvance=24 page=0 chnl=15
|
||||
char id=98 x=264 y=214 width=30 height=40 xoffset=-2 yoffset=4 xadvance=25 page=0 chnl=15
|
||||
char id=99 x=268 y=296 width=29 height=32 xoffset=-3 yoffset=12 xadvance=22 page=0 chnl=15
|
||||
char id=100 x=213 y=256 width=29 height=40 xoffset=-3 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=101 x=82 y=298 width=30 height=32 xoffset=-3 yoffset=12 xadvance=24 page=0 chnl=15
|
||||
char id=102 x=243 y=256 width=23 height=40 xoffset=-4 yoffset=4 xadvance=13 page=0 chnl=15
|
||||
char id=103 x=134 y=50 width=29 height=41 xoffset=-3 yoffset=12 xadvance=25 page=0 chnl=15
|
||||
char id=104 x=483 y=83 width=28 height=40 xoffset=-2 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=105 x=380 y=255 width=14 height=40 xoffset=-2 yoffset=4 xadvance=10 page=0 chnl=15
|
||||
char id=106 x=267 y=0 width=19 height=49 xoffset=-7 yoffset=4 xadvance=10 page=0 chnl=15
|
||||
char id=107 x=483 y=124 width=28 height=40 xoffset=-2 yoffset=4 xadvance=22 page=0 chnl=15
|
||||
char id=108 x=365 y=255 width=14 height=40 xoffset=-2 yoffset=4 xadvance=10 page=0 chnl=15
|
||||
char id=109 x=0 y=298 width=42 height=32 xoffset=-2 yoffset=12 xadvance=38 page=0 chnl=15
|
||||
char id=110 x=387 y=296 width=28 height=32 xoffset=-2 yoffset=12 xadvance=24 page=0 chnl=15
|
||||
char id=111 x=206 y=297 width=30 height=32 xoffset=-3 yoffset=12 xadvance=24 page=0 chnl=15
|
||||
char id=112 x=72 y=50 width=30 height=41 xoffset=-2 yoffset=12 xadvance=25 page=0 chnl=15
|
||||
char id=113 x=41 y=50 width=30 height=41 xoffset=-3 yoffset=12 xadvance=25 page=0 chnl=15
|
||||
char id=114 x=443 y=293 width=22 height=32 xoffset=-2 yoffset=12 xadvance=15 page=0 chnl=15
|
||||
char id=115 x=358 y=296 width=28 height=32 xoffset=-3 yoffset=12 xadvance=22 page=0 chnl=15
|
||||
char id=116 x=426 y=253 width=20 height=39 xoffset=-4 yoffset=5 xadvance=12 page=0 chnl=15
|
||||
char id=117 x=29 y=363 width=28 height=31 xoffset=-2 yoffset=13 xadvance=24 page=0 chnl=15
|
||||
char id=118 x=221 y=330 width=31 height=31 xoffset=-4 yoffset=13 xadvance=23 page=0 chnl=15
|
||||
char id=119 x=466 y=291 width=41 height=31 xoffset=-4 yoffset=13 xadvance=33 page=0 chnl=15
|
||||
char id=120 x=284 y=329 width=30 height=31 xoffset=-4 yoffset=13 xadvance=22 page=0 chnl=15
|
||||
char id=121 x=153 y=256 width=29 height=40 xoffset=-4 yoffset=13 xadvance=21 page=0 chnl=15
|
||||
char id=122 x=315 y=329 width=30 height=31 xoffset=-4 yoffset=13 xadvance=22 page=0 chnl=15
|
||||
char id=123 x=178 y=0 width=23 height=49 xoffset=-4 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=124 x=325 y=0 width=13 height=49 xoffset=-1 yoffset=4 xadvance=11 page=0 chnl=15
|
||||
char id=125 x=202 y=0 width=22 height=49 xoffset=-4 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=126 x=380 y=361 width=32 height=16 xoffset=-3 yoffset=17 xadvance=26 page=0 chnl=15
|
||||
char id=1025 x=413 y=0 width=32 height=46 xoffset=-1 yoffset=-2 xadvance=29 page=0 chnl=15
|
||||
char id=1040 x=326 y=91 width=39 height=40 xoffset=-5 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=1041 x=34 y=216 width=33 height=40 xoffset=-1 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=1042 x=451 y=170 width=33 height=40 xoffset=-2 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=1043 x=31 y=257 width=30 height=40 xoffset=-1 yoffset=4 xadvance=24 page=0 chnl=15
|
||||
char id=1044 x=374 y=0 width=38 height=47 xoffset=-5 yoffset=4 xadvance=30 page=0 chnl=15
|
||||
char id=1045 x=135 y=215 width=32 height=40 xoffset=-1 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=1046 x=247 y=50 width=50 height=40 xoffset=-4 yoffset=4 xadvance=41 page=0 chnl=15
|
||||
char id=1047 x=383 y=172 width=33 height=40 xoffset=-3 yoffset=4 xadvance=27 page=0 chnl=15
|
||||
char id=1048 x=210 y=174 width=34 height=40 xoffset=-1 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=1049 x=339 y=0 width=34 height=48 xoffset=-1 yoffset=-4 xadvance=32 page=0 chnl=15
|
||||
char id=1050 x=200 y=215 width=31 height=40 xoffset=-1 yoffset=4 xadvance=26 page=0 chnl=15
|
||||
char id=1051 x=70 y=175 width=34 height=40 xoffset=-4 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=1052 x=206 y=91 width=39 height=40 xoffset=-1 yoffset=4 xadvance=37 page=0 chnl=15
|
||||
char id=1053 x=105 y=174 width=34 height=40 xoffset=-1 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=1054 x=125 y=92 width=40 height=40 xoffset=-3 yoffset=4 xadvance=34 page=0 chnl=15
|
||||
char id=1055 x=175 y=174 width=34 height=40 xoffset=-1 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=1056 x=478 y=42 width=33 height=40 xoffset=-1 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=1057 x=366 y=90 width=38 height=40 xoffset=-3 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=1058 x=280 y=173 width=34 height=40 xoffset=-4 yoffset=4 xadvance=26 page=0 chnl=15
|
||||
char id=1059 x=266 y=132 width=36 height=40 xoffset=-4 yoffset=4 xadvance=28 page=0 chnl=15
|
||||
char id=1060 x=246 y=91 width=39 height=40 xoffset=-3 yoffset=4 xadvance=33 page=0 chnl=15
|
||||
char id=1061 x=77 y=133 width=37 height=40 xoffset=-4 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=1062 x=140 y=0 width=37 height=49 xoffset=-1 yoffset=4 xadvance=33 page=0 chnl=15
|
||||
char id=1063 x=349 y=173 width=33 height=40 xoffset=-3 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=1064 x=435 y=47 width=42 height=40 xoffset=-1 yoffset=4 xadvance=40 page=0 chnl=15
|
||||
char id=1065 x=51 y=0 width=45 height=49 xoffset=-1 yoffset=4 xadvance=41 page=0 chnl=15
|
||||
char id=1066 x=391 y=48 width=43 height=40 xoffset=-5 yoffset=4 xadvance=35 page=0 chnl=15
|
||||
char id=1067 x=42 y=92 width=41 height=40 xoffset=-1 yoffset=4 xadvance=39 page=0 chnl=15
|
||||
char id=1068 x=417 y=171 width=33 height=40 xoffset=-1 yoffset=4 xadvance=29 page=0 chnl=15
|
||||
char id=1069 x=153 y=133 width=37 height=40 xoffset=-3 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=1070 x=298 y=50 width=48 height=40 xoffset=-1 yoffset=4 xadvance=44 page=0 chnl=15
|
||||
char id=1071 x=191 y=133 width=37 height=40 xoffset=-4 yoffset=4 xadvance=32 page=0 chnl=15
|
||||
char id=1072 x=237 y=297 width=30 height=32 xoffset=-3 yoffset=12 xadvance=24 page=0 chnl=15
|
||||
char id=1073 x=477 y=0 width=31 height=41 xoffset=-3 yoffset=3 xadvance=25 page=0 chnl=15
|
||||
char id=1074 x=465 y=326 width=28 height=31 xoffset=-2 yoffset=13 xadvance=23 page=0 chnl=15
|
||||
char id=1075 x=143 y=363 width=23 height=31 xoffset=-2 yoffset=13 xadvance=16 page=0 chnl=15
|
||||
char id=1076 x=462 y=253 width=34 height=37 xoffset=-5 yoffset=13 xadvance=26 page=0 chnl=15
|
||||
char id=1077 x=175 y=297 width=30 height=32 xoffset=-3 yoffset=12 xadvance=24 page=0 chnl=15
|
||||
char id=1078 x=40 y=331 width=39 height=31 xoffset=-5 yoffset=13 xadvance=29 page=0 chnl=15
|
||||
char id=1079 x=416 y=294 width=26 height=32 xoffset=-3 yoffset=12 xadvance=20 page=0 chnl=15
|
||||
char id=1080 x=377 y=329 width=29 height=31 xoffset=-2 yoffset=13 xadvance=25 page=0 chnl=15
|
||||
char id=1081 x=164 y=50 width=29 height=41 xoffset=-2 yoffset=3 xadvance=25 page=0 chnl=15
|
||||
char id=1082 x=116 y=363 width=26 height=31 xoffset=-2 yoffset=13 xadvance=19 page=0 chnl=15
|
||||
char id=1083 x=188 y=330 width=32 height=31 xoffset=-4 yoffset=13 xadvance=26 page=0 chnl=15
|
||||
char id=1084 x=153 y=331 width=34 height=31 xoffset=-2 yoffset=13 xadvance=30 page=0 chnl=15
|
||||
char id=1085 x=58 y=363 width=28 height=31 xoffset=-2 yoffset=13 xadvance=24 page=0 chnl=15
|
||||
char id=1086 x=113 y=298 width=30 height=32 xoffset=-3 yoffset=12 xadvance=24 page=0 chnl=15
|
||||
char id=1087 x=87 y=363 width=28 height=31 xoffset=-2 yoffset=13 xadvance=24 page=0 chnl=15
|
||||
char id=1088 x=103 y=50 width=30 height=41 xoffset=-2 yoffset=12 xadvance=25 page=0 chnl=15
|
||||
char id=1089 x=298 y=296 width=29 height=32 xoffset=-3 yoffset=12 xadvance=22 page=0 chnl=15
|
||||
char id=1090 x=436 y=327 width=28 height=31 xoffset=-4 yoffset=13 xadvance=20 page=0 chnl=15
|
||||
char id=1091 x=183 y=256 width=29 height=40 xoffset=-4 yoffset=13 xadvance=21 page=0 chnl=15
|
||||
char id=1092 x=97 y=0 width=42 height=49 xoffset=-3 yoffset=4 xadvance=36 page=0 chnl=15
|
||||
char id=1093 x=253 y=330 width=30 height=31 xoffset=-4 yoffset=13 xadvance=22 page=0 chnl=15
|
||||
char id=1094 x=62 y=257 width=30 height=40 xoffset=-2 yoffset=13 xadvance=25 page=0 chnl=15
|
||||
char id=1095 x=407 y=329 width=28 height=31 xoffset=-3 yoffset=13 xadvance=23 page=0 chnl=15
|
||||
char id=1096 x=0 y=331 width=39 height=31 xoffset=-2 yoffset=13 xadvance=35 page=0 chnl=15
|
||||
char id=1097 x=0 y=93 width=41 height=40 xoffset=-2 yoffset=13 xadvance=36 page=0 chnl=15
|
||||
char id=1098 x=117 y=331 width=35 height=31 xoffset=-4 yoffset=13 xadvance=28 page=0 chnl=15
|
||||
char id=1099 x=80 y=331 width=36 height=31 xoffset=-2 yoffset=13 xadvance=32 page=0 chnl=15
|
||||
char id=1100 x=0 y=363 width=28 height=31 xoffset=-2 yoffset=13 xadvance=23 page=0 chnl=15
|
||||
char id=1101 x=328 y=296 width=29 height=32 xoffset=-4 yoffset=12 xadvance=22 page=0 chnl=15
|
||||
char id=1102 x=43 y=298 width=38 height=32 xoffset=-2 yoffset=12 xadvance=33 page=0 chnl=15
|
||||
char id=1103 x=346 y=329 width=30 height=31 xoffset=-4 yoffset=13 xadvance=24 page=0 chnl=15
|
||||
char id=1105 x=395 y=254 width=30 height=39 xoffset=-3 yoffset=5 xadvance=24 page=0 chnl=15
|
||||
kernings count=547
|
||||
kerning first=32 second=65 amount=-2
|
||||
kerning first=32 second=84 amount=-1
|
||||
kerning first=32 second=89 amount=-1
|
||||
kerning first=1102 second=1095 amount=-1
|
||||
kerning first=1102 second=1093 amount=-1
|
||||
kerning first=1102 second=1090 amount=-1
|
||||
kerning first=1102 second=1084 amount=-1
|
||||
kerning first=1102 second=1083 amount=-1
|
||||
kerning first=1102 second=1078 amount=-1
|
||||
kerning first=1102 second=1076 amount=-1
|
||||
kerning first=49 second=49 amount=-3
|
||||
kerning first=65 second=32 amount=-2
|
||||
kerning first=65 second=84 amount=-3
|
||||
kerning first=65 second=86 amount=-3
|
||||
kerning first=65 second=87 amount=-2
|
||||
kerning first=65 second=89 amount=-3
|
||||
kerning first=65 second=118 amount=-1
|
||||
kerning first=65 second=119 amount=-1
|
||||
kerning first=65 second=121 amount=-1
|
||||
kerning first=1101 second=1103 amount=-1
|
||||
kerning first=70 second=44 amount=-5
|
||||
kerning first=70 second=46 amount=-5
|
||||
kerning first=70 second=65 amount=-2
|
||||
kerning first=76 second=32 amount=-2
|
||||
kerning first=76 second=84 amount=-3
|
||||
kerning first=76 second=86 amount=-3
|
||||
kerning first=76 second=87 amount=-3
|
||||
kerning first=76 second=89 amount=-3
|
||||
kerning first=76 second=121 amount=-2
|
||||
kerning first=1101 second=1093 amount=-1
|
||||
kerning first=80 second=32 amount=-1
|
||||
kerning first=80 second=44 amount=-6
|
||||
kerning first=80 second=46 amount=-6
|
||||
kerning first=80 second=65 amount=-3
|
||||
kerning first=82 second=84 amount=-1
|
||||
kerning first=82 second=86 amount=-1
|
||||
kerning first=82 second=87 amount=-1
|
||||
kerning first=82 second=89 amount=-1
|
||||
kerning first=84 second=32 amount=-1
|
||||
kerning first=84 second=44 amount=-5
|
||||
kerning first=84 second=45 amount=-2
|
||||
kerning first=84 second=46 amount=-5
|
||||
kerning first=84 second=58 amount=-5
|
||||
kerning first=1101 second=1090 amount=-1
|
||||
kerning first=84 second=65 amount=-3
|
||||
kerning first=84 second=79 amount=-1
|
||||
kerning first=84 second=97 amount=-5
|
||||
kerning first=84 second=99 amount=-5
|
||||
kerning first=84 second=101 amount=-5
|
||||
kerning first=84 second=105 amount=-2
|
||||
kerning first=84 second=111 amount=-5
|
||||
kerning first=84 second=114 amount=-2
|
||||
kerning first=84 second=115 amount=-5
|
||||
kerning first=84 second=117 amount=-2
|
||||
kerning first=84 second=119 amount=-2
|
||||
kerning first=84 second=121 amount=-2
|
||||
kerning first=86 second=44 amount=-4
|
||||
kerning first=86 second=45 amount=-2
|
||||
kerning first=86 second=46 amount=-4
|
||||
kerning first=86 second=58 amount=-2
|
||||
kerning first=1101 second=1086 amount=1
|
||||
kerning first=86 second=65 amount=-3
|
||||
kerning first=86 second=97 amount=-3
|
||||
kerning first=86 second=101 amount=-2
|
||||
kerning first=86 second=105 amount=-1
|
||||
kerning first=86 second=111 amount=-2
|
||||
kerning first=86 second=114 amount=-2
|
||||
kerning first=86 second=117 amount=-2
|
||||
kerning first=86 second=121 amount=-2
|
||||
kerning first=87 second=44 amount=-2
|
||||
kerning first=87 second=45 amount=-1
|
||||
kerning first=87 second=46 amount=-2
|
||||
kerning first=87 second=58 amount=-1
|
||||
kerning first=1101 second=1083 amount=-1
|
||||
kerning first=87 second=65 amount=-2
|
||||
kerning first=87 second=97 amount=-2
|
||||
kerning first=87 second=101 amount=-1
|
||||
kerning first=1101 second=1079 amount=-1
|
||||
kerning first=87 second=111 amount=-1
|
||||
kerning first=87 second=114 amount=-1
|
||||
kerning first=87 second=117 amount=-1
|
||||
kerning first=1101 second=1077 amount=1
|
||||
kerning first=89 second=32 amount=-1
|
||||
kerning first=89 second=44 amount=-6
|
||||
kerning first=89 second=45 amount=-4
|
||||
kerning first=89 second=46 amount=-6
|
||||
kerning first=89 second=58 amount=-2
|
||||
kerning first=1101 second=1076 amount=-1
|
||||
kerning first=89 second=65 amount=-3
|
||||
kerning first=89 second=97 amount=-3
|
||||
kerning first=89 second=101 amount=-4
|
||||
kerning first=89 second=105 amount=-2
|
||||
kerning first=89 second=111 amount=-4
|
||||
kerning first=89 second=112 amount=-3
|
||||
kerning first=89 second=113 amount=-4
|
||||
kerning first=89 second=117 amount=-2
|
||||
kerning first=89 second=118 amount=-2
|
||||
kerning first=102 second=102 amount=-1
|
||||
kerning first=1100 second=1095 amount=-3
|
||||
kerning first=114 second=44 amount=-2
|
||||
kerning first=114 second=46 amount=-2
|
||||
kerning first=1100 second=1090 amount=-3
|
||||
kerning first=118 second=44 amount=-3
|
||||
kerning first=118 second=46 amount=-3
|
||||
kerning first=119 second=44 amount=-2
|
||||
kerning first=119 second=46 amount=-2
|
||||
kerning first=121 second=44 amount=-3
|
||||
kerning first=121 second=46 amount=-3
|
||||
kerning first=1097 second=1091 amount=1
|
||||
kerning first=1097 second=1086 amount=-1
|
||||
kerning first=1097 second=1077 amount=-1
|
||||
kerning first=1094 second=1089 amount=-1
|
||||
kerning first=1094 second=1086 amount=-1
|
||||
kerning first=1094 second=1079 amount=-1
|
||||
kerning first=1094 second=1077 amount=-1
|
||||
kerning first=1093 second=1095 amount=-1
|
||||
kerning first=1093 second=1092 amount=-1
|
||||
kerning first=1093 second=1090 amount=-1
|
||||
kerning first=1093 second=1089 amount=-1
|
||||
kerning first=1093 second=1086 amount=-1
|
||||
kerning first=1093 second=1079 amount=-1
|
||||
kerning first=1093 second=1077 amount=-1
|
||||
kerning first=1093 second=1073 amount=-1
|
||||
kerning first=1093 second=1072 amount=-1
|
||||
kerning first=1092 second=1103 amount=-1
|
||||
kerning first=1092 second=1095 amount=-1
|
||||
kerning first=1092 second=1091 amount=-1
|
||||
kerning first=1092 second=1090 amount=-1
|
||||
kerning first=1092 second=1083 amount=-1
|
||||
kerning first=1092 second=1076 amount=-1
|
||||
kerning first=1092 second=1073 amount=-1
|
||||
kerning first=1091 second=1103 amount=-1
|
||||
kerning first=1091 second=1101 amount=-1
|
||||
kerning first=1091 second=1092 amount=-1
|
||||
kerning first=1091 second=1089 amount=-1
|
||||
kerning first=1091 second=1088 amount=-1
|
||||
kerning first=1091 second=1086 amount=-1
|
||||
kerning first=1091 second=1084 amount=-1
|
||||
kerning first=1091 second=1083 amount=-1
|
||||
kerning first=1091 second=1078 amount=1
|
||||
kerning first=1091 second=1077 amount=-1
|
||||
kerning first=1091 second=1076 amount=-1
|
||||
kerning first=1091 second=1073 amount=1
|
||||
kerning first=1091 second=1072 amount=-1
|
||||
kerning first=1091 second=46 amount=-4
|
||||
kerning first=1091 second=44 amount=-4
|
||||
kerning first=1090 second=1091 amount=1
|
||||
kerning first=1090 second=1089 amount=-1
|
||||
kerning first=1090 second=1086 amount=-1
|
||||
kerning first=1090 second=1083 amount=-1
|
||||
kerning first=1090 second=1078 amount=1
|
||||
kerning first=1090 second=1077 amount=-1
|
||||
kerning first=1090 second=1076 amount=-1
|
||||
kerning first=1090 second=1072 amount=-1
|
||||
kerning first=1090 second=46 amount=-5
|
||||
kerning first=1090 second=44 amount=-5
|
||||
kerning first=1089 second=1101 amount=1
|
||||
kerning first=1089 second=1095 amount=-1
|
||||
kerning first=1089 second=1086 amount=1
|
||||
kerning first=1089 second=1078 amount=1
|
||||
kerning first=1088 second=1103 amount=-1
|
||||
kerning first=1088 second=1095 amount=-1
|
||||
kerning first=1088 second=1093 amount=-1
|
||||
kerning first=1088 second=1091 amount=-1
|
||||
kerning first=1088 second=1090 amount=-1
|
||||
kerning first=1088 second=1083 amount=-2
|
||||
kerning first=1088 second=1079 amount=-1
|
||||
kerning first=1088 second=1076 amount=-1
|
||||
kerning first=1086 second=1095 amount=-1
|
||||
kerning first=1086 second=1093 amount=-1
|
||||
kerning first=1086 second=1091 amount=-1
|
||||
kerning first=1086 second=1090 amount=-1
|
||||
kerning first=1086 second=1083 amount=-1
|
||||
kerning first=1086 second=1079 amount=-1
|
||||
kerning first=1086 second=1078 amount=-1
|
||||
kerning first=1086 second=1076 amount=-1
|
||||
kerning first=1084 second=1091 amount=1
|
||||
kerning first=1084 second=1079 amount=-1
|
||||
kerning first=1084 second=1073 amount=-1
|
||||
kerning first=1083 second=1095 amount=-1
|
||||
kerning first=1083 second=1086 amount=1
|
||||
kerning first=1082 second=1101 amount=1
|
||||
kerning first=1082 second=1091 amount=1
|
||||
kerning first=1082 second=1090 amount=1
|
||||
kerning first=1082 second=1089 amount=1
|
||||
kerning first=1082 second=1086 amount=1
|
||||
kerning first=1082 second=1083 amount=1
|
||||
kerning first=1082 second=1079 amount=1
|
||||
kerning first=1082 second=1077 amount=1
|
||||
kerning first=1082 second=1073 amount=1
|
||||
kerning first=1082 second=1072 amount=1
|
||||
kerning first=1079 second=1098 amount=-1
|
||||
kerning first=1079 second=1095 amount=-1
|
||||
kerning first=1079 second=1092 amount=-1
|
||||
kerning first=1079 second=1091 amount=-1
|
||||
kerning first=1079 second=1089 amount=-1
|
||||
kerning first=1079 second=1086 amount=-1
|
||||
kerning first=1079 second=1083 amount=-1
|
||||
kerning first=1079 second=1079 amount=-1
|
||||
kerning first=1079 second=1077 amount=-1
|
||||
kerning first=1079 second=1076 amount=-1
|
||||
kerning first=1079 second=1073 amount=-1
|
||||
kerning first=1078 second=1098 amount=1
|
||||
kerning first=1078 second=1095 amount=-1
|
||||
kerning first=1078 second=1091 amount=1
|
||||
kerning first=1078 second=1073 amount=1
|
||||
kerning first=1077 second=1095 amount=-1
|
||||
kerning first=1077 second=1093 amount=-1
|
||||
kerning first=1077 second=1091 amount=-1
|
||||
kerning first=1077 second=1090 amount=-1
|
||||
kerning first=1077 second=1083 amount=-1
|
||||
kerning first=1077 second=1079 amount=-1
|
||||
kerning first=1077 second=1078 amount=-1
|
||||
kerning first=1077 second=1076 amount=-1
|
||||
kerning first=1077 second=1073 amount=-1
|
||||
kerning first=1076 second=1101 amount=1
|
||||
kerning first=1076 second=1098 amount=-1
|
||||
kerning first=1075 second=1103 amount=-1
|
||||
kerning first=1075 second=1089 amount=-1
|
||||
kerning first=1075 second=1086 amount=-1
|
||||
kerning first=1075 second=1083 amount=-1
|
||||
kerning first=1075 second=1079 amount=-1
|
||||
kerning first=1075 second=1077 amount=-1
|
||||
kerning first=1075 second=1076 amount=-2
|
||||
kerning first=1075 second=1072 amount=-1
|
||||
kerning first=1075 second=46 amount=-5
|
||||
kerning first=1075 second=44 amount=-5
|
||||
kerning first=1074 second=1103 amount=-1
|
||||
kerning first=1074 second=1098 amount=-1
|
||||
kerning first=1074 second=1095 amount=-2
|
||||
kerning first=1074 second=1092 amount=-1
|
||||
kerning first=1074 second=1091 amount=-1
|
||||
kerning first=1074 second=1090 amount=-1
|
||||
kerning first=1074 second=1089 amount=-1
|
||||
kerning first=1074 second=1086 amount=-1
|
||||
kerning first=1074 second=1084 amount=-1
|
||||
kerning first=1074 second=1083 amount=-1
|
||||
kerning first=1074 second=1079 amount=-1
|
||||
kerning first=1074 second=1078 amount=-1
|
||||
kerning first=1074 second=1077 amount=-1
|
||||
kerning first=1074 second=1076 amount=-1
|
||||
kerning first=1074 second=1073 amount=-1
|
||||
kerning first=1074 second=1072 amount=-1
|
||||
kerning first=1073 second=1103 amount=-1
|
||||
kerning first=1073 second=1101 amount=-1
|
||||
kerning first=1073 second=1098 amount=-1
|
||||
kerning first=1073 second=1095 amount=-1
|
||||
kerning first=1073 second=1093 amount=-1
|
||||
kerning first=1073 second=1092 amount=-1
|
||||
kerning first=1073 second=1091 amount=-1
|
||||
kerning first=1073 second=1089 amount=-1
|
||||
kerning first=1073 second=1084 amount=-1
|
||||
kerning first=1073 second=1083 amount=-2
|
||||
kerning first=1073 second=1079 amount=-1
|
||||
kerning first=1073 second=1078 amount=-1
|
||||
kerning first=1073 second=1077 amount=-1
|
||||
kerning first=1073 second=1076 amount=-2
|
||||
kerning first=1073 second=1072 amount=-1
|
||||
kerning first=1072 second=1095 amount=-1
|
||||
kerning first=1072 second=1091 amount=-1
|
||||
kerning first=1072 second=1090 amount=-1
|
||||
kerning first=1072 second=1079 amount=-1
|
||||
kerning first=1070 second=1084 amount=-1
|
||||
kerning first=1070 second=1083 amount=-2
|
||||
kerning first=1070 second=1076 amount=-2
|
||||
kerning first=1070 second=1063 amount=-1
|
||||
kerning first=1070 second=1061 amount=-2
|
||||
kerning first=1070 second=1058 amount=-3
|
||||
kerning first=1070 second=1057 amount=-1
|
||||
kerning first=1070 second=1054 amount=-1
|
||||
kerning first=1070 second=1051 amount=-2
|
||||
kerning first=1070 second=1046 amount=-1
|
||||
kerning first=1070 second=1044 amount=-2
|
||||
kerning first=1070 second=1040 amount=-1
|
||||
kerning first=1069 second=1103 amount=-1
|
||||
kerning first=1069 second=1084 amount=-1
|
||||
kerning first=1069 second=1083 amount=-1
|
||||
kerning first=1069 second=1078 amount=1
|
||||
kerning first=1069 second=1076 amount=-1
|
||||
kerning first=1069 second=1071 amount=-1
|
||||
kerning first=1069 second=1061 amount=-2
|
||||
kerning first=1069 second=1051 amount=-1
|
||||
kerning first=1069 second=1047 amount=-1
|
||||
kerning first=1069 second=1046 amount=-1
|
||||
kerning first=1069 second=1044 amount=-1
|
||||
kerning first=1068 second=1071 amount=-2
|
||||
kerning first=1068 second=1069 amount=-1
|
||||
kerning first=1068 second=1063 amount=-3
|
||||
kerning first=1068 second=1061 amount=-2
|
||||
kerning first=1068 second=1058 amount=-4
|
||||
kerning first=1068 second=1057 amount=-1
|
||||
kerning first=1068 second=1054 amount=-1
|
||||
kerning first=1068 second=1052 amount=-1
|
||||
kerning first=1068 second=1051 amount=-2
|
||||
kerning first=1068 second=1047 amount=-1
|
||||
kerning first=1068 second=1046 amount=-1
|
||||
kerning first=1068 second=1044 amount=-1
|
||||
kerning first=1068 second=1040 amount=-1
|
||||
kerning first=1066 second=1071 amount=-1
|
||||
kerning first=1065 second=1091 amount=1
|
||||
kerning first=1065 second=1072 amount=1
|
||||
kerning first=1062 second=1072 amount=1
|
||||
kerning first=1062 second=1054 amount=-1
|
||||
kerning first=1061 second=1091 amount=-1
|
||||
kerning first=1061 second=1086 amount=-1
|
||||
kerning first=1061 second=1069 amount=-2
|
||||
kerning first=1061 second=1060 amount=-1
|
||||
kerning first=1061 second=1057 amount=-1
|
||||
kerning first=1061 second=1054 amount=-1
|
||||
kerning first=1061 second=1047 amount=-1
|
||||
kerning first=1060 second=1083 amount=-1
|
||||
kerning first=1060 second=1071 amount=-2
|
||||
kerning first=1060 second=1063 amount=-1
|
||||
kerning first=1060 second=1059 amount=-2
|
||||
kerning first=1060 second=1058 amount=-3
|
||||
kerning first=1060 second=1051 amount=-1
|
||||
kerning first=1060 second=1044 amount=-1
|
||||
kerning first=1060 second=1040 amount=-1
|
||||
kerning first=1059 second=1103 amount=-3
|
||||
kerning first=1059 second=1102 amount=-2
|
||||
kerning first=1059 second=1097 amount=-2
|
||||
kerning first=1059 second=1096 amount=-2
|
||||
kerning first=1059 second=1094 amount=-2
|
||||
kerning first=1059 second=1093 amount=-2
|
||||
kerning first=1059 second=1089 amount=-3
|
||||
kerning first=1059 second=1088 amount=-2
|
||||
kerning first=1059 second=1087 amount=-2
|
||||
kerning first=1059 second=1086 amount=-3
|
||||
kerning first=1059 second=1085 amount=-2
|
||||
kerning first=1059 second=1084 amount=-2
|
||||
kerning first=1059 second=1083 amount=-3
|
||||
kerning first=1059 second=1082 amount=-2
|
||||
kerning first=1059 second=1081 amount=-1
|
||||
kerning first=1059 second=1080 amount=-2
|
||||
kerning first=1059 second=1079 amount=-3
|
||||
kerning first=1059 second=1078 amount=-1
|
||||
kerning first=1059 second=1077 amount=-3
|
||||
kerning first=1059 second=1076 amount=-3
|
||||
kerning first=1059 second=1075 amount=-2
|
||||
kerning first=1059 second=1074 amount=-3
|
||||
kerning first=1059 second=1073 amount=-1
|
||||
kerning first=1059 second=1071 amount=-1
|
||||
kerning first=1059 second=1069 amount=-1
|
||||
kerning first=1059 second=1060 amount=-1
|
||||
kerning first=1059 second=1054 amount=-1
|
||||
kerning first=1059 second=1051 amount=-1
|
||||
kerning first=1059 second=1047 amount=-1
|
||||
kerning first=1059 second=1044 amount=-2
|
||||
kerning first=1059 second=1040 amount=-3
|
||||
kerning first=1059 second=58 amount=-1
|
||||
kerning first=1059 second=46 amount=-6
|
||||
kerning first=1059 second=44 amount=-6
|
||||
kerning first=1058 second=1103 amount=-3
|
||||
kerning first=1058 second=1102 amount=-2
|
||||
kerning first=1058 second=1100 amount=-2
|
||||
kerning first=1058 second=1099 amount=-2
|
||||
kerning first=1058 second=1097 amount=-2
|
||||
kerning first=1058 second=1093 amount=-2
|
||||
kerning first=1058 second=1091 amount=-3
|
||||
kerning first=1058 second=1089 amount=-3
|
||||
kerning first=1058 second=1088 amount=-3
|
||||
kerning first=1058 second=1087 amount=-2
|
||||
kerning first=1058 second=1086 amount=-3
|
||||
kerning first=1058 second=1084 amount=-2
|
||||
kerning first=1058 second=1083 amount=-2
|
||||
kerning first=1058 second=1082 amount=-2
|
||||
kerning first=1058 second=1080 amount=-2
|
||||
kerning first=1058 second=1077 amount=-3
|
||||
kerning first=1058 second=1074 amount=-2
|
||||
kerning first=1058 second=1072 amount=-2
|
||||
kerning first=1058 second=1071 amount=-1
|
||||
kerning first=1058 second=1060 amount=-1
|
||||
kerning first=1058 second=1054 amount=-2
|
||||
kerning first=1058 second=1051 amount=-1
|
||||
kerning first=1058 second=1047 amount=-1
|
||||
kerning first=1058 second=1046 amount=1
|
||||
kerning first=1058 second=1044 amount=-1
|
||||
kerning first=1058 second=1040 amount=-1
|
||||
kerning first=1058 second=46 amount=-5
|
||||
kerning first=1058 second=44 amount=-5
|
||||
kerning first=1057 second=1095 amount=-1
|
||||
kerning first=1057 second=1078 amount=1
|
||||
kerning first=1057 second=1072 amount=1
|
||||
kerning first=1057 second=1069 amount=-1
|
||||
kerning first=1057 second=1066 amount=-2
|
||||
kerning first=1057 second=1063 amount=-1
|
||||
kerning first=1057 second=1061 amount=-3
|
||||
kerning first=1057 second=1059 amount=-1
|
||||
kerning first=1057 second=1058 amount=-1
|
||||
kerning first=1057 second=1054 amount=-1
|
||||
kerning first=1057 second=1052 amount=-1
|
||||
kerning first=1057 second=1051 amount=-1
|
||||
kerning first=1057 second=1047 amount=-1
|
||||
kerning first=1057 second=1044 amount=-1
|
||||
kerning first=1057 second=1040 amount=-1
|
||||
kerning first=1056 second=1103 amount=-1
|
||||
kerning first=1056 second=1101 amount=-1
|
||||
kerning first=1056 second=1086 amount=-2
|
||||
kerning first=1056 second=1077 amount=-2
|
||||
kerning first=1056 second=1076 amount=-3
|
||||
kerning first=1056 second=1072 amount=-1
|
||||
kerning first=1056 second=1071 amount=-1
|
||||
kerning first=1056 second=1061 amount=-2
|
||||
kerning first=1056 second=1060 amount=-1
|
||||
kerning first=1056 second=1059 amount=-1
|
||||
kerning first=1056 second=1058 amount=-2
|
||||
kerning first=1056 second=1057 amount=-1
|
||||
kerning first=1056 second=1054 amount=-1
|
||||
kerning first=1056 second=1052 amount=-1
|
||||
kerning first=1056 second=1051 amount=-3
|
||||
kerning first=1056 second=1047 amount=-1
|
||||
kerning first=1056 second=1046 amount=-1
|
||||
kerning first=1056 second=1044 amount=-3
|
||||
kerning first=1056 second=1040 amount=-3
|
||||
kerning first=1056 second=58 amount=-1
|
||||
kerning first=1056 second=46 amount=-8
|
||||
kerning first=1056 second=44 amount=-8
|
||||
kerning first=1054 second=1093 amount=-1
|
||||
kerning first=1054 second=1083 amount=-1
|
||||
kerning first=1054 second=1076 amount=-1
|
||||
kerning first=1040 second=1044 amount=1
|
||||
kerning first=1040 second=1047 amount=-1
|
||||
kerning first=1040 second=1051 amount=1
|
||||
kerning first=1040 second=1054 amount=-1
|
||||
kerning first=1040 second=1055 amount=-1
|
||||
kerning first=1040 second=1057 amount=-1
|
||||
kerning first=1040 second=1058 amount=-3
|
||||
kerning first=1040 second=1059 amount=-2
|
||||
kerning first=1040 second=1060 amount=-1
|
||||
kerning first=1040 second=1063 amount=-3
|
||||
kerning first=1040 second=1069 amount=-1
|
||||
kerning first=1040 second=1072 amount=1
|
||||
kerning first=1040 second=1090 amount=-1
|
||||
kerning first=1040 second=1091 amount=-1
|
||||
kerning first=1040 second=1092 amount=1
|
||||
kerning first=1040 second=1101 amount=1
|
||||
kerning first=1041 second=1040 amount=-1
|
||||
kerning first=1041 second=1047 amount=-1
|
||||
kerning first=1041 second=1054 amount=-1
|
||||
kerning first=1041 second=1057 amount=-1
|
||||
kerning first=1041 second=1058 amount=-2
|
||||
kerning first=1041 second=1059 amount=-1
|
||||
kerning first=1041 second=1060 amount=-1
|
||||
kerning first=1041 second=1061 amount=-1
|
||||
kerning first=1041 second=1063 amount=-2
|
||||
kerning first=1041 second=1066 amount=-1
|
||||
kerning first=1041 second=1069 amount=-1
|
||||
kerning first=1041 second=1071 amount=-1
|
||||
kerning first=1041 second=1083 amount=-1
|
||||
kerning first=1041 second=1091 amount=-1
|
||||
kerning first=1042 second=1040 amount=-1
|
||||
kerning first=1042 second=1044 amount=-1
|
||||
kerning first=1042 second=1046 amount=-1
|
||||
kerning first=1042 second=1047 amount=-1
|
||||
kerning first=1042 second=1051 amount=-1
|
||||
kerning first=1042 second=1054 amount=-1
|
||||
kerning first=1042 second=1057 amount=-1
|
||||
kerning first=1042 second=1058 amount=-3
|
||||
kerning first=1042 second=1059 amount=-1
|
||||
kerning first=1042 second=1060 amount=-1
|
||||
kerning first=1042 second=1061 amount=-2
|
||||
kerning first=1042 second=1063 amount=-2
|
||||
kerning first=1042 second=1066 amount=-3
|
||||
kerning first=1042 second=1071 amount=-1
|
||||
kerning first=1042 second=1076 amount=-1
|
||||
kerning first=1042 second=1084 amount=-1
|
||||
kerning first=1042 second=1090 amount=-1
|
||||
kerning first=1042 second=1091 amount=-1
|
||||
kerning first=1042 second=1093 amount=-1
|
||||
kerning first=1042 second=1095 amount=-1
|
||||
kerning first=1042 second=1103 amount=-1
|
||||
kerning first=1043 second=44 amount=-5
|
||||
kerning first=1043 second=46 amount=-5
|
||||
kerning first=1054 second=1071 amount=-1
|
||||
kerning first=1054 second=1063 amount=-1
|
||||
kerning first=1054 second=1061 amount=-2
|
||||
kerning first=1043 second=1040 amount=-3
|
||||
kerning first=1043 second=1044 amount=-3
|
||||
kerning first=1043 second=1047 amount=-1
|
||||
kerning first=1043 second=1051 amount=-3
|
||||
kerning first=1043 second=1052 amount=-1
|
||||
kerning first=1043 second=1054 amount=-3
|
||||
kerning first=1043 second=1057 amount=-2
|
||||
kerning first=1043 second=1071 amount=-1
|
||||
kerning first=1043 second=1072 amount=-3
|
||||
kerning first=1043 second=1074 amount=-3
|
||||
kerning first=1043 second=1076 amount=-3
|
||||
kerning first=1043 second=1077 amount=-3
|
||||
kerning first=1043 second=1080 amount=-3
|
||||
kerning first=1043 second=1083 amount=-3
|
||||
kerning first=1043 second=1084 amount=-3
|
||||
kerning first=1043 second=1085 amount=-3
|
||||
kerning first=1043 second=1086 amount=-3
|
||||
kerning first=1043 second=1088 amount=-3
|
||||
kerning first=1043 second=1091 amount=-3
|
||||
kerning first=1043 second=1099 amount=-3
|
||||
kerning first=1043 second=1100 amount=-3
|
||||
kerning first=1043 second=1102 amount=-3
|
||||
kerning first=1043 second=1103 amount=-3
|
||||
kerning first=1044 second=1059 amount=1
|
||||
kerning first=1044 second=1060 amount=-1
|
||||
kerning first=1044 second=1063 amount=-2
|
||||
kerning first=1044 second=1079 amount=1
|
||||
kerning first=1044 second=1086 amount=1
|
||||
kerning first=1044 second=1091 amount=1
|
||||
kerning first=1045 second=1047 amount=-1
|
||||
kerning first=1045 second=1089 amount=-1
|
||||
kerning first=1046 second=1047 amount=-1
|
||||
kerning first=1046 second=1054 amount=-1
|
||||
kerning first=1046 second=1057 amount=-1
|
||||
kerning first=1046 second=1058 amount=1
|
||||
kerning first=1046 second=1059 amount=1
|
||||
kerning first=1046 second=1066 amount=1
|
||||
kerning first=1046 second=1072 amount=1
|
||||
kerning first=1046 second=1077 amount=-1
|
||||
kerning first=1046 second=1086 amount=-1
|
||||
kerning first=1046 second=1091 amount=-1
|
||||
kerning first=1047 second=1051 amount=-1
|
||||
kerning first=1047 second=1054 amount=-1
|
||||
kerning first=1047 second=1057 amount=-1
|
||||
kerning first=1047 second=1058 amount=-1
|
||||
kerning first=1047 second=1059 amount=-1
|
||||
kerning first=1047 second=1060 amount=-1
|
||||
kerning first=1047 second=1063 amount=-1
|
||||
kerning first=1047 second=1071 amount=-1
|
||||
kerning first=1050 second=1047 amount=-1
|
||||
kerning first=1050 second=1054 amount=-1
|
||||
kerning first=1050 second=1057 amount=-1
|
||||
kerning first=1050 second=1059 amount=1
|
||||
kerning first=1050 second=1060 amount=-2
|
||||
kerning first=1051 second=1060 amount=-1
|
||||
kerning first=1051 second=1073 amount=1
|
||||
kerning first=1051 second=1091 amount=1
|
||||
kerning first=1052 second=1060 amount=-1
|
||||
kerning first=1052 second=1063 amount=-1
|
||||
kerning first=1052 second=1072 amount=1
|
||||
kerning first=1052 second=1077 amount=1
|
||||
kerning first=1052 second=1086 amount=1
|
||||
kerning first=1052 second=1089 amount=1
|
||||
kerning first=1052 second=1091 amount=1
|
||||
kerning first=1052 second=1095 amount=-1
|
||||
kerning first=1052 second=1101 amount=1
|
||||
kerning first=1054 second=1040 amount=-1
|
||||
kerning first=1054 second=1044 amount=-1
|
||||
kerning first=1054 second=1046 amount=-1
|
||||
kerning first=1054 second=1051 amount=-1
|
||||
kerning first=1054 second=1059 amount=-1
|
||||
3
samples/bin/library/arial_bm.png
Normal file
3
samples/bin/library/arial_bm.png
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cdd1e2d175c5109ec5840ea37093e7f745fbf618b709ee334b7459ef1567960a
|
||||
size 61729
|
||||
720
samples/bin/library/arial_sdf.fnt
Normal file
720
samples/bin/library/arial_sdf.fnt
Normal file
@@ -0,0 +1,720 @@
|
||||
info face="Arial" size=50 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=0,0
|
||||
common lineHeight=51 base=41 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0
|
||||
page id=0 file="arial_sdf.png"
|
||||
chars count=161
|
||||
char id=32 x=0 y=0 width=0 height=0 xoffset=0 yoffset=41 xadvance=12 page=0 chnl=8
|
||||
char id=33 x=225 y=312 width=16 height=43 xoffset=-2 yoffset=3 xadvance=12 page=0 chnl=8
|
||||
char id=34 x=131 y=423 width=22 height=23 xoffset=-3 yoffset=3 xadvance=16 page=0 chnl=8
|
||||
char id=35 x=156 y=96 width=35 height=44 xoffset=-5 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=36 x=422 y=0 width=32 height=50 xoffset=-4 yoffset=1 xadvance=25 page=0 chnl=8
|
||||
char id=37 x=386 y=50 width=46 height=45 xoffset=-3 yoffset=3 xadvance=40 page=0 chnl=8
|
||||
char id=38 x=349 y=95 width=38 height=44 xoffset=-4 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=39 x=153 y=423 width=16 height=23 xoffset=-4 yoffset=3 xadvance=9 page=0 chnl=8
|
||||
char id=40 x=120 y=0 width=22 height=53 xoffset=-3 yoffset=3 xadvance=15 page=0 chnl=8
|
||||
char id=41 x=98 y=0 width=22 height=53 xoffset=-3 yoffset=3 xadvance=15 page=0 chnl=8
|
||||
char id=42 x=408 y=422 width=25 height=25 xoffset=-4 yoffset=3 xadvance=17 page=0 chnl=8
|
||||
char id=43 x=347 y=422 width=32 height=32 xoffset=-3 yoffset=9 xadvance=26 page=0 chnl=8
|
||||
char id=44 x=169 y=423 width=16 height=22 xoffset=-2 yoffset=31 xadvance=12 page=0 chnl=8
|
||||
char id=45 x=239 y=423 width=23 height=15 xoffset=-4 yoffset=22 xadvance=15 page=0 chnl=8
|
||||
char id=46 x=262 y=423 width=15 height=15 xoffset=-1 yoffset=31 xadvance=12 page=0 chnl=8
|
||||
char id=47 x=156 y=140 width=23 height=44 xoffset=-5 yoffset=3 xadvance=12 page=0 chnl=8
|
||||
char id=48 x=96 y=97 width=32 height=44 xoffset=-4 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=49 x=179 y=312 width=23 height=43 xoffset=-1 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=50 x=0 y=270 width=32 height=43 xoffset=-4 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=51 x=64 y=97 width=32 height=44 xoffset=-4 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=52 x=278 y=269 width=33 height=43 xoffset=-5 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=53 x=311 y=269 width=33 height=43 xoffset=-4 yoffset=4 xadvance=25 page=0 chnl=8
|
||||
char id=54 x=32 y=97 width=32 height=44 xoffset=-4 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=55 x=286 y=312 width=31 height=42 xoffset=-3 yoffset=4 xadvance=25 page=0 chnl=8
|
||||
char id=56 x=0 y=97 width=32 height=44 xoffset=-4 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=57 x=292 y=96 width=32 height=44 xoffset=-4 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=58 x=52 y=417 width=15 height=34 xoffset=-1 yoffset=12 xadvance=12 page=0 chnl=8
|
||||
char id=59 x=458 y=312 width=16 height=41 xoffset=-2 yoffset=12 xadvance=12 page=0 chnl=8
|
||||
char id=60 x=67 y=417 width=32 height=33 xoffset=-3 yoffset=9 xadvance=26 page=0 chnl=8
|
||||
char id=61 x=99 y=423 width=32 height=24 xoffset=-3 yoffset=13 xadvance=26 page=0 chnl=8
|
||||
char id=62 x=315 y=422 width=32 height=33 xoffset=-3 yoffset=9 xadvance=26 page=0 chnl=8
|
||||
char id=63 x=441 y=269 width=32 height=43 xoffset=-4 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=64 x=0 y=0 width=52 height=53 xoffset=-3 yoffset=3 xadvance=45 page=0 chnl=8
|
||||
char id=65 x=283 y=140 width=41 height=43 xoffset=-6 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=66 x=477 y=226 width=35 height=43 xoffset=-2 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=67 x=117 y=53 width=39 height=44 xoffset=-3 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=68 x=78 y=184 width=37 height=43 xoffset=-2 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=69 x=70 y=227 width=35 height=43 xoffset=-2 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=70 x=344 y=269 width=33 height=43 xoffset=-2 yoffset=3 xadvance=27 page=0 chnl=8
|
||||
char id=71 x=267 y=52 width=41 height=44 xoffset=-3 yoffset=3 xadvance=35 page=0 chnl=8
|
||||
char id=72 x=441 y=226 width=36 height=43 xoffset=-2 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=73 x=271 y=312 width=15 height=43 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=8
|
||||
char id=74 x=128 y=97 width=28 height=44 xoffset=-4 yoffset=3 xadvance=22 page=0 chnl=8
|
||||
char id=75 x=152 y=226 width=37 height=43 xoffset=-2 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=76 x=63 y=270 width=31 height=43 xoffset=-2 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=77 x=221 y=183 width=41 height=43 xoffset=-2 yoffset=3 xadvance=37 page=0 chnl=8
|
||||
char id=78 x=369 y=226 width=36 height=43 xoffset=-2 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=79 x=226 y=52 width=41 height=44 xoffset=-3 yoffset=3 xadvance=35 page=0 chnl=8
|
||||
char id=80 x=0 y=227 width=35 height=43 xoffset=-2 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=81 x=454 y=49 width=43 height=46 xoffset=-4 yoffset=3 xadvance=35 page=0 chnl=8
|
||||
char id=82 x=39 y=184 width=39 height=43 xoffset=-2 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=83 x=387 y=95 width=36 height=44 xoffset=-3 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=84 x=225 y=226 width=36 height=43 xoffset=-4 yoffset=3 xadvance=27 page=0 chnl=8
|
||||
char id=85 x=459 y=95 width=36 height=44 xoffset=-2 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=86 x=384 y=183 width=40 height=43 xoffset=-5 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=87 x=179 y=140 width=52 height=43 xoffset=-5 yoffset=3 xadvance=42 page=0 chnl=8
|
||||
char id=88 x=464 y=183 width=40 height=43 xoffset=-5 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=89 x=344 y=183 width=40 height=43 xoffset=-5 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=90 x=115 y=184 width=37 height=43 xoffset=-5 yoffset=3 xadvance=27 page=0 chnl=8
|
||||
char id=91 x=328 y=0 width=19 height=52 xoffset=-2 yoffset=3 xadvance=12 page=0 chnl=8
|
||||
char id=92 x=482 y=139 width=23 height=44 xoffset=-5 yoffset=3 xadvance=12 page=0 chnl=8
|
||||
char id=93 x=308 y=0 width=20 height=52 xoffset=-5 yoffset=3 xadvance=12 page=0 chnl=8
|
||||
char id=94 x=379 y=422 width=29 height=28 xoffset=-4 yoffset=3 xadvance=21 page=0 chnl=8
|
||||
char id=95 x=277 y=423 width=37 height=13 xoffset=-6 yoffset=42 xadvance=25 page=0 chnl=8
|
||||
char id=96 x=219 y=423 width=20 height=17 xoffset=-4 yoffset=3 xadvance=15 page=0 chnl=8
|
||||
char id=97 x=33 y=348 width=32 height=35 xoffset=-4 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=98 x=388 y=139 width=32 height=44 xoffset=-3 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=99 x=380 y=353 width=31 height=35 xoffset=-4 yoffset=12 xadvance=22 page=0 chnl=8
|
||||
char id=100 x=420 y=139 width=31 height=44 xoffset=-4 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=101 x=474 y=347 width=33 height=35 xoffset=-4 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=102 x=155 y=312 width=24 height=43 xoffset=-5 yoffset=3 xadvance=12 page=0 chnl=8
|
||||
char id=103 x=451 y=139 width=31 height=44 xoffset=-4 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=104 x=125 y=312 width=30 height=43 xoffset=-3 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
char id=105 x=256 y=312 width=15 height=43 xoffset=-3 yoffset=3 xadvance=10 page=0 chnl=8
|
||||
char id=106 x=142 y=0 width=20 height=53 xoffset=-8 yoffset=3 xadvance=10 page=0 chnl=8
|
||||
char id=107 x=94 y=270 width=31 height=43 xoffset=-3 yoffset=3 xadvance=22 page=0 chnl=8
|
||||
char id=108 x=241 y=312 width=15 height=43 xoffset=-3 yoffset=3 xadvance=10 page=0 chnl=8
|
||||
char id=109 x=125 y=355 width=43 height=34 xoffset=-3 yoffset=12 xadvance=37 page=0 chnl=8
|
||||
char id=110 x=475 y=416 width=30 height=34 xoffset=-3 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=111 x=40 y=313 width=33 height=35 xoffset=-4 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=112 x=409 y=269 width=32 height=43 xoffset=-3 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=113 x=32 y=270 width=31 height=43 xoffset=-4 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=114 x=28 y=417 width=24 height=34 xoffset=-3 yoffset=12 xadvance=15 page=0 chnl=8
|
||||
char id=115 x=442 y=353 width=30 height=35 xoffset=-4 yoffset=12 xadvance=22 page=0 chnl=8
|
||||
char id=116 x=202 y=312 width=23 height=43 xoffset=-5 yoffset=4 xadvance=12 page=0 chnl=8
|
||||
char id=117 x=286 y=354 width=30 height=35 xoffset=-3 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=118 x=413 y=388 width=32 height=34 xoffset=-5 yoffset=12 xadvance=22 page=0 chnl=8
|
||||
char id=119 x=168 y=355 width=42 height=34 xoffset=-5 yoffset=12 xadvance=32 page=0 chnl=8
|
||||
char id=120 x=316 y=388 width=33 height=34 xoffset=-5 yoffset=12 xadvance=22 page=0 chnl=8
|
||||
char id=121 x=324 y=139 width=32 height=44 xoffset=-5 yoffset=12 xadvance=22 page=0 chnl=8
|
||||
char id=122 x=349 y=388 width=32 height=34 xoffset=-5 yoffset=12 xadvance=22 page=0 chnl=8
|
||||
char id=123 x=52 y=0 width=23 height=53 xoffset=-4 yoffset=3 xadvance=15 page=0 chnl=8
|
||||
char id=124 x=162 y=0 width=14 height=53 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=8
|
||||
char id=125 x=75 y=0 width=23 height=53 xoffset=-4 yoffset=3 xadvance=15 page=0 chnl=8
|
||||
char id=126 x=185 y=423 width=34 height=18 xoffset=-4 yoffset=16 xadvance=26 page=0 chnl=8
|
||||
char id=1025 x=454 y=0 width=35 height=49 xoffset=-2 yoffset=-3 xadvance=30 page=0 chnl=8
|
||||
char id=1040 x=262 y=183 width=41 height=43 xoffset=-6 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=1041 x=140 y=269 width=35 height=43 xoffset=-2 yoffset=3 xadvance=29 page=0 chnl=8
|
||||
char id=1042 x=175 y=269 width=35 height=43 xoffset=-2 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=1043 x=473 y=269 width=32 height=43 xoffset=-2 yoffset=3 xadvance=24 page=0 chnl=8
|
||||
char id=1044 x=347 y=0 width=39 height=51 xoffset=-5 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=1045 x=210 y=269 width=35 height=43 xoffset=-2 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=1046 x=231 y=140 width=52 height=43 xoffset=-5 yoffset=3 xadvance=41 page=0 chnl=8
|
||||
char id=1047 x=191 y=96 width=35 height=44 xoffset=-4 yoffset=3 xadvance=27 page=0 chnl=8
|
||||
char id=1048 x=333 y=226 width=36 height=43 xoffset=-2 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=1049 x=386 y=0 width=36 height=50 xoffset=-2 yoffset=-4 xadvance=32 page=0 chnl=8
|
||||
char id=1050 x=245 y=269 width=33 height=43 xoffset=-2 yoffset=3 xadvance=26 page=0 chnl=8
|
||||
char id=1051 x=423 y=95 width=36 height=44 xoffset=-5 yoffset=3 xadvance=29 page=0 chnl=8
|
||||
char id=1052 x=303 y=183 width=41 height=43 xoffset=-2 yoffset=3 xadvance=37 page=0 chnl=8
|
||||
char id=1053 x=261 y=226 width=36 height=43 xoffset=-2 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=1054 x=308 y=52 width=41 height=44 xoffset=-3 yoffset=3 xadvance=35 page=0 chnl=8
|
||||
char id=1055 x=405 y=226 width=36 height=43 xoffset=-2 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=1056 x=105 y=227 width=35 height=43 xoffset=-2 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=1057 x=78 y=53 width=39 height=44 xoffset=-3 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=1058 x=189 y=226 width=36 height=43 xoffset=-4 yoffset=3 xadvance=27 page=0 chnl=8
|
||||
char id=1059 x=39 y=53 width=39 height=44 xoffset=-5 yoffset=3 xadvance=28 page=0 chnl=8
|
||||
char id=1060 x=179 y=183 width=42 height=43 xoffset=-4 yoffset=3 xadvance=34 page=0 chnl=8
|
||||
char id=1061 x=424 y=183 width=40 height=43 xoffset=-5 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=1062 x=269 y=0 width=39 height=52 xoffset=-2 yoffset=3 xadvance=33 page=0 chnl=8
|
||||
char id=1063 x=297 y=226 width=36 height=43 xoffset=-4 yoffset=3 xadvance=30 page=0 chnl=8
|
||||
char id=1064 x=0 y=141 width=45 height=43 xoffset=-2 yoffset=3 xadvance=41 page=0 chnl=8
|
||||
char id=1065 x=176 y=0 width=48 height=52 xoffset=-2 yoffset=3 xadvance=42 page=0 chnl=8
|
||||
char id=1066 x=45 y=141 width=44 height=43 xoffset=-5 yoffset=3 xadvance=35 page=0 chnl=8
|
||||
char id=1067 x=89 y=141 width=43 height=43 xoffset=-2 yoffset=3 xadvance=40 page=0 chnl=8
|
||||
char id=1068 x=35 y=227 width=35 height=43 xoffset=-2 yoffset=3 xadvance=29 page=0 chnl=8
|
||||
char id=1069 x=0 y=53 width=39 height=44 xoffset=-4 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=1070 x=176 y=52 width=50 height=44 xoffset=-2 yoffset=3 xadvance=45 page=0 chnl=8
|
||||
char id=1071 x=0 y=184 width=39 height=43 xoffset=-5 yoffset=3 xadvance=32 page=0 chnl=8
|
||||
char id=1072 x=348 y=353 width=32 height=35 xoffset=-4 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=1073 x=259 y=96 width=33 height=44 xoffset=-4 yoffset=3 xadvance=26 page=0 chnl=8
|
||||
char id=1074 x=108 y=389 width=31 height=34 xoffset=-3 yoffset=12 xadvance=24 page=0 chnl=8
|
||||
char id=1075 x=290 y=389 width=25 height=34 xoffset=-3 yoffset=12 xadvance=16 page=0 chnl=8
|
||||
char id=1076 x=391 y=312 width=35 height=41 xoffset=-5 yoffset=12 xadvance=26 page=0 chnl=8
|
||||
char id=1077 x=0 y=348 width=33 height=35 xoffset=-4 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=1078 x=210 y=355 width=42 height=34 xoffset=-6 yoffset=12 xadvance=30 page=0 chnl=8
|
||||
char id=1079 x=97 y=348 width=28 height=35 xoffset=-4 yoffset=12 xadvance=21 page=0 chnl=8
|
||||
char id=1080 x=139 y=389 width=31 height=34 xoffset=-3 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=1081 x=317 y=312 width=31 height=42 xoffset=-3 yoffset=4 xadvance=25 page=0 chnl=8
|
||||
char id=1082 x=0 y=417 width=28 height=34 xoffset=-3 yoffset=12 xadvance=20 page=0 chnl=8
|
||||
char id=1083 x=474 y=312 width=34 height=35 xoffset=-5 yoffset=12 xadvance=26 page=0 chnl=8
|
||||
char id=1084 x=73 y=383 width=35 height=34 xoffset=-2 yoffset=12 xadvance=31 page=0 chnl=8
|
||||
char id=1085 x=260 y=389 width=30 height=34 xoffset=-3 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=1086 x=73 y=313 width=33 height=35 xoffset=-4 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=1087 x=445 y=416 width=30 height=34 xoffset=-3 yoffset=12 xadvance=24 page=0 chnl=8
|
||||
char id=1088 x=377 y=269 width=32 height=43 xoffset=-3 yoffset=12 xadvance=25 page=0 chnl=8
|
||||
char id=1089 x=411 y=353 width=31 height=35 xoffset=-4 yoffset=12 xadvance=22 page=0 chnl=8
|
||||
char id=1090 x=200 y=389 width=30 height=34 xoffset=-5 yoffset=12 xadvance=20 page=0 chnl=8
|
||||
char id=1091 x=356 y=139 width=32 height=44 xoffset=-5 yoffset=12 xadvance=22 page=0 chnl=8
|
||||
char id=1092 x=224 y=0 width=45 height=52 xoffset=-4 yoffset=3 xadvance=37 page=0 chnl=8
|
||||
char id=1093 x=252 y=355 width=33 height=34 xoffset=-5 yoffset=12 xadvance=22 page=0 chnl=8
|
||||
char id=1094 x=426 y=312 width=32 height=41 xoffset=-2 yoffset=12 xadvance=26 page=0 chnl=8
|
||||
char id=1095 x=170 y=389 width=30 height=34 xoffset=-4 yoffset=12 xadvance=23 page=0 chnl=8
|
||||
char id=1096 x=472 y=382 width=40 height=34 xoffset=-2 yoffset=12 xadvance=36 page=0 chnl=8
|
||||
char id=1097 x=348 y=312 width=43 height=41 xoffset=-2 yoffset=12 xadvance=37 page=0 chnl=8
|
||||
char id=1098 x=0 y=383 width=37 height=34 xoffset=-5 yoffset=12 xadvance=28 page=0 chnl=8
|
||||
char id=1099 x=37 y=383 width=36 height=34 xoffset=-2 yoffset=12 xadvance=32 page=0 chnl=8
|
||||
char id=1100 x=230 y=389 width=30 height=34 xoffset=-3 yoffset=12 xadvance=23 page=0 chnl=8
|
||||
char id=1101 x=65 y=348 width=32 height=35 xoffset=-5 yoffset=12 xadvance=23 page=0 chnl=8
|
||||
char id=1102 x=0 y=313 width=40 height=35 xoffset=-3 yoffset=12 xadvance=34 page=0 chnl=8
|
||||
char id=1103 x=381 y=388 width=32 height=34 xoffset=-5 yoffset=12 xadvance=24 page=0 chnl=8
|
||||
char id=1105 x=226 y=96 width=33 height=44 xoffset=-4 yoffset=3 xadvance=25 page=0 chnl=8
|
||||
kernings count=554
|
||||
kerning first=32 second=65 amount=-5
|
||||
kerning first=32 second=84 amount=-2
|
||||
kerning first=32 second=89 amount=-2
|
||||
kerning first=49 second=49 amount=-7
|
||||
kerning first=65 second=32 amount=-5
|
||||
kerning first=65 second=84 amount=-7
|
||||
kerning first=65 second=86 amount=-7
|
||||
kerning first=65 second=87 amount=-3
|
||||
kerning first=65 second=89 amount=-7
|
||||
kerning first=65 second=118 amount=-2
|
||||
kerning first=65 second=119 amount=-2
|
||||
kerning first=65 second=121 amount=-2
|
||||
kerning first=70 second=44 amount=-10
|
||||
kerning first=70 second=46 amount=-10
|
||||
kerning first=70 second=65 amount=-5
|
||||
kerning first=76 second=32 amount=-3
|
||||
kerning first=76 second=84 amount=-7
|
||||
kerning first=76 second=86 amount=-7
|
||||
kerning first=76 second=87 amount=-7
|
||||
kerning first=76 second=89 amount=-7
|
||||
kerning first=76 second=121 amount=-3
|
||||
kerning first=80 second=32 amount=-2
|
||||
kerning first=80 second=44 amount=-12
|
||||
kerning first=80 second=46 amount=-12
|
||||
kerning first=80 second=65 amount=-7
|
||||
kerning first=82 second=84 amount=-2
|
||||
kerning first=82 second=86 amount=-2
|
||||
kerning first=82 second=87 amount=-2
|
||||
kerning first=82 second=89 amount=-2
|
||||
kerning first=84 second=32 amount=-2
|
||||
kerning first=84 second=44 amount=-10
|
||||
kerning first=84 second=45 amount=-5
|
||||
kerning first=84 second=46 amount=-10
|
||||
kerning first=84 second=58 amount=-10
|
||||
kerning first=84 second=59 amount=-10
|
||||
kerning first=84 second=65 amount=-7
|
||||
kerning first=84 second=79 amount=-2
|
||||
kerning first=84 second=97 amount=-10
|
||||
kerning first=84 second=99 amount=-10
|
||||
kerning first=84 second=101 amount=-10
|
||||
kerning first=84 second=105 amount=-3
|
||||
kerning first=84 second=111 amount=-10
|
||||
kerning first=84 second=114 amount=-3
|
||||
kerning first=84 second=115 amount=-10
|
||||
kerning first=84 second=117 amount=-3
|
||||
kerning first=84 second=119 amount=-5
|
||||
kerning first=84 second=121 amount=-5
|
||||
kerning first=86 second=44 amount=-8
|
||||
kerning first=86 second=45 amount=-5
|
||||
kerning first=86 second=46 amount=-8
|
||||
kerning first=86 second=58 amount=-3
|
||||
kerning first=86 second=59 amount=-3
|
||||
kerning first=86 second=65 amount=-7
|
||||
kerning first=86 second=97 amount=-7
|
||||
kerning first=86 second=101 amount=-5
|
||||
kerning first=86 second=105 amount=-2
|
||||
kerning first=86 second=111 amount=-5
|
||||
kerning first=86 second=114 amount=-3
|
||||
kerning first=86 second=117 amount=-3
|
||||
kerning first=86 second=121 amount=-3
|
||||
kerning first=87 second=44 amount=-5
|
||||
kerning first=87 second=45 amount=-2
|
||||
kerning first=87 second=46 amount=-5
|
||||
kerning first=87 second=58 amount=-2
|
||||
kerning first=87 second=59 amount=-2
|
||||
kerning first=87 second=65 amount=-3
|
||||
kerning first=87 second=97 amount=-3
|
||||
kerning first=87 second=101 amount=-2
|
||||
kerning first=87 second=111 amount=-2
|
||||
kerning first=87 second=114 amount=-2
|
||||
kerning first=87 second=117 amount=-2
|
||||
kerning first=87 second=121 amount=-1
|
||||
kerning first=89 second=32 amount=-2
|
||||
kerning first=89 second=44 amount=-12
|
||||
kerning first=89 second=45 amount=-8
|
||||
kerning first=89 second=46 amount=-12
|
||||
kerning first=89 second=58 amount=-5
|
||||
kerning first=89 second=59 amount=-6
|
||||
kerning first=89 second=65 amount=-7
|
||||
kerning first=89 second=97 amount=-7
|
||||
kerning first=89 second=101 amount=-8
|
||||
kerning first=89 second=105 amount=-3
|
||||
kerning first=89 second=111 amount=-8
|
||||
kerning first=89 second=112 amount=-7
|
||||
kerning first=89 second=113 amount=-8
|
||||
kerning first=89 second=117 amount=-5
|
||||
kerning first=89 second=118 amount=-5
|
||||
kerning first=102 second=102 amount=-2
|
||||
kerning first=114 second=44 amount=-5
|
||||
kerning first=114 second=46 amount=-5
|
||||
kerning first=118 second=44 amount=-7
|
||||
kerning first=118 second=46 amount=-7
|
||||
kerning first=119 second=44 amount=-5
|
||||
kerning first=119 second=46 amount=-5
|
||||
kerning first=121 second=44 amount=-7
|
||||
kerning first=121 second=46 amount=-7
|
||||
kerning first=1040 second=1044 amount=3
|
||||
kerning first=1040 second=1047 amount=-1
|
||||
kerning first=1040 second=1051 amount=2
|
||||
kerning first=1040 second=1054 amount=-2
|
||||
kerning first=1040 second=1055 amount=-1
|
||||
kerning first=1040 second=1057 amount=-2
|
||||
kerning first=1040 second=1058 amount=-7
|
||||
kerning first=1040 second=1059 amount=-4
|
||||
kerning first=1040 second=1060 amount=-3
|
||||
kerning first=1040 second=1063 amount=-7
|
||||
kerning first=1040 second=1069 amount=-2
|
||||
kerning first=1040 second=1072 amount=1
|
||||
kerning first=1040 second=1090 amount=-2
|
||||
kerning first=1040 second=1091 amount=-1
|
||||
kerning first=1040 second=1092 amount=1
|
||||
kerning first=1040 second=1101 amount=2
|
||||
kerning first=1041 second=1040 amount=-2
|
||||
kerning first=1041 second=1047 amount=-1
|
||||
kerning first=1041 second=1054 amount=-1
|
||||
kerning first=1041 second=1057 amount=-1
|
||||
kerning first=1041 second=1058 amount=-4
|
||||
kerning first=1041 second=1059 amount=-2
|
||||
kerning first=1041 second=1060 amount=-1
|
||||
kerning first=1041 second=1061 amount=-2
|
||||
kerning first=1041 second=1063 amount=-4
|
||||
kerning first=1041 second=1066 amount=-3
|
||||
kerning first=1041 second=1069 amount=-1
|
||||
kerning first=1041 second=1071 amount=-1
|
||||
kerning first=1041 second=1083 amount=-1
|
||||
kerning first=1041 second=1091 amount=-2
|
||||
kerning first=1042 second=1040 amount=-3
|
||||
kerning first=1042 second=1044 amount=-2
|
||||
kerning first=1042 second=1046 amount=-2
|
||||
kerning first=1042 second=1047 amount=-3
|
||||
kerning first=1042 second=1051 amount=-1
|
||||
kerning first=1042 second=1054 amount=-3
|
||||
kerning first=1042 second=1057 amount=-3
|
||||
kerning first=1042 second=1058 amount=-6
|
||||
kerning first=1042 second=1059 amount=-3
|
||||
kerning first=1042 second=1060 amount=-3
|
||||
kerning first=1042 second=1061 amount=-4
|
||||
kerning first=1042 second=1063 amount=-4
|
||||
kerning first=1042 second=1066 amount=-5
|
||||
kerning first=1042 second=1071 amount=-3
|
||||
kerning first=1042 second=1076 amount=-1
|
||||
kerning first=1042 second=1084 amount=-1
|
||||
kerning first=1042 second=1090 amount=-3
|
||||
kerning first=1042 second=1091 amount=-1
|
||||
kerning first=1042 second=1093 amount=-1
|
||||
kerning first=1042 second=1095 amount=-3
|
||||
kerning first=1042 second=1103 amount=-1
|
||||
kerning first=1043 second=44 amount=-11
|
||||
kerning first=1043 second=46 amount=-11
|
||||
kerning first=1043 second=1040 amount=-6
|
||||
kerning first=1043 second=1044 amount=-6
|
||||
kerning first=1043 second=1047 amount=-2
|
||||
kerning first=1043 second=1051 amount=-5
|
||||
kerning first=1043 second=1052 amount=-2
|
||||
kerning first=1043 second=1054 amount=-5
|
||||
kerning first=1043 second=1057 amount=-4
|
||||
kerning first=1043 second=1071 amount=-3
|
||||
kerning first=1043 second=1072 amount=-5
|
||||
kerning first=1043 second=1074 amount=-5
|
||||
kerning first=1043 second=1076 amount=-6
|
||||
kerning first=1043 second=1077 amount=-6
|
||||
kerning first=1043 second=1080 amount=-5
|
||||
kerning first=1043 second=1083 amount=-5
|
||||
kerning first=1043 second=1084 amount=-5
|
||||
kerning first=1043 second=1085 amount=-5
|
||||
kerning first=1043 second=1086 amount=-6
|
||||
kerning first=1043 second=1088 amount=-5
|
||||
kerning first=1043 second=1091 amount=-6
|
||||
kerning first=1043 second=1099 amount=-5
|
||||
kerning first=1043 second=1100 amount=-5
|
||||
kerning first=1043 second=1102 amount=-5
|
||||
kerning first=1043 second=1103 amount=-6
|
||||
kerning first=1044 second=1059 amount=1
|
||||
kerning first=1044 second=1060 amount=-2
|
||||
kerning first=1044 second=1063 amount=-3
|
||||
kerning first=1044 second=1079 amount=3
|
||||
kerning first=1044 second=1086 amount=1
|
||||
kerning first=1044 second=1091 amount=2
|
||||
kerning first=1045 second=1047 amount=-2
|
||||
kerning first=1045 second=1089 amount=-1
|
||||
kerning first=1046 second=1047 amount=-1
|
||||
kerning first=1046 second=1054 amount=-2
|
||||
kerning first=1046 second=1057 amount=-1
|
||||
kerning first=1046 second=1058 amount=1
|
||||
kerning first=1046 second=1059 amount=2
|
||||
kerning first=1046 second=1066 amount=2
|
||||
kerning first=1046 second=1072 amount=1
|
||||
kerning first=1046 second=1077 amount=-1
|
||||
kerning first=1046 second=1086 amount=-1
|
||||
kerning first=1046 second=1091 amount=-1
|
||||
kerning first=1047 second=1051 amount=-1
|
||||
kerning first=1047 second=1054 amount=-1
|
||||
kerning first=1047 second=1057 amount=-1
|
||||
kerning first=1047 second=1058 amount=-2
|
||||
kerning first=1047 second=1059 amount=-1
|
||||
kerning first=1047 second=1060 amount=-1
|
||||
kerning first=1047 second=1063 amount=-2
|
||||
kerning first=1047 second=1071 amount=-1
|
||||
kerning first=1050 second=1047 amount=-1
|
||||
kerning first=1050 second=1054 amount=-1
|
||||
kerning first=1050 second=1057 amount=-1
|
||||
kerning first=1050 second=1059 amount=1
|
||||
kerning first=1050 second=1060 amount=-3
|
||||
kerning first=1051 second=1060 amount=-1
|
||||
kerning first=1051 second=1073 amount=1
|
||||
kerning first=1051 second=1091 amount=1
|
||||
kerning first=1052 second=1060 amount=-1
|
||||
kerning first=1052 second=1063 amount=-1
|
||||
kerning first=1052 second=1072 amount=1
|
||||
kerning first=1052 second=1077 amount=1
|
||||
kerning first=1052 second=1086 amount=1
|
||||
kerning first=1052 second=1089 amount=1
|
||||
kerning first=1052 second=1091 amount=1
|
||||
kerning first=1052 second=1095 amount=-1
|
||||
kerning first=1052 second=1101 amount=1
|
||||
kerning first=1054 second=1040 amount=-2
|
||||
kerning first=1054 second=1044 amount=-2
|
||||
kerning first=1054 second=1046 amount=-2
|
||||
kerning first=1054 second=1051 amount=-1
|
||||
kerning first=1054 second=1059 amount=-2
|
||||
kerning first=1054 second=1061 amount=-4
|
||||
kerning first=1054 second=1063 amount=-2
|
||||
kerning first=1054 second=1071 amount=-2
|
||||
kerning first=1054 second=1076 amount=-2
|
||||
kerning first=1054 second=1083 amount=-1
|
||||
kerning first=1054 second=1093 amount=-1
|
||||
kerning first=1056 second=44 amount=-17
|
||||
kerning first=1056 second=46 amount=-17
|
||||
kerning first=1056 second=58 amount=-2
|
||||
kerning first=1056 second=59 amount=-2
|
||||
kerning first=1056 second=1040 amount=-6
|
||||
kerning first=1056 second=1044 amount=-6
|
||||
kerning first=1056 second=1046 amount=-1
|
||||
kerning first=1056 second=1047 amount=-2
|
||||
kerning first=1056 second=1051 amount=-5
|
||||
kerning first=1056 second=1052 amount=-1
|
||||
kerning first=1056 second=1054 amount=-2
|
||||
kerning first=1056 second=1057 amount=-1
|
||||
kerning first=1056 second=1058 amount=-4
|
||||
kerning first=1056 second=1059 amount=-2
|
||||
kerning first=1056 second=1060 amount=-1
|
||||
kerning first=1056 second=1061 amount=-4
|
||||
kerning first=1056 second=1071 amount=-2
|
||||
kerning first=1056 second=1072 amount=-3
|
||||
kerning first=1056 second=1076 amount=-7
|
||||
kerning first=1056 second=1077 amount=-4
|
||||
kerning first=1056 second=1086 amount=-4
|
||||
kerning first=1056 second=1101 amount=-2
|
||||
kerning first=1056 second=1103 amount=-3
|
||||
kerning first=1057 second=1040 amount=-2
|
||||
kerning first=1057 second=1044 amount=-2
|
||||
kerning first=1057 second=1047 amount=-1
|
||||
kerning first=1057 second=1051 amount=-3
|
||||
kerning first=1057 second=1052 amount=-1
|
||||
kerning first=1057 second=1054 amount=-2
|
||||
kerning first=1057 second=1058 amount=-3
|
||||
kerning first=1057 second=1059 amount=-3
|
||||
kerning first=1057 second=1061 amount=-5
|
||||
kerning first=1057 second=1063 amount=-3
|
||||
kerning first=1057 second=1066 amount=-3
|
||||
kerning first=1057 second=1069 amount=-1
|
||||
kerning first=1057 second=1072 amount=1
|
||||
kerning first=1057 second=1078 amount=2
|
||||
kerning first=1057 second=1095 amount=-1
|
||||
kerning first=1058 second=44 amount=-10
|
||||
kerning first=1058 second=46 amount=-10
|
||||
kerning first=1058 second=1040 amount=-3
|
||||
kerning first=1058 second=1044 amount=-3
|
||||
kerning first=1058 second=1046 amount=1
|
||||
kerning first=1058 second=1047 amount=-1
|
||||
kerning first=1058 second=1051 amount=-2
|
||||
kerning first=1058 second=1054 amount=-4
|
||||
kerning first=1058 second=1060 amount=-3
|
||||
kerning first=1058 second=1071 amount=-2
|
||||
kerning first=1058 second=1072 amount=-4
|
||||
kerning first=1058 second=1074 amount=-4
|
||||
kerning first=1058 second=1077 amount=-5
|
||||
kerning first=1058 second=1080 amount=-4
|
||||
kerning first=1058 second=1082 amount=-4
|
||||
kerning first=1058 second=1083 amount=-4
|
||||
kerning first=1058 second=1084 amount=-4
|
||||
kerning first=1058 second=1086 amount=-7
|
||||
kerning first=1058 second=1087 amount=-4
|
||||
kerning first=1058 second=1088 amount=-5
|
||||
kerning first=1058 second=1089 amount=-5
|
||||
kerning first=1058 second=1091 amount=-5
|
||||
kerning first=1058 second=1093 amount=-4
|
||||
kerning first=1058 second=1097 amount=-4
|
||||
kerning first=1058 second=1099 amount=-4
|
||||
kerning first=1058 second=1100 amount=-4
|
||||
kerning first=1058 second=1102 amount=-4
|
||||
kerning first=1058 second=1103 amount=-5
|
||||
kerning first=1059 second=44 amount=-12
|
||||
kerning first=1059 second=46 amount=-12
|
||||
kerning first=1059 second=58 amount=-2
|
||||
kerning first=1059 second=59 amount=-2
|
||||
kerning first=1059 second=1040 amount=-6
|
||||
kerning first=1059 second=1044 amount=-4
|
||||
kerning first=1059 second=1047 amount=-2
|
||||
kerning first=1059 second=1051 amount=-3
|
||||
kerning first=1059 second=1054 amount=-3
|
||||
kerning first=1059 second=1060 amount=-3
|
||||
kerning first=1059 second=1069 amount=-2
|
||||
kerning first=1059 second=1071 amount=-2
|
||||
kerning first=1059 second=1073 amount=-2
|
||||
kerning first=1059 second=1074 amount=-5
|
||||
kerning first=1059 second=1075 amount=-4
|
||||
kerning first=1059 second=1076 amount=-7
|
||||
kerning first=1059 second=1077 amount=-6
|
||||
kerning first=1059 second=1078 amount=-3
|
||||
kerning first=1059 second=1079 amount=-5
|
||||
kerning first=1059 second=1080 amount=-4
|
||||
kerning first=1059 second=1081 amount=-3
|
||||
kerning first=1059 second=1082 amount=-4
|
||||
kerning first=1059 second=1083 amount=-6
|
||||
kerning first=1059 second=1084 amount=-4
|
||||
kerning first=1059 second=1085 amount=-4
|
||||
kerning first=1059 second=1086 amount=-6
|
||||
kerning first=1059 second=1087 amount=-4
|
||||
kerning first=1059 second=1088 amount=-4
|
||||
kerning first=1059 second=1089 amount=-6
|
||||
kerning first=1059 second=1093 amount=-4
|
||||
kerning first=1059 second=1094 amount=-4
|
||||
kerning first=1059 second=1096 amount=-4
|
||||
kerning first=1059 second=1097 amount=-4
|
||||
kerning first=1059 second=1102 amount=-4
|
||||
kerning first=1059 second=1103 amount=-6
|
||||
kerning first=1060 second=1040 amount=-2
|
||||
kerning first=1060 second=1044 amount=-3
|
||||
kerning first=1060 second=1051 amount=-3
|
||||
kerning first=1060 second=1058 amount=-5
|
||||
kerning first=1060 second=1059 amount=-4
|
||||
kerning first=1060 second=1063 amount=-2
|
||||
kerning first=1060 second=1071 amount=-3
|
||||
kerning first=1060 second=1083 amount=-3
|
||||
kerning first=1061 second=1047 amount=-2
|
||||
kerning first=1061 second=1054 amount=-3
|
||||
kerning first=1061 second=1057 amount=-3
|
||||
kerning first=1061 second=1060 amount=-3
|
||||
kerning first=1061 second=1069 amount=-3
|
||||
kerning first=1061 second=1086 amount=-1
|
||||
kerning first=1061 second=1091 amount=-2
|
||||
kerning first=1062 second=1054 amount=-2
|
||||
kerning first=1062 second=1072 amount=2
|
||||
kerning first=1065 second=1072 amount=1
|
||||
kerning first=1065 second=1091 amount=2
|
||||
kerning first=1066 second=1071 amount=-3
|
||||
kerning first=1068 second=1040 amount=-2
|
||||
kerning first=1068 second=1044 amount=-2
|
||||
kerning first=1068 second=1046 amount=-3
|
||||
kerning first=1068 second=1047 amount=-1
|
||||
kerning first=1068 second=1051 amount=-3
|
||||
kerning first=1068 second=1052 amount=-2
|
||||
kerning first=1068 second=1054 amount=-2
|
||||
kerning first=1068 second=1057 amount=-2
|
||||
kerning first=1068 second=1058 amount=-9
|
||||
kerning first=1068 second=1061 amount=-4
|
||||
kerning first=1068 second=1063 amount=-7
|
||||
kerning first=1068 second=1069 amount=-1
|
||||
kerning first=1068 second=1071 amount=-4
|
||||
kerning first=1069 second=1044 amount=-3
|
||||
kerning first=1069 second=1046 amount=-1
|
||||
kerning first=1069 second=1047 amount=-1
|
||||
kerning first=1069 second=1051 amount=-3
|
||||
kerning first=1069 second=1061 amount=-3
|
||||
kerning first=1069 second=1071 amount=-2
|
||||
kerning first=1069 second=1076 amount=-3
|
||||
kerning first=1069 second=1078 amount=1
|
||||
kerning first=1069 second=1083 amount=-3
|
||||
kerning first=1069 second=1084 amount=-1
|
||||
kerning first=1069 second=1103 amount=-1
|
||||
kerning first=1070 second=1040 amount=-3
|
||||
kerning first=1070 second=1044 amount=-4
|
||||
kerning first=1070 second=1046 amount=-2
|
||||
kerning first=1070 second=1051 amount=-4
|
||||
kerning first=1070 second=1054 amount=-1
|
||||
kerning first=1070 second=1057 amount=-1
|
||||
kerning first=1070 second=1058 amount=-5
|
||||
kerning first=1070 second=1061 amount=-4
|
||||
kerning first=1070 second=1063 amount=-3
|
||||
kerning first=1070 second=1076 amount=-4
|
||||
kerning first=1070 second=1083 amount=-4
|
||||
kerning first=1070 second=1084 amount=-1
|
||||
kerning first=1072 second=1079 amount=-1
|
||||
kerning first=1072 second=1090 amount=-2
|
||||
kerning first=1072 second=1091 amount=-1
|
||||
kerning first=1072 second=1095 amount=-2
|
||||
kerning first=1073 second=1072 amount=-2
|
||||
kerning first=1073 second=1076 amount=-4
|
||||
kerning first=1073 second=1077 amount=-1
|
||||
kerning first=1073 second=1078 amount=-1
|
||||
kerning first=1073 second=1079 amount=-2
|
||||
kerning first=1073 second=1083 amount=-4
|
||||
kerning first=1073 second=1084 amount=-2
|
||||
kerning first=1073 second=1089 amount=-1
|
||||
kerning first=1073 second=1091 amount=-2
|
||||
kerning first=1073 second=1092 amount=-1
|
||||
kerning first=1073 second=1093 amount=-3
|
||||
kerning first=1073 second=1095 amount=-3
|
||||
kerning first=1073 second=1098 amount=-3
|
||||
kerning first=1073 second=1101 amount=-1
|
||||
kerning first=1073 second=1103 amount=-2
|
||||
kerning first=1074 second=1072 amount=-1
|
||||
kerning first=1074 second=1073 amount=-1
|
||||
kerning first=1074 second=1076 amount=-1
|
||||
kerning first=1074 second=1077 amount=-1
|
||||
kerning first=1074 second=1078 amount=-1
|
||||
kerning first=1074 second=1079 amount=-1
|
||||
kerning first=1074 second=1083 amount=-2
|
||||
kerning first=1074 second=1084 amount=-1
|
||||
kerning first=1074 second=1086 amount=-1
|
||||
kerning first=1074 second=1089 amount=-1
|
||||
kerning first=1074 second=1090 amount=-2
|
||||
kerning first=1074 second=1091 amount=-2
|
||||
kerning first=1074 second=1092 amount=-1
|
||||
kerning first=1074 second=1095 amount=-4
|
||||
kerning first=1074 second=1098 amount=-3
|
||||
kerning first=1074 second=1103 amount=-1
|
||||
kerning first=1075 second=44 amount=-11
|
||||
kerning first=1075 second=46 amount=-11
|
||||
kerning first=1075 second=1072 amount=-2
|
||||
kerning first=1075 second=1076 amount=-4
|
||||
kerning first=1075 second=1077 amount=-2
|
||||
kerning first=1075 second=1079 amount=-1
|
||||
kerning first=1075 second=1083 amount=-2
|
||||
kerning first=1075 second=1086 amount=-2
|
||||
kerning first=1075 second=1089 amount=-2
|
||||
kerning first=1075 second=1103 amount=-1
|
||||
kerning first=1076 second=1098 amount=-2
|
||||
kerning first=1076 second=1101 amount=1
|
||||
kerning first=1077 second=1073 amount=-1
|
||||
kerning first=1077 second=1076 amount=-2
|
||||
kerning first=1077 second=1078 amount=-1
|
||||
kerning first=1077 second=1079 amount=-2
|
||||
kerning first=1077 second=1083 amount=-3
|
||||
kerning first=1077 second=1090 amount=-3
|
||||
kerning first=1077 second=1091 amount=-1
|
||||
kerning first=1077 second=1093 amount=-2
|
||||
kerning first=1077 second=1095 amount=-3
|
||||
kerning first=1078 second=1073 amount=1
|
||||
kerning first=1078 second=1091 amount=1
|
||||
kerning first=1078 second=1095 amount=-1
|
||||
kerning first=1078 second=1098 amount=2
|
||||
kerning first=1079 second=1073 amount=-1
|
||||
kerning first=1079 second=1076 amount=-2
|
||||
kerning first=1079 second=1077 amount=-1
|
||||
kerning first=1079 second=1079 amount=-1
|
||||
kerning first=1079 second=1083 amount=-1
|
||||
kerning first=1079 second=1086 amount=-1
|
||||
kerning first=1079 second=1089 amount=-1
|
||||
kerning first=1079 second=1091 amount=-1
|
||||
kerning first=1079 second=1092 amount=-1
|
||||
kerning first=1079 second=1095 amount=-3
|
||||
kerning first=1079 second=1098 amount=-2
|
||||
kerning first=1082 second=1072 amount=2
|
||||
kerning first=1082 second=1073 amount=2
|
||||
kerning first=1082 second=1077 amount=1
|
||||
kerning first=1082 second=1079 amount=1
|
||||
kerning first=1082 second=1083 amount=1
|
||||
kerning first=1082 second=1086 amount=1
|
||||
kerning first=1082 second=1089 amount=1
|
||||
kerning first=1082 second=1090 amount=1
|
||||
kerning first=1082 second=1091 amount=1
|
||||
kerning first=1082 second=1101 amount=1
|
||||
kerning first=1083 second=1086 amount=1
|
||||
kerning first=1083 second=1095 amount=-2
|
||||
kerning first=1084 second=1073 amount=-1
|
||||
kerning first=1084 second=1079 amount=-1
|
||||
kerning first=1084 second=1091 amount=1
|
||||
kerning first=1086 second=1076 amount=-2
|
||||
kerning first=1086 second=1078 amount=-1
|
||||
kerning first=1086 second=1079 amount=-1
|
||||
kerning first=1086 second=1083 amount=-2
|
||||
kerning first=1086 second=1090 amount=-2
|
||||
kerning first=1086 second=1091 amount=-1
|
||||
kerning first=1086 second=1093 amount=-1
|
||||
kerning first=1086 second=1095 amount=-2
|
||||
kerning first=1088 second=1076 amount=-2
|
||||
kerning first=1088 second=1079 amount=-1
|
||||
kerning first=1088 second=1083 amount=-3
|
||||
kerning first=1088 second=1090 amount=-2
|
||||
kerning first=1088 second=1091 amount=-1
|
||||
kerning first=1088 second=1093 amount=-1
|
||||
kerning first=1088 second=1095 amount=-2
|
||||
kerning first=1088 second=1103 amount=-1
|
||||
kerning first=1089 second=1078 amount=1
|
||||
kerning first=1089 second=1086 amount=1
|
||||
kerning first=1089 second=1095 amount=-1
|
||||
kerning first=1089 second=1101 amount=1
|
||||
kerning first=1090 second=44 amount=-10
|
||||
kerning first=1090 second=46 amount=-10
|
||||
kerning first=1090 second=1072 amount=-1
|
||||
kerning first=1090 second=1076 amount=-3
|
||||
kerning first=1090 second=1077 amount=-1
|
||||
kerning first=1090 second=1078 amount=3
|
||||
kerning first=1090 second=1083 amount=-2
|
||||
kerning first=1090 second=1086 amount=-1
|
||||
kerning first=1090 second=1089 amount=-1
|
||||
kerning first=1090 second=1091 amount=1
|
||||
kerning first=1091 second=44 amount=-9
|
||||
kerning first=1091 second=46 amount=-9
|
||||
kerning first=1091 second=1072 amount=-1
|
||||
kerning first=1091 second=1073 amount=1
|
||||
kerning first=1091 second=1076 amount=-3
|
||||
kerning first=1091 second=1077 amount=-1
|
||||
kerning first=1091 second=1078 amount=1
|
||||
kerning first=1091 second=1083 amount=-2
|
||||
kerning first=1091 second=1084 amount=-1
|
||||
kerning first=1091 second=1086 amount=-1
|
||||
kerning first=1091 second=1088 amount=-1
|
||||
kerning first=1091 second=1089 amount=-1
|
||||
kerning first=1091 second=1092 amount=-1
|
||||
kerning first=1091 second=1101 amount=-1
|
||||
kerning first=1091 second=1103 amount=-1
|
||||
kerning first=1092 second=1073 amount=-1
|
||||
kerning first=1092 second=1076 amount=-2
|
||||
kerning first=1092 second=1083 amount=-2
|
||||
kerning first=1092 second=1090 amount=-2
|
||||
kerning first=1092 second=1091 amount=-1
|
||||
kerning first=1092 second=1095 amount=-2
|
||||
kerning first=1092 second=1103 amount=-1
|
||||
kerning first=1093 second=1072 amount=-1
|
||||
kerning first=1093 second=1073 amount=-1
|
||||
kerning first=1093 second=1077 amount=-1
|
||||
kerning first=1093 second=1079 amount=-1
|
||||
kerning first=1093 second=1086 amount=-1
|
||||
kerning first=1093 second=1089 amount=-1
|
||||
kerning first=1093 second=1090 amount=-1
|
||||
kerning first=1093 second=1092 amount=-1
|
||||
kerning first=1093 second=1095 amount=-2
|
||||
kerning first=1094 second=1077 amount=-1
|
||||
kerning first=1094 second=1079 amount=-1
|
||||
kerning first=1094 second=1086 amount=-1
|
||||
kerning first=1094 second=1089 amount=-1
|
||||
kerning first=1097 second=1077 amount=-1
|
||||
kerning first=1097 second=1086 amount=-1
|
||||
kerning first=1097 second=1091 amount=1
|
||||
kerning first=1100 second=1090 amount=-7
|
||||
kerning first=1100 second=1095 amount=-6
|
||||
kerning first=1101 second=1076 amount=-2
|
||||
kerning first=1101 second=1077 amount=1
|
||||
kerning first=1101 second=1079 amount=-1
|
||||
kerning first=1101 second=1083 amount=-2
|
||||
kerning first=1101 second=1086 amount=1
|
||||
kerning first=1101 second=1090 amount=-2
|
||||
kerning first=1101 second=1093 amount=-1
|
||||
kerning first=1101 second=1103 amount=-1
|
||||
kerning first=1102 second=1076 amount=-2
|
||||
kerning first=1102 second=1078 amount=-1
|
||||
kerning first=1102 second=1083 amount=-2
|
||||
kerning first=1102 second=1084 amount=-1
|
||||
kerning first=1102 second=1090 amount=-2
|
||||
kerning first=1102 second=1093 amount=-1
|
||||
kerning first=1102 second=1095 amount=-2
|
||||
3
samples/bin/library/arial_sdf.png
Normal file
3
samples/bin/library/arial_sdf.png
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ca1ca296c9b96cfccc469e1fa19f83019b95c77c564119db697595f418820440
|
||||
size 89901
|
||||
14
samples/bin/library/font_bm_material.json
Normal file
14
samples/bin/library/font_bm_material.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"passes" : [{
|
||||
"shader" : "font_bm_shader.json",
|
||||
"state_block" : {
|
||||
"blending_state" : {
|
||||
"src_factor" : "one",
|
||||
"dst_factor" : "one_minus_src_alpha"
|
||||
},
|
||||
"capabilities_state" : {
|
||||
"blending" : true
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
26
samples/bin/library/font_bm_shader.frag
Normal file
26
samples/bin/library/font_bm_shader.frag
Normal file
@@ -0,0 +1,26 @@
|
||||
uniform sampler2D u_texture;
|
||||
|
||||
uniform float u_glyph_dilate;
|
||||
uniform float u_outline_width;
|
||||
uniform vec4 u_outline_color;
|
||||
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color0;
|
||||
|
||||
void main() {
|
||||
vec4 t = texture2D(u_texture, v_st0);
|
||||
|
||||
float glyph_alpha = t.a;
|
||||
float outline_alpha = t.r;
|
||||
|
||||
vec4 glyph_color = vec4(v_color0.rgb * v_color0.a, v_color0.a);
|
||||
vec4 outline_color = vec4(u_outline_color.rgb * u_outline_color.a, u_outline_color.a);
|
||||
|
||||
vec2 layers_mask = vec2(
|
||||
step(0.0001, v_color0.a),
|
||||
step(0.0001, u_outline_color.a * u_outline_width));
|
||||
|
||||
gl_FragColor =
|
||||
layers_mask.x * glyph_alpha * glyph_color +
|
||||
layers_mask.y * outline_alpha * outline_color * (1.0 - glyph_alpha);
|
||||
}
|
||||
4
samples/bin/library/font_bm_shader.json
Normal file
4
samples/bin/library/font_bm_shader.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"vertex" : "font_bm_shader.vert",
|
||||
"fragment" : "font_bm_shader.frag"
|
||||
}
|
||||
39
samples/bin/library/font_bm_shader.vert
Normal file
39
samples/bin/library/font_bm_shader.vert
Normal file
@@ -0,0 +1,39 @@
|
||||
uniform vec2 u_screen_s;
|
||||
uniform mat4 u_matrix_m;
|
||||
uniform mat4 u_matrix_vp;
|
||||
|
||||
attribute vec3 a_vertex;
|
||||
attribute vec2 a_st0;
|
||||
attribute vec4 a_color0;
|
||||
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color0;
|
||||
|
||||
#define VERTEX_SNAPPING_ON
|
||||
|
||||
vec2 round(vec2 v) {
|
||||
return vec2(
|
||||
floor(v.x + 0.5),
|
||||
floor(v.y + 0.5));
|
||||
}
|
||||
|
||||
vec4 pixel_snap(vec4 pos) {
|
||||
vec2 hpc = u_screen_s * 0.5;
|
||||
vec2 pixel_pos = round((pos.xy / pos.w) * hpc);
|
||||
pos.xy = pixel_pos / hpc * pos.w;
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec4 vertex_to_homo(vec3 pos) {
|
||||
return vec4(pos, 1.0) * u_matrix_m * u_matrix_vp;
|
||||
}
|
||||
|
||||
void main() {
|
||||
v_st0 = vec2(a_st0.s, 1.0 - a_st0.t);
|
||||
v_color0 = a_color0;
|
||||
#ifndef VERTEX_SNAPPING_ON
|
||||
gl_Position = vertex_to_homo(a_vertex);
|
||||
#else
|
||||
gl_Position = pixel_snap(vertex_to_homo(a_vertex));
|
||||
#endif
|
||||
}
|
||||
14
samples/bin/library/font_sdf_material.json
Normal file
14
samples/bin/library/font_sdf_material.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"passes" : [{
|
||||
"shader" : "font_sdf_shader.json",
|
||||
"state_block" : {
|
||||
"blending_state" : {
|
||||
"src_factor" : "one",
|
||||
"dst_factor" : "one_minus_src_alpha"
|
||||
},
|
||||
"capabilities_state" : {
|
||||
"blending" : true
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
34
samples/bin/library/font_sdf_shader.frag
Normal file
34
samples/bin/library/font_sdf_shader.frag
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifdef GL_OES_standard_derivatives
|
||||
# extension GL_OES_standard_derivatives : require
|
||||
#endif
|
||||
|
||||
uniform sampler2D u_texture;
|
||||
|
||||
uniform float u_glyph_dilate;
|
||||
uniform float u_outline_width;
|
||||
uniform vec4 u_outline_color;
|
||||
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color0;
|
||||
|
||||
void main() {
|
||||
float distance = texture2D(u_texture, v_st0).a;
|
||||
float width = fwidth(distance);
|
||||
|
||||
float glyph_center = 0.5 - u_glyph_dilate * 0.5;
|
||||
float outline_center = glyph_center - u_outline_width * 0.5;
|
||||
|
||||
float glyph_alpha = smoothstep(glyph_center - width, glyph_center + width, distance);
|
||||
float outline_alpha = smoothstep(outline_center - width, outline_center + width, distance);
|
||||
|
||||
vec4 glyph_color = vec4(v_color0.rgb * v_color0.a, v_color0.a);
|
||||
vec4 outline_color = vec4(u_outline_color.rgb * u_outline_color.a, u_outline_color.a);
|
||||
|
||||
vec2 layers_mask = vec2(
|
||||
step(0.0001, v_color0.a),
|
||||
step(0.0001, u_outline_color.a * u_outline_width));
|
||||
|
||||
gl_FragColor =
|
||||
layers_mask.x * glyph_alpha * glyph_color +
|
||||
layers_mask.y * outline_alpha * outline_color * (1.0 - glyph_alpha);
|
||||
}
|
||||
4
samples/bin/library/font_sdf_shader.json
Normal file
4
samples/bin/library/font_sdf_shader.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"vertex" : "font_sdf_shader.vert",
|
||||
"fragment" : "font_sdf_shader.frag"
|
||||
}
|
||||
39
samples/bin/library/font_sdf_shader.vert
Normal file
39
samples/bin/library/font_sdf_shader.vert
Normal file
@@ -0,0 +1,39 @@
|
||||
uniform vec2 u_screen_s;
|
||||
uniform mat4 u_matrix_m;
|
||||
uniform mat4 u_matrix_vp;
|
||||
|
||||
attribute vec3 a_vertex;
|
||||
attribute vec2 a_st0;
|
||||
attribute vec4 a_color0;
|
||||
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color0;
|
||||
|
||||
#define VERTEX_SNAPPING_ON
|
||||
|
||||
vec2 round(vec2 v) {
|
||||
return vec2(
|
||||
floor(v.x + 0.5),
|
||||
floor(v.y + 0.5));
|
||||
}
|
||||
|
||||
vec4 pixel_snap(vec4 pos) {
|
||||
vec2 hpc = u_screen_s * 0.5;
|
||||
vec2 pixel_pos = round((pos.xy / pos.w) * hpc);
|
||||
pos.xy = pixel_pos / hpc * pos.w;
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec4 vertex_to_homo(vec3 pos) {
|
||||
return vec4(pos, 1.0) * u_matrix_m * u_matrix_vp;
|
||||
}
|
||||
|
||||
void main() {
|
||||
v_st0 = vec2(a_st0.s, 1.0 - a_st0.t);
|
||||
v_color0 = a_color0;
|
||||
#ifndef VERTEX_SNAPPING_ON
|
||||
gl_Position = vertex_to_homo(a_vertex);
|
||||
#else
|
||||
gl_Position = pixel_snap(vertex_to_homo(a_vertex));
|
||||
#endif
|
||||
}
|
||||
15
samples/bin/library/label_bm_prefab.json
Normal file
15
samples/bin/library/label_bm_prefab.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"components" : {
|
||||
"renderer" : {
|
||||
"materials" : [
|
||||
"font_bm_material.json"
|
||||
]
|
||||
},
|
||||
"model_renderer" : {},
|
||||
"label" : {
|
||||
"font" : "arial_bm.fnt",
|
||||
"text" : "Hello World!"
|
||||
},
|
||||
"label.dirty" : {}
|
||||
}
|
||||
}
|
||||
15
samples/bin/library/label_sdf_prefab.json
Normal file
15
samples/bin/library/label_sdf_prefab.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"components" : {
|
||||
"renderer" : {
|
||||
"materials" : [
|
||||
"font_sdf_material.json"
|
||||
]
|
||||
},
|
||||
"model_renderer" : {},
|
||||
"label" : {
|
||||
"font" : "arial_sdf.fnt",
|
||||
"text" : "Hello World!"
|
||||
},
|
||||
"label.dirty" : {}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,5 @@ uniform sampler2D u_texture;
|
||||
varying vec2 v_st0;
|
||||
|
||||
void main() {
|
||||
vec2 st = vec2(v_st0.s, 1.0 - v_st0.t);
|
||||
gl_FragColor = texture2D(u_texture, st);
|
||||
gl_FragColor = texture2D(u_texture, v_st0);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,11 @@ attribute vec2 a_st0;
|
||||
|
||||
varying vec2 v_st0;
|
||||
|
||||
void main() {
|
||||
v_st0 = a_st0;
|
||||
gl_Position = vec4(a_vertex, 1.0) * u_matrix_m * u_matrix_vp;
|
||||
vec4 vertex_to_homo(vec3 pos) {
|
||||
return vec4(pos, 1.0) * u_matrix_m * u_matrix_vp;
|
||||
}
|
||||
|
||||
void main() {
|
||||
v_st0 = vec2(a_st0.s, 1.0 - a_st0.t);
|
||||
gl_Position = vertex_to_homo(a_vertex);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"prototype" : "gnome_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [0,50,0],
|
||||
"translation" : [0,0,0],
|
||||
"scale" : 20
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,40 @@
|
||||
}, {
|
||||
"prototype" : "ship_prefab.json",
|
||||
"components" : {
|
||||
"sprite_renderer" : {
|
||||
"tint" : [255,0,0,255]
|
||||
},
|
||||
"actor" : {
|
||||
"translation" : [50,-50,0]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"prototype" : "label_bm_prefab.json",
|
||||
"components" : {
|
||||
"label" : {
|
||||
"text" : "bm font",
|
||||
"valign" : "center",
|
||||
"outline_width" : 0.5,
|
||||
"outline_color" : [0,0,0,255]
|
||||
},
|
||||
"actor" : {
|
||||
"translation" : [0,180,0],
|
||||
"scale" : 3
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"prototype" : "label_sdf_prefab.json",
|
||||
"components" : {
|
||||
"label" : {
|
||||
"text" : "sdf font",
|
||||
"valign" : "center",
|
||||
"outline_width" : 0.5,
|
||||
"outline_color" : [0,0,0,255]
|
||||
},
|
||||
"actor" : {
|
||||
"translation" : [0.5,-180.5,0],
|
||||
"scale" : 3
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"shader" : "sprite_shader.json",
|
||||
"state_block" : {
|
||||
"blending_state" : {
|
||||
"src_factor" : "src_alpha",
|
||||
"src_factor" : "one",
|
||||
"dst_factor" : "one_minus_src_alpha"
|
||||
},
|
||||
"capabilities_state" : {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
uniform sampler2D u_texture;
|
||||
|
||||
varying vec4 v_tint;
|
||||
varying vec2 v_st;
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color0;
|
||||
|
||||
void main() {
|
||||
vec2 st = vec2(v_st.s, 1.0 - v_st.t);
|
||||
gl_FragColor = texture2D(u_texture, st) * v_tint;
|
||||
vec4 c = texture2D(u_texture, v_st0) * v_color0;
|
||||
c.rgb *= c.a;
|
||||
gl_FragColor = c;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,36 @@
|
||||
uniform vec2 u_screen_s;
|
||||
uniform mat4 u_matrix_vp;
|
||||
|
||||
attribute vec3 a_vertex;
|
||||
attribute vec4 a_tint;
|
||||
attribute vec2 a_st;
|
||||
attribute vec2 a_st0;
|
||||
attribute vec4 a_color0;
|
||||
|
||||
varying vec4 v_tint;
|
||||
varying vec2 v_st;
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color0;
|
||||
|
||||
vec2 round(vec2 v) {
|
||||
return vec2(
|
||||
floor(v.x + 0.5),
|
||||
floor(v.y + 0.5));
|
||||
}
|
||||
|
||||
vec4 pixel_snap(vec4 pos) {
|
||||
vec2 hpc = u_screen_s * 0.5;
|
||||
vec2 pixel_pos = round((pos.xy / pos.w) * hpc);
|
||||
pos.xy = pixel_pos / hpc * pos.w;
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec4 vertex_to_homo(vec3 pos) {
|
||||
return vec4(pos, 1.0) * u_matrix_vp;
|
||||
}
|
||||
|
||||
void main() {
|
||||
v_st = a_st;
|
||||
v_tint = a_tint;
|
||||
gl_Position = vec4(a_vertex, 1.0) * u_matrix_vp;
|
||||
v_st0 = vec2(a_st0.s, 1.0 - a_st0.t);
|
||||
v_color0 = a_color0;
|
||||
#ifndef VERTEX_SNAPPING_ON
|
||||
gl_Position = vertex_to_homo(a_vertex);
|
||||
#else
|
||||
gl_Position = pixel_snap(vertex_to_homo(a_vertex));
|
||||
#endif
|
||||
}
|
||||
|
||||
1
sources/3rdparty/miniz/miniz_export.h
vendored
1
sources/3rdparty/miniz/miniz_export.h
vendored
@@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#define MINIZ_EXPORT
|
||||
#define MINIZ_NO_STDIO
|
||||
|
||||
63
sources/enduro2d/high/assets/font_asset.cpp
Normal file
63
sources/enduro2d/high/assets/font_asset.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <enduro2d/high/assets/font_asset.hpp>
|
||||
|
||||
#include <enduro2d/high/assets/binary_asset.hpp>
|
||||
#include <enduro2d/high/assets/texture_asset.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
class font_asset_loading_exception final : public asset_loading_exception {
|
||||
const char* what() const noexcept final {
|
||||
return "font asset loading exception";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
font_asset::load_async_result font_asset::load_async(
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<binary_asset>(address)
|
||||
.then([](const binary_asset::load_result& font_data){
|
||||
return the<deferrer>().do_in_worker_thread([font_data](){
|
||||
font content;
|
||||
if ( !fonts::try_load_font(content, font_data->content()) ) {
|
||||
throw font_asset_loading_exception();
|
||||
}
|
||||
return content;
|
||||
});
|
||||
})
|
||||
.then([
|
||||
&library,
|
||||
parent_address = path::parent_path(address)
|
||||
](const font& content){
|
||||
return stdex::make_tuple_promise(std::make_tuple(
|
||||
stdex::make_resolved_promise(content),
|
||||
library.load_asset_async<texture_asset>(
|
||||
path::combine(parent_address, content.info().atlas_file))
|
||||
));
|
||||
})
|
||||
.then([](const std::tuple<
|
||||
font,
|
||||
texture_asset::load_result
|
||||
>& results){
|
||||
font content = std::get<0>(results);
|
||||
texture_asset::load_result texture_res = std::get<1>(results);
|
||||
if ( content.info().atlas_size != texture_res->content()->size() ) {
|
||||
throw font_asset_loading_exception();
|
||||
}
|
||||
nested_content ncontent{{
|
||||
make_hash(content.info().atlas_file),
|
||||
std::move(texture_res)}};
|
||||
return font_asset::create(std::move(content), std::move(ncontent));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ namespace
|
||||
},
|
||||
"sampler" : {
|
||||
"type" : "object",
|
||||
"required" : [ "name" ],
|
||||
"required" : [ "name", "texture" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"name" : {
|
||||
@@ -201,7 +201,7 @@ namespace
|
||||
},
|
||||
"property" : {
|
||||
"type" : "object",
|
||||
"required" : [ "name", "type" ],
|
||||
"required" : [ "name", "type", "value" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"name" : { "$ref" : "#/common_definitions/name" },
|
||||
@@ -514,11 +514,10 @@ namespace
|
||||
render::sampler_state content;
|
||||
|
||||
E2D_ASSERT(root.HasMember("name") && root["name"].IsString());
|
||||
auto name_hash = make_hash(root["name"].GetString());
|
||||
E2D_ASSERT(root.HasMember("texture") && root["texture"].IsString());
|
||||
|
||||
auto texture_p = root.HasMember("texture")
|
||||
? parse_texture_block(library, parent_address, root["texture"])
|
||||
: stdex::make_resolved_promise<texture_ptr>(nullptr);
|
||||
auto name_hash = make_hash(root["name"].GetString());
|
||||
auto texture_p = parse_texture_block(library, parent_address, root["texture"]);
|
||||
|
||||
if ( root.HasMember("wrap") ) {
|
||||
const auto& wrap_json = root["wrap"];
|
||||
@@ -609,15 +608,14 @@ namespace
|
||||
|
||||
E2D_ASSERT(property_json.HasMember("name") && property_json["name"].IsString());
|
||||
E2D_ASSERT(property_json.HasMember("type") && property_json["type"].IsString());
|
||||
E2D_ASSERT(property_json.HasMember("value"));
|
||||
|
||||
#define DEFINE_CASE(x)\
|
||||
if ( 0 == std::strcmp(property_json["type"].GetString(), #x) ) {\
|
||||
x value;\
|
||||
if ( property_json.HasMember("value") ) {\
|
||||
if ( !json_utils::try_parse_value(property_json["value"], value) ) {\
|
||||
E2D_ASSERT_MSG(false, "unexpected property value");\
|
||||
return false;\
|
||||
}\
|
||||
if ( !json_utils::try_parse_value(property_json["value"], value) ) {\
|
||||
E2D_ASSERT_MSG(false, "unexpected property value");\
|
||||
return false;\
|
||||
}\
|
||||
props.property(property_json["name"].GetString(), value);\
|
||||
continue;\
|
||||
|
||||
221
sources/enduro2d/high/components/label.cpp
Normal file
221
sources/enduro2d/high/components/label.cpp
Normal file
@@ -0,0 +1,221 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <enduro2d/high/components/label.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
bool parse_halign(str_view str, label::haligns& align) noexcept {
|
||||
#define DEFINE_IF(x) if ( str == #x ) { align = label::haligns::x; return true; }
|
||||
DEFINE_IF(left);
|
||||
DEFINE_IF(center);
|
||||
DEFINE_IF(right);
|
||||
#undef DEFINE_IF
|
||||
return false;
|
||||
}
|
||||
|
||||
bool parse_valign(str_view str, label::valigns& align) noexcept {
|
||||
#define DEFINE_IF(x) if ( str == #x ) { align = label::valigns::x; return true; }
|
||||
DEFINE_IF(top);
|
||||
DEFINE_IF(center);
|
||||
DEFINE_IF(bottom);
|
||||
DEFINE_IF(baseline);
|
||||
#undef DEFINE_IF
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
const char* factory_loader<label>::schema_source = R"json({
|
||||
"type" : "object",
|
||||
"required" : [],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"text" : { "type" : "string" },
|
||||
"font" : { "$ref": "#/common_definitions/address" },
|
||||
"tint" : { "$ref": "#/common_definitions/color" },
|
||||
"halign" : { "$ref": "#/definitions/haligns" },
|
||||
"valign" : { "$ref": "#/definitions/valigns" },
|
||||
"leading" : { "type" : "number" },
|
||||
"tracking" : { "type" : "number" },
|
||||
"text_width" : { "type" : "number" },
|
||||
"glyph_dilate" : { "type" : "number" },
|
||||
"outline_width" : { "type" : "number" },
|
||||
"outline_color" : { "$ref": "#/common_definitions/color" }
|
||||
},
|
||||
"definitions" : {
|
||||
"haligns" : {
|
||||
"type" : "string",
|
||||
"enum" : [
|
||||
"left",
|
||||
"center",
|
||||
"right"
|
||||
]
|
||||
},
|
||||
"valigns" : {
|
||||
"type" : "string",
|
||||
"enum" : [
|
||||
"top",
|
||||
"center",
|
||||
"bottom",
|
||||
"baseline"
|
||||
]
|
||||
}
|
||||
}
|
||||
})json";
|
||||
|
||||
bool factory_loader<label>::operator()(
|
||||
label& component,
|
||||
const fill_context& ctx) const
|
||||
{
|
||||
if ( ctx.root.HasMember("text") ) {
|
||||
str text = component.text();
|
||||
if ( !json_utils::try_parse_value(ctx.root["text"], text) ) {
|
||||
the<debug>().error("LABEL: Incorrect formatting of 'text' property");
|
||||
return false;
|
||||
}
|
||||
component.text(std::move(text));
|
||||
}
|
||||
|
||||
if ( ctx.root.HasMember("font") ) {
|
||||
auto font = ctx.dependencies.find_asset<font_asset>(
|
||||
path::combine(ctx.parent_address, ctx.root["font"].GetString()));
|
||||
if ( !font ) {
|
||||
the<debug>().error("LABEL: Dependency 'font' is not found:\n"
|
||||
"--> Parent address: %0\n"
|
||||
"--> Dependency address: %1",
|
||||
ctx.parent_address,
|
||||
ctx.root["font"].GetString());
|
||||
return false;
|
||||
}
|
||||
component.font(font);
|
||||
}
|
||||
|
||||
if ( ctx.root.HasMember("tint") ) {
|
||||
color32 tint = component.tint();
|
||||
if ( !json_utils::try_parse_value(ctx.root["tint"], tint) ) {
|
||||
the<debug>().error("LABEL: Incorrect formatting of 'tint' property");
|
||||
return false;
|
||||
}
|
||||
component.tint(tint);
|
||||
}
|
||||
|
||||
if ( ctx.root.HasMember("halign") ) {
|
||||
label::haligns halign = component.halign();
|
||||
if ( !parse_halign(ctx.root["halign"].GetString(), halign) ) {
|
||||
the<debug>().error("LABEL: Incorrect formatting of 'halign' property");
|
||||
return false;
|
||||
}
|
||||
component.haligh(halign);
|
||||
}
|
||||
|
||||
if ( ctx.root.HasMember("valign") ) {
|
||||
label::valigns valign = component.valign();
|
||||
if ( !parse_valign(ctx.root["valign"].GetString(), valign) ) {
|
||||
the<debug>().error("LABEL: Incorrect formatting of 'valign' property");
|
||||
return false;
|
||||
}
|
||||
component.valigh(valign);
|
||||
}
|
||||
|
||||
if ( ctx.root.HasMember("leading") ) {
|
||||
f32 leading = component.leading();
|
||||
if ( !json_utils::try_parse_value(ctx.root["leading"], leading) ) {
|
||||
the<debug>().error("LABEL: Incorrect formatting of 'leading' property");
|
||||
return false;
|
||||
}
|
||||
component.leading(leading);
|
||||
}
|
||||
|
||||
if ( ctx.root.HasMember("tracking") ) {
|
||||
f32 tracking = component.tracking();
|
||||
if ( !json_utils::try_parse_value(ctx.root["tracking"], tracking) ) {
|
||||
the<debug>().error("LABEL: Incorrect formatting of 'tracking' property");
|
||||
return false;
|
||||
}
|
||||
component.tracking(tracking);
|
||||
}
|
||||
|
||||
if ( ctx.root.HasMember("text_width") ) {
|
||||
f32 text_width = component.text_width();
|
||||
if ( !json_utils::try_parse_value(ctx.root["text_width"], text_width) ) {
|
||||
the<debug>().error("LABEL: Incorrect formatting of 'text_width' property");
|
||||
return false;
|
||||
}
|
||||
component.text_width(text_width);
|
||||
}
|
||||
|
||||
if ( ctx.root.HasMember("glyph_dilate") ) {
|
||||
f32 glyph_dilate = component.glyph_dilate();
|
||||
if ( !json_utils::try_parse_value(ctx.root["glyph_dilate"], glyph_dilate) ) {
|
||||
the<debug>().error("LABEL: Incorrect formatting of 'glyph_dilate' property");
|
||||
return false;
|
||||
}
|
||||
component.glyph_dilate(glyph_dilate);
|
||||
}
|
||||
|
||||
if ( ctx.root.HasMember("outline_width") ) {
|
||||
f32 outline_width = component.outline_width();
|
||||
if ( !json_utils::try_parse_value(ctx.root["outline_width"], outline_width) ) {
|
||||
the<debug>().error("LABEL: Incorrect formatting of 'outline_width' property");
|
||||
return false;
|
||||
}
|
||||
component.outline_width(outline_width);
|
||||
}
|
||||
|
||||
if ( ctx.root.HasMember("outline_color") ) {
|
||||
color32 outline_color = component.outline_color();
|
||||
if ( !json_utils::try_parse_value(ctx.root["outline_color"], outline_color) ) {
|
||||
the<debug>().error("LABEL: Incorrect formatting of 'outline_color' property");
|
||||
return false;
|
||||
}
|
||||
component.outline_color(outline_color);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool factory_loader<label>::operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const
|
||||
{
|
||||
if ( ctx.root.HasMember("font") ) {
|
||||
dependencies.add_dependency<font_asset>(
|
||||
path::combine(ctx.parent_address, ctx.root["font"].GetString()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
const char* factory_loader<label::dirty>::schema_source = R"json({
|
||||
"type" : "object",
|
||||
"required" : [],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {}
|
||||
})json";
|
||||
|
||||
bool factory_loader<label::dirty>::operator()(
|
||||
label::dirty& component,
|
||||
const fill_context& ctx) const
|
||||
{
|
||||
E2D_UNUSED(component, ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool factory_loader<label::dirty>::operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const
|
||||
{
|
||||
E2D_UNUSED(dependencies, ctx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -14,12 +14,14 @@
|
||||
#include <enduro2d/high/components/camera.hpp>
|
||||
#include <enduro2d/high/components/flipbook_player.hpp>
|
||||
#include <enduro2d/high/components/flipbook_source.hpp>
|
||||
#include <enduro2d/high/components/label.hpp>
|
||||
#include <enduro2d/high/components/model_renderer.hpp>
|
||||
#include <enduro2d/high/components/renderer.hpp>
|
||||
#include <enduro2d/high/components/scene.hpp>
|
||||
#include <enduro2d/high/components/sprite_renderer.hpp>
|
||||
|
||||
#include <enduro2d/high/systems/flipbook_system.hpp>
|
||||
#include <enduro2d/high/systems/label_system.hpp>
|
||||
#include <enduro2d/high/systems/render_system.hpp>
|
||||
|
||||
namespace
|
||||
@@ -41,6 +43,7 @@ namespace
|
||||
bool initialize() final {
|
||||
ecs::registry_filler(the<world>().registry())
|
||||
.system<flipbook_system>(world::priority_update)
|
||||
.system<label_system>(world::priority_update)
|
||||
.system<render_system>(world::priority_render);
|
||||
return !application_ || application_->initialize();
|
||||
}
|
||||
@@ -130,6 +133,8 @@ namespace e2d
|
||||
.register_component<camera>("camera")
|
||||
.register_component<flipbook_player>("flipbook_player")
|
||||
.register_component<flipbook_source>("flipbook_source")
|
||||
.register_component<label>("label")
|
||||
.register_component<label::dirty>("label.dirty")
|
||||
.register_component<model_renderer>("model_renderer")
|
||||
.register_component<renderer>("renderer")
|
||||
.register_component<scene>("scene")
|
||||
|
||||
386
sources/enduro2d/high/systems/label_system.cpp
Normal file
386
sources/enduro2d/high/systems/label_system.cpp
Normal file
@@ -0,0 +1,386 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <enduro2d/high/systems/label_system.hpp>
|
||||
|
||||
#include <enduro2d/high/assets/font_asset.hpp>
|
||||
#include <enduro2d/high/assets/texture_asset.hpp>
|
||||
|
||||
#include <enduro2d/high/components/label.hpp>
|
||||
#include <enduro2d/high/components/renderer.hpp>
|
||||
#include <enduro2d/high/components/model_renderer.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
class geometry_builder {
|
||||
public:
|
||||
geometry_builder() = default;
|
||||
|
||||
void add_quad(
|
||||
const b2f& rect,
|
||||
const b2f& texrect,
|
||||
const color32& color)
|
||||
{
|
||||
const std::size_t start_vertex = vertices_.size();
|
||||
|
||||
// Y
|
||||
// ^
|
||||
// | 3 - 2
|
||||
// | | / |
|
||||
// | 0 - 1
|
||||
// +------> X
|
||||
|
||||
{
|
||||
const v2f& gp = rect.position;
|
||||
const v2f& gs = rect.size;
|
||||
|
||||
vertices_.emplace_back(gp.x + 0.0f, gp.y + 0.0f, 0.f);
|
||||
vertices_.emplace_back(gp.x + gs.x, gp.y + 0.0f, 0.f);
|
||||
vertices_.emplace_back(gp.x + gs.x, gp.y + gs.y, 0.f);
|
||||
vertices_.emplace_back(gp.x + 0.0f, gp.y + gs.y, 0.f);
|
||||
}
|
||||
|
||||
{
|
||||
const v2f& tp = texrect.position;
|
||||
const v2f& ts = texrect.size;
|
||||
|
||||
uvs_.emplace_back(tp.x + 0.0f, tp.y + 0.0f);
|
||||
uvs_.emplace_back(tp.x + ts.x, tp.y + 0.0f);
|
||||
uvs_.emplace_back(tp.x + ts.x, tp.y + ts.y);
|
||||
uvs_.emplace_back(tp.x + 0.0f, tp.y + ts.y);
|
||||
}
|
||||
|
||||
{
|
||||
indices_.emplace_back(start_vertex + 0u);
|
||||
indices_.emplace_back(start_vertex + 1u);
|
||||
indices_.emplace_back(start_vertex + 2u);
|
||||
indices_.emplace_back(start_vertex + 2u);
|
||||
indices_.emplace_back(start_vertex + 3u);
|
||||
indices_.emplace_back(start_vertex + 0u);
|
||||
}
|
||||
|
||||
{
|
||||
colors_.emplace_back(color);
|
||||
colors_.emplace_back(color);
|
||||
colors_.emplace_back(color);
|
||||
colors_.emplace_back(color);
|
||||
}
|
||||
}
|
||||
|
||||
void update_model(model_renderer& mr) {
|
||||
mesh new_mesh;
|
||||
new_mesh.set_vertices(vertices_);
|
||||
new_mesh.set_indices(0, indices_);
|
||||
new_mesh.set_uvs(0, uvs_);
|
||||
new_mesh.set_colors(0, colors_);
|
||||
|
||||
model new_model;
|
||||
new_model.set_mesh(mesh_asset::create(std::move(new_mesh)));
|
||||
new_model.regenerate_geometry(the<render>());
|
||||
|
||||
if ( mr.model() ) {
|
||||
mr.model()->fill(std::move(new_model));
|
||||
} else {
|
||||
mr.model(model_asset::create(std::move(new_model)));
|
||||
}
|
||||
}
|
||||
|
||||
void clear() noexcept {
|
||||
vertices_.clear();
|
||||
uvs_.clear();
|
||||
indices_.clear();
|
||||
colors_.clear();
|
||||
}
|
||||
private:
|
||||
vector<v3f> vertices_;
|
||||
vector<v2f> uvs_;
|
||||
vector<u32> indices_;
|
||||
vector<color32> colors_;
|
||||
};
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
f32 calculate_halign_offset(
|
||||
label::haligns halign,
|
||||
f32 string_width) noexcept
|
||||
{
|
||||
switch ( halign ) {
|
||||
case label::haligns::left:
|
||||
return 0.0f;
|
||||
case label::haligns::center:
|
||||
return -0.5f * string_width;
|
||||
case label::haligns::right:
|
||||
return -1.0f * string_width;
|
||||
default:
|
||||
E2D_ASSERT_MSG(false, "unexpected label halign");
|
||||
return 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
f32 calculate_valign_offset(
|
||||
label::valigns valign,
|
||||
f32 leading,
|
||||
u32 glyph_ascent,
|
||||
u32 line_height,
|
||||
std::size_t string_count) noexcept
|
||||
{
|
||||
const f32 label_height = string_count > 1u
|
||||
? line_height + line_height * leading * (string_count - 1u)
|
||||
: line_height;
|
||||
|
||||
switch ( valign ) {
|
||||
case label::valigns::top:
|
||||
return 0.f;
|
||||
case label::valigns::center:
|
||||
return 0.5f * label_height;
|
||||
case label::valigns::bottom:
|
||||
return 1.0f * label_height;
|
||||
case label::valigns::baseline:
|
||||
return 1.0f * glyph_ascent;
|
||||
default:
|
||||
E2D_ASSERT_MSG(false, "unexpected label valign");
|
||||
return 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t calculate_string_count(str32_view text) noexcept {
|
||||
std::size_t count{0u};
|
||||
for ( std::size_t i = 0; i < text.size(); ++i ) {
|
||||
if ( text[i] == '\n' ) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
void update_label_material(const label& l, renderer& r) {
|
||||
auto texture_res = l.font() && !l.font()->content().empty()
|
||||
? l.font()->find_nested_asset<texture_asset>(l.font()->content().info().atlas_file)
|
||||
: nullptr;
|
||||
|
||||
auto texture = texture_res
|
||||
? texture_res->content()
|
||||
: nullptr;
|
||||
|
||||
const f32 glyph_dilate = math::clamp(l.glyph_dilate(), -1.f, 1.0f);
|
||||
const f32 outline_width = math::clamp(l.outline_width(), 0.f, 1.f - glyph_dilate);
|
||||
const v4f outline_color = make_vec4(color(l.outline_color()));
|
||||
|
||||
r.properties(render::property_block()
|
||||
.sampler("u_texture", render::sampler_state()
|
||||
.texture(texture)
|
||||
.min_filter(render::sampler_min_filter::linear)
|
||||
.mag_filter(render::sampler_mag_filter::linear))
|
||||
.property("u_glyph_dilate", glyph_dilate)
|
||||
.property("u_outline_width", outline_width)
|
||||
.property("u_outline_color", outline_color));
|
||||
}
|
||||
|
||||
void update_label_geometry(const label& l, model_renderer& mr, geometry_builder& gb) {
|
||||
if ( !l.font() || l.font()->content().empty() || l.text().empty() ) {
|
||||
gb.update_model(mr);
|
||||
return;
|
||||
}
|
||||
|
||||
const font& f = l.font()->content();
|
||||
const str32& text = make_utf32(l.text());
|
||||
|
||||
//
|
||||
// update glyphs
|
||||
//
|
||||
|
||||
struct glyph_desc {
|
||||
const font::glyph_info* glyph{nullptr};
|
||||
f32 kerning{0.f};
|
||||
};
|
||||
|
||||
vector<glyph_desc> glyphs;
|
||||
glyphs.reserve(text.size());
|
||||
|
||||
for ( std::size_t i = 0, e = text.size(); i < e; ++i ) {
|
||||
glyph_desc desc;
|
||||
desc.glyph = f.find_glyph(text[i]);
|
||||
desc.kerning = i > 0
|
||||
? f.get_kerning(text[i-1], text[i])
|
||||
: 0.f;
|
||||
glyphs.push_back(std::move(desc));
|
||||
|
||||
if ( !desc.glyph && text[i] != '\n' ) {
|
||||
the<debug>().warning("LABEL: Missing font glyph:\n"
|
||||
"--> Code Point: %0",
|
||||
text[i]);
|
||||
}
|
||||
}
|
||||
|
||||
f32 tracking_width = 0.f;
|
||||
if ( const font::glyph_info* sp = f.find_glyph(' '); sp ) {
|
||||
tracking_width = sp->advance * l.tracking();
|
||||
}
|
||||
|
||||
//
|
||||
// update strings
|
||||
//
|
||||
|
||||
struct string_desc {
|
||||
f32 width{0.f};
|
||||
std::size_t start{0};
|
||||
std::size_t length{0};
|
||||
|
||||
string_desc(std::size_t start)
|
||||
: start(start) {}
|
||||
};
|
||||
|
||||
vector<string_desc> strings;
|
||||
strings.reserve(calculate_string_count(text));
|
||||
|
||||
f32 last_space_width = 0.f;
|
||||
std::size_t last_space_index = std::size_t(-1);
|
||||
|
||||
strings.push_back(string_desc(0u));
|
||||
|
||||
for ( std::size_t i = 0, e = text.size(); i < e; ++i ) {
|
||||
const u32 code_point = text[i];
|
||||
const glyph_desc& glyph = glyphs[i];
|
||||
|
||||
if ( code_point == ' ' ) {
|
||||
last_space_width = strings.back().width;
|
||||
last_space_index = i;
|
||||
}
|
||||
|
||||
bool new_line = false;
|
||||
|
||||
if ( code_point == '\n' ) {
|
||||
new_line = true;
|
||||
strings.back().length = i - strings.back().start;
|
||||
} else if ( glyph.glyph ) {
|
||||
strings.back().width +=
|
||||
glyph.kerning +
|
||||
glyph.glyph->advance +
|
||||
tracking_width;
|
||||
|
||||
const bool break_line =
|
||||
l.text_width() > 0.f &&
|
||||
last_space_index != std::size_t(-1) &&
|
||||
strings.back().width > l.text_width();
|
||||
|
||||
if ( break_line ) {
|
||||
new_line = true;
|
||||
strings.back().width = last_space_width;
|
||||
strings.back().length = last_space_index - strings.back().start;
|
||||
i = last_space_index;
|
||||
}
|
||||
}
|
||||
|
||||
if ( i == e - 1 ) {
|
||||
new_line = true;
|
||||
strings.back().length = i + 1 - strings.back().start;
|
||||
}
|
||||
|
||||
if ( new_line ) {
|
||||
if ( i < e - 1 ) {
|
||||
strings.push_back(string_desc(i + 1u));
|
||||
}
|
||||
last_space_width = 0.f;
|
||||
last_space_index = std::size_t(-1);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// update geometry
|
||||
//
|
||||
|
||||
v2f cursor = v2f::unit_y() * calculate_valign_offset(
|
||||
l.valign(),
|
||||
l.leading(),
|
||||
f.info().glyph_ascent,
|
||||
f.info().line_height,
|
||||
strings.size());
|
||||
|
||||
for ( std::size_t i = 0, ie = strings.size(); i < ie; ++i ) {
|
||||
cursor.x = calculate_halign_offset(l.halign(), strings[i].width);
|
||||
for ( std::size_t j = strings[i].start, je = strings[i].start + strings[i].length; j < je; ++j ) {
|
||||
const glyph_desc& glyph = glyphs[j];
|
||||
if ( !glyph.glyph ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cursor.x += glyph.kerning;
|
||||
|
||||
b2f rect = make_rect(cursor, glyph.glyph->tex_rect.size.cast_to<f32>());
|
||||
rect.position += glyph.glyph->offset.cast_to<f32>();
|
||||
|
||||
b2f texrect = glyph.glyph->tex_rect.cast_to<f32>();
|
||||
texrect.position /= f.info().atlas_size.cast_to<f32>();
|
||||
texrect.size /= f.info().atlas_size.cast_to<f32>();
|
||||
|
||||
gb.add_quad(rect, texrect, l.tint());
|
||||
cursor.x += glyph.glyph->advance + tracking_width;
|
||||
}
|
||||
cursor.y -= f.info().line_height * l.leading();
|
||||
}
|
||||
|
||||
//
|
||||
// update model
|
||||
//
|
||||
|
||||
gb.update_model(mr);
|
||||
}
|
||||
|
||||
void update_dirty_labels(ecs::registry& owner) {
|
||||
geometry_builder gb;
|
||||
owner.for_joined_components<label::dirty, label, renderer, model_renderer>([&gb](
|
||||
const ecs::const_entity&,
|
||||
const label::dirty&,
|
||||
const label& l,
|
||||
renderer& r,
|
||||
model_renderer& mr
|
||||
){
|
||||
update_label_material(l, r);
|
||||
update_label_geometry(l, mr, gb);
|
||||
gb.clear();
|
||||
});
|
||||
owner.remove_all_components<label::dirty>();
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
//
|
||||
// label_system::internal_state
|
||||
//
|
||||
|
||||
class label_system::internal_state final : private noncopyable {
|
||||
public:
|
||||
internal_state() = default;
|
||||
~internal_state() noexcept = default;
|
||||
|
||||
void process(ecs::registry& owner) {
|
||||
update_dirty_labels(owner);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// label_system
|
||||
//
|
||||
|
||||
label_system::label_system()
|
||||
: state_(new internal_state()) {}
|
||||
label_system::~label_system() noexcept = default;
|
||||
|
||||
void label_system::process(ecs::registry& owner) {
|
||||
state_->process(owner);
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,7 @@ namespace e2d
|
||||
class render_system::internal_state final : private noncopyable {
|
||||
public:
|
||||
internal_state()
|
||||
: drawer_(the<engine>(), the<debug>(), the<render>()) {}
|
||||
: drawer_(the<engine>(), the<debug>(), the<render>(), the<window>()) {}
|
||||
~internal_state() noexcept = default;
|
||||
|
||||
void process(ecs::registry& owner) {
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace e2d::render_system_impl
|
||||
static vertex_declaration decl() noexcept {
|
||||
return vertex_declaration()
|
||||
.add_attribute<v3f>("a_vertex")
|
||||
.add_attribute<v2f>("a_st")
|
||||
.add_attribute<color32>("a_tint").normalized();
|
||||
.add_attribute<v2f>("a_st0")
|
||||
.add_attribute<color32>("a_color0").normalized();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
const str_hash screen_s_property_hash = "u_screen_s";
|
||||
const str_hash matrix_v_property_hash = "u_matrix_v";
|
||||
const str_hash matrix_p_property_hash = "u_matrix_p";
|
||||
const str_hash matrix_vp_property_hash = "u_matrix_vp";
|
||||
@@ -32,6 +33,7 @@ namespace e2d::render_system_impl
|
||||
const const_node_iptr& cam_n,
|
||||
engine& engine,
|
||||
render& render,
|
||||
window& window,
|
||||
batcher_type& batcher)
|
||||
: render_(render)
|
||||
, batcher_(batcher)
|
||||
@@ -47,6 +49,9 @@ namespace e2d::render_system_impl
|
||||
const m4f& m_p = cam.projection();
|
||||
|
||||
batcher_.flush()
|
||||
.property(screen_s_property_hash, cam.target()
|
||||
? cam.target()->size().cast_to<f32>()
|
||||
: window.framebuffer_size().cast_to<f32>())
|
||||
.property(matrix_v_property_hash, m_v)
|
||||
.property(matrix_p_property_hash, m_p)
|
||||
.property(matrix_vp_property_hash, m_v * m_p)
|
||||
@@ -219,8 +224,9 @@ namespace e2d::render_system_impl
|
||||
// drawer
|
||||
//
|
||||
|
||||
drawer::drawer(engine& e, debug& d, render& r)
|
||||
drawer::drawer(engine& e, debug& d, render& r, window& w)
|
||||
: engine_(e)
|
||||
, render_(r)
|
||||
, window_(w)
|
||||
, batcher_(d, r) {}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace e2d::render_system_impl
|
||||
const const_node_iptr& cam_n,
|
||||
engine& engine,
|
||||
render& render,
|
||||
window& window,
|
||||
batcher_type& batcher);
|
||||
~context() noexcept;
|
||||
|
||||
@@ -59,13 +60,14 @@ namespace e2d::render_system_impl
|
||||
render::property_block property_cache_;
|
||||
};
|
||||
public:
|
||||
drawer(engine& e, debug& d, render& r);
|
||||
drawer(engine& e, debug& d, render& r, window& w);
|
||||
|
||||
template < typename F >
|
||||
void with(const camera& cam, const const_node_iptr& cam_n, F&& f);
|
||||
private:
|
||||
engine& engine_;
|
||||
render& render_;
|
||||
window& window_;
|
||||
batcher_type batcher_;
|
||||
};
|
||||
}
|
||||
@@ -74,7 +76,7 @@ namespace e2d::render_system_impl
|
||||
{
|
||||
template < typename F >
|
||||
void drawer::with(const camera& cam, const const_node_iptr& cam_n, F&& f) {
|
||||
context ctx{cam, cam_n, engine_, render_, batcher_};
|
||||
context ctx{cam, cam_n, engine_, render_, window_, batcher_};
|
||||
std::forward<F>(f)(ctx);
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
@@ -139,6 +139,14 @@ namespace e2d
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
vec3<f32> make_vec3(const color& c) noexcept {
|
||||
return make_vec3(c.r, c.g, c.b);
|
||||
}
|
||||
|
||||
vec4<f32> make_vec4(const color& c) noexcept {
|
||||
return make_vec4(c.r, c.g, c.b, c.a);
|
||||
}
|
||||
|
||||
//
|
||||
// color (<,==,!=) color
|
||||
//
|
||||
|
||||
@@ -139,6 +139,14 @@ namespace e2d
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
vec3<u8> make_vec3(const color32& c) noexcept {
|
||||
return make_vec3(c.r, c.g, c.b);
|
||||
}
|
||||
|
||||
vec4<u8> make_vec4(const color32& c) noexcept {
|
||||
return make_vec4(c.r, c.g, c.b, c.a);
|
||||
}
|
||||
|
||||
//
|
||||
// color32 (<,==,!=) color32
|
||||
//
|
||||
|
||||
170
sources/enduro2d/utils/font.cpp
Normal file
170
sources/enduro2d/utils/font.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "font_impl/font_impl.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
u64 make_kerning_key(u32 first, u32 second) noexcept {
|
||||
return (static_cast<u64>(first) << 32) | static_cast<u64>(second);
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
font::font(font&& other) noexcept {
|
||||
assign(std::move(other));
|
||||
}
|
||||
|
||||
font& font::operator=(font&& other) noexcept {
|
||||
return assign(std::move(other));
|
||||
}
|
||||
|
||||
font::font(const font& other) {
|
||||
assign(other);
|
||||
}
|
||||
|
||||
font& font::operator=(const font& other) {
|
||||
return assign(other);
|
||||
}
|
||||
|
||||
font::font(content&& content) noexcept {
|
||||
assign(std::move(content));
|
||||
}
|
||||
|
||||
font::font(const content& content) {
|
||||
assign(content);
|
||||
}
|
||||
|
||||
font& font::assign(font&& other) noexcept {
|
||||
if ( this != &other ) {
|
||||
swap(other);
|
||||
other.clear();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
font& font::assign(const font& other) {
|
||||
if ( this != &other ) {
|
||||
content_ = other.content_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
font& font::assign(content&& content) noexcept {
|
||||
content_ = std::move(content);
|
||||
return *this;
|
||||
}
|
||||
|
||||
font& font::assign(const content& content) {
|
||||
content_ = content;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void font::swap(font& other) noexcept {
|
||||
using std::swap;
|
||||
swap(content_.info, other.content_.info);
|
||||
swap(content_.kernings, other.content_.kernings);
|
||||
swap(content_.glyphs, other.content_.glyphs);
|
||||
}
|
||||
|
||||
void font::clear() noexcept {
|
||||
content_ = content();
|
||||
}
|
||||
|
||||
bool font::empty() const noexcept {
|
||||
return !content_.info.font_size;
|
||||
}
|
||||
|
||||
const font::font_info& font::info() const noexcept {
|
||||
return content_.info;
|
||||
}
|
||||
|
||||
const flat_map<u64, i32>& font::kernings() const noexcept {
|
||||
return content_.kernings;
|
||||
}
|
||||
|
||||
const flat_map<u32, font::glyph_info>& font::glyphs() const noexcept {
|
||||
return content_.glyphs;
|
||||
}
|
||||
|
||||
i32 font::get_kerning(u32 first, u32 second) const noexcept {
|
||||
const u64 key = make_kerning_key(first, second);
|
||||
const auto iter = content_.kernings.find(key);
|
||||
return iter != content_.kernings.end()
|
||||
? iter->second
|
||||
: 0;
|
||||
}
|
||||
|
||||
const font::glyph_info* font::find_glyph(u32 code_point) const noexcept {
|
||||
const auto iter = content_.glyphs.find(code_point);
|
||||
return iter != content_.glyphs.end()
|
||||
? &iter->second
|
||||
: nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
void swap(font& l, font& r) noexcept {
|
||||
l.swap(r);
|
||||
}
|
||||
|
||||
bool operator==(const font& l, const font& r) noexcept {
|
||||
return l.info() == r.info()
|
||||
&& l.kernings() == r.kernings()
|
||||
&& l.glyphs() == r.glyphs();
|
||||
}
|
||||
|
||||
bool operator!=(const font& l, const font& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
bool operator==(const font::font_info& l, const font::font_info& r) noexcept {
|
||||
return l.atlas_file == r.atlas_file
|
||||
&& l.atlas_size == r.atlas_size
|
||||
&& l.font_size == r.font_size
|
||||
&& l.line_height == r.line_height
|
||||
&& l.glyph_ascent == r.glyph_ascent;
|
||||
}
|
||||
|
||||
bool operator==(const font::glyph_info& l, const font::glyph_info& r) noexcept {
|
||||
return l.offset == r.offset
|
||||
&& l.tex_rect == r.tex_rect
|
||||
&& l.advance == r.advance;
|
||||
}
|
||||
|
||||
bool operator==(const font::content& l, const font::content& r) noexcept {
|
||||
return l.info == r.info
|
||||
&& l.kernings == r.kernings
|
||||
&& l.glyphs == r.glyphs;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d::fonts
|
||||
{
|
||||
bool try_load_font(
|
||||
font& dst,
|
||||
buffer_view src) noexcept
|
||||
{
|
||||
try {
|
||||
return impl::load_font_bmfont(dst, src);
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool try_load_font(
|
||||
font& dst,
|
||||
const input_stream_uptr& src) noexcept
|
||||
{
|
||||
buffer file_data;
|
||||
return streams::try_read_tail(file_data, src)
|
||||
&& try_load_font(dst, file_data);
|
||||
}
|
||||
}
|
||||
17
sources/enduro2d/utils/font_impl/font_impl.hpp
Normal file
17
sources/enduro2d/utils/font_impl/font_impl.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <enduro2d/utils/font.hpp>
|
||||
#include <enduro2d/utils/buffer.hpp>
|
||||
#include <enduro2d/utils/strings.hpp>
|
||||
#include <enduro2d/utils/buffer_view.hpp>
|
||||
|
||||
namespace e2d::fonts::impl
|
||||
{
|
||||
bool load_font_bmfont(font& dst, buffer_view src);
|
||||
}
|
||||
363
sources/enduro2d/utils/font_impl/font_reader_bmfont.cpp
Normal file
363
sources/enduro2d/utils/font_impl/font_reader_bmfont.cpp
Normal file
@@ -0,0 +1,363 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "font_impl.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
bool read_line(str_view content, std::size_t& pos, str_view& line) {
|
||||
if ( pos > content.size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto end_of_line = content.find('\n', pos);
|
||||
if ( end_of_line == str_view::npos ) {
|
||||
end_of_line = content.size();
|
||||
}
|
||||
|
||||
line = content.substr(pos, end_of_line - pos);
|
||||
if ( !line.empty() && line.back() == '\r' ) {
|
||||
line.remove_suffix(1u);
|
||||
}
|
||||
|
||||
pos = end_of_line + 1u;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read_tag(str_view line, std::size_t& pos, str_view& tag) {
|
||||
const auto start = line.find_first_not_of(' ', pos);
|
||||
if ( start == str_view::npos ) {
|
||||
return false;
|
||||
}
|
||||
const auto end = line.find(' ', start);
|
||||
if ( end == str_view::npos || end == line.size() ) {
|
||||
return false;
|
||||
}
|
||||
tag = line.substr(start, end - start);
|
||||
pos = end + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read_key(str_view line, std::size_t& pos, str_view& key) {
|
||||
const auto eq = line.find('=', pos);
|
||||
if ( eq == str_view::npos || eq == 0u || eq == line.size() ) {
|
||||
return false;
|
||||
}
|
||||
const auto last = line.find_last_not_of(' ', eq - 1u);
|
||||
if ( last == str_view::npos ) {
|
||||
return false;
|
||||
}
|
||||
const auto prestart = line.rfind(' ', last);
|
||||
const auto start = prestart == str_view::npos
|
||||
? 0u
|
||||
: prestart + 1u;
|
||||
key = line.substr(start, last - prestart);
|
||||
pos = eq + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool read_value(str_view line, std::size_t& pos, T& value) {
|
||||
const auto start = line.find_first_not_of(' ', pos);
|
||||
if ( start == str_view::npos ) {
|
||||
return false;
|
||||
}
|
||||
auto end = line.find(' ', start);
|
||||
if ( end == str_view::npos ) {
|
||||
end = line.size();
|
||||
}
|
||||
if ( !strings::try_parse(line.substr(start, end - start), value) ) {
|
||||
return false;
|
||||
}
|
||||
pos = end + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read_value(str_view line, std::size_t& pos, str& value) {
|
||||
const auto start = line.find("\"", pos);
|
||||
if ( start == str_view::npos || start == line.size() ) {
|
||||
return false;
|
||||
}
|
||||
const auto end = line.find("\"", start + 1u);
|
||||
if ( end == str_view::npos ) {
|
||||
return false;
|
||||
}
|
||||
value = line.substr(start + 1, end - start - 1u);
|
||||
pos = end + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// info face="Arial-Black" size=32 bold=0 italic=0 charset=""
|
||||
// unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=2,2
|
||||
bool parse_info_line(str_view line, font::content& font_content) {
|
||||
str_view key;
|
||||
std::size_t pos = 0u;
|
||||
while ( read_key(line, pos, key) ) {
|
||||
if ( key == "size" ) {
|
||||
if ( !read_value(line, pos, font_content.info.font_size) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// common lineHeight=54 base=35 scaleW=512 scaleH=512 pages=1 packed=0
|
||||
bool parse_common_line(str_view line, font::content& font_content) {
|
||||
str_view key;
|
||||
std::size_t pos = 0u;
|
||||
while ( read_key(line, pos, key) ) {
|
||||
if ( key == "lineHeight" ) {
|
||||
if ( !read_value(line, pos, font_content.info.line_height) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "base" ) {
|
||||
if ( !read_value(line, pos, font_content.info.glyph_ascent) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "scaleW" ) {
|
||||
if ( !read_value(line, pos, font_content.info.atlas_size.x) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "scaleH" ) {
|
||||
if ( !read_value(line, pos, font_content.info.atlas_size.y) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "pages" ) {
|
||||
u32 pages = 0u;
|
||||
if ( !read_value(line, pos, pages) || pages > 1u ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// page id=0 file="arial.png"
|
||||
bool parse_page_line(str_view line, font::content& font_content) {
|
||||
str_view key;
|
||||
std::size_t pos = 0u;
|
||||
while ( read_key(line, pos, key) ) {
|
||||
if ( key == "id" ) {
|
||||
u32 id = 0u;
|
||||
if ( !read_value(line, pos, id) || id > 0 ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "file" ) {
|
||||
if ( !read_value(line, pos, font_content.info.atlas_file) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// chars count=95
|
||||
bool parse_chars_line(str_view line, font::content& font_content) {
|
||||
str_view key;
|
||||
std::size_t pos = 0u;
|
||||
while ( read_key(line, pos, key) ) {
|
||||
if ( key == "count" ) {
|
||||
std::size_t count = 0u;
|
||||
if ( !read_value(line, pos, count) ) {
|
||||
return false;
|
||||
}
|
||||
font_content.glyphs.reserve(count);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// char id=123 x=2 y=2 width=38 height=54
|
||||
// xoffset=0 yoffset=-3 xadvance=12 page=0 chnl=0
|
||||
bool parse_char_line(str_view line, font::content& font_content) {
|
||||
u32 code_point = 0;
|
||||
font::glyph_info glyph;
|
||||
|
||||
str_view key;
|
||||
std::size_t pos = 0u;
|
||||
while ( read_key(line, pos, key) ) {
|
||||
if ( key == "id" ) {
|
||||
if ( !read_value(line, pos, code_point) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "x" ) {
|
||||
if ( !read_value(line, pos, glyph.tex_rect.position.x) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "y" ) {
|
||||
if ( !read_value(line, pos, glyph.tex_rect.position.y) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "width" ) {
|
||||
if ( !read_value(line, pos, glyph.tex_rect.size.x) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "height" ) {
|
||||
if ( !read_value(line, pos, glyph.tex_rect.size.y) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "xoffset" ) {
|
||||
if ( !read_value(line, pos, glyph.offset.x) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "yoffset" ) {
|
||||
if ( !read_value(line, pos, glyph.offset.y) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "xadvance" ) {
|
||||
if ( !read_value(line, pos, glyph.advance) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "page" ) {
|
||||
u32 page = 0;
|
||||
if ( !read_value(line, pos, page) || page > 0 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
font_content.glyphs.insert_or_assign(
|
||||
code_point,
|
||||
std::move(glyph));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// kernings count=343
|
||||
bool parse_kernings_line(str_view line, font::content& font_content) {
|
||||
str_view key;
|
||||
std::size_t pos = 0u;
|
||||
while ( read_key(line, pos, key) ) {
|
||||
if ( key == "count" ) {
|
||||
std::size_t count = 0u;
|
||||
if ( !read_value(line, pos, count) ) {
|
||||
return false;
|
||||
}
|
||||
font_content.kernings.reserve(count);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// kerning first=1043 second=1071 amount=-1
|
||||
bool parse_kerning_line(str_view line, font::content& font_content) {
|
||||
u32 first = 0;
|
||||
u32 second = 0;
|
||||
i32 amount = 0;
|
||||
|
||||
str_view key;
|
||||
std::size_t pos = 0u;
|
||||
while ( read_key(line, pos, key) ) {
|
||||
if ( key == "first" ) {
|
||||
if ( !read_value(line, pos, first) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "second" ) {
|
||||
if ( !read_value(line, pos, second) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( key == "amount" ) {
|
||||
if ( !read_value(line, pos, amount) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
font_content.kernings.insert_or_assign(
|
||||
(static_cast<u64>(first) << 32) | static_cast<u64>(second),
|
||||
amount);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d::fonts::impl
|
||||
{
|
||||
bool load_font_bmfont(font& dst, buffer_view src) {
|
||||
const auto text_src = str_view{
|
||||
reinterpret_cast<const char*>(src.data()),
|
||||
src.size()};
|
||||
|
||||
font::content font_content;
|
||||
|
||||
str_view line;
|
||||
std::size_t pos = 0u;
|
||||
while ( read_line(text_src, pos, line) ) {
|
||||
str_view tag;
|
||||
std::size_t tag_pos = 0u;
|
||||
if ( !read_tag(line, tag_pos, tag) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
line.remove_prefix(tag_pos);
|
||||
|
||||
if ( tag == "info" ) {
|
||||
if ( !parse_info_line(line, font_content) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( tag == "common" ) {
|
||||
if ( !parse_common_line(line, font_content) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( tag == "page" ) {
|
||||
if ( !parse_page_line(line, font_content) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( tag == "chars" ) {
|
||||
if ( !parse_chars_line(line, font_content) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( tag == "char" ) {
|
||||
if ( !parse_char_line(line, font_content) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( tag == "kernings" ) {
|
||||
if ( !parse_kernings_line(line, font_content) ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( tag == "kerning" ) {
|
||||
if ( !parse_kerning_line(line, font_content) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto& glyph : font_content.glyphs ) {
|
||||
glyph.second.offset.y =
|
||||
0 -
|
||||
glyph.second.offset.y -
|
||||
glyph.second.tex_rect.size.y;
|
||||
glyph.second.tex_rect.position.y =
|
||||
font_content.info.atlas_size.y -
|
||||
glyph.second.tex_rect.position.y -
|
||||
glyph.second.tex_rect.size.y;
|
||||
}
|
||||
|
||||
bool info_valid = !font_content.info.atlas_file.empty()
|
||||
&& font_content.info.atlas_size.x > 0u
|
||||
&& font_content.info.atlas_size.y > 0u
|
||||
&& font_content.info.font_size > 0u
|
||||
&& font_content.info.line_height > 0u
|
||||
&& font_content.info.font_size > 0u
|
||||
&& font_content.info.glyph_ascent > 0u;
|
||||
|
||||
bool glyphs_valid = true;
|
||||
for ( const auto& glyph : font_content.glyphs ) {
|
||||
const v2u& mst = glyph.second.tex_rect.position + glyph.second.tex_rect.size;
|
||||
glyphs_valid = glyphs_valid && math::inside(b2u(font_content.info.atlas_size), mst);
|
||||
}
|
||||
|
||||
if ( !info_valid || !glyphs_valid ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dst = font(font_content);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ namespace
|
||||
|
||||
image_data_format image_format_from_stb_channels(u32 channels) noexcept {
|
||||
switch ( channels ) {
|
||||
case 1: return image_data_format::l8;
|
||||
case 1: return image_data_format::a8;
|
||||
case 2: return image_data_format::la8;
|
||||
case 3: return image_data_format::rgb8;
|
||||
case 4: return image_data_format::rgba8;
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace
|
||||
|
||||
bool stb_check_save_image_format(image_data_format format) noexcept {
|
||||
switch ( format ) {
|
||||
case image_data_format::l8:
|
||||
case image_data_format::a8:
|
||||
case image_data_format::la8:
|
||||
case image_data_format::rgb8:
|
||||
case image_data_format::rgba8:
|
||||
@@ -56,7 +56,7 @@ namespace
|
||||
|
||||
int stb_channels_from_image_format(image_data_format format) noexcept {
|
||||
switch ( format ) {
|
||||
case image_data_format::l8: return 1;
|
||||
case image_data_format::a8: return 1;
|
||||
case image_data_format::la8: return 2;
|
||||
case image_data_format::rgb8: return 3;
|
||||
case image_data_format::rgba8: return 4;
|
||||
|
||||
@@ -48,6 +48,10 @@ TEST_CASE("color") {
|
||||
c /= color(0.1f,0.2f,0.3f,0.4f);
|
||||
REQUIRE(c == color(0.5f,0.6f,0.7f,0.8f));
|
||||
}
|
||||
{
|
||||
REQUIRE(make_vec3(color(0.1f,0.2f,0.3f,0.4f)) == v3f(0.1f,0.2f,0.3f));
|
||||
REQUIRE(make_vec4(color(0.1f,0.2f,0.3f,0.4f)) == v4f(0.1f,0.2f,0.3f, 0.4f));
|
||||
}
|
||||
{
|
||||
REQUIRE(color(0.1f,0.2f,0.3f,0.4f) + 0.1f == color(0.2f,0.3f,0.4f,0.5f));
|
||||
REQUIRE(color(0.1f,0.2f,0.3f,0.4f) - 0.1f == color(0.0f,0.1f,0.2f,0.3f));
|
||||
|
||||
@@ -50,6 +50,10 @@ TEST_CASE("color32") {
|
||||
c /= color32(2,3,6,7);
|
||||
REQUIRE(c == color32(40,50,40,20));
|
||||
}
|
||||
{
|
||||
REQUIRE(make_vec3(color32(10,20,30,40)) == vec3<u8>(10,20,30));
|
||||
REQUIRE(make_vec4(color32(10,20,30,40)) == vec4<u8>(10,20,30,40));
|
||||
}
|
||||
{
|
||||
REQUIRE(color32(10,20,30,40) + 10 == color32(20,30,40,50));
|
||||
REQUIRE(color32(10,20,30,40) - 10 == color32(0,10,20,30));
|
||||
|
||||
66
untests/sources/untests_utils/font.cpp
Normal file
66
untests/sources/untests_utils/font.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "_utils.hpp"
|
||||
using namespace e2d;
|
||||
|
||||
namespace
|
||||
{
|
||||
const char* const mini_fnt = R"fnt(
|
||||
info face ="Arial" size= 50 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=0,0
|
||||
common lineHeight =58 base= 49 scaleW = 512 scaleH=512 pages=1 packed=0
|
||||
page id=0 file="arial.png"
|
||||
|
||||
chars count=3
|
||||
char id=32 x=342 y=38 width=0 height=0 xoffset=0 yoffset=46 xadvance=14 page=0 chnl=0
|
||||
char id=33 x=448 y=386 width=10 height=40 xoffset=5 yoffset=10 xadvance=14 page=0 chnl=0
|
||||
char id=34 x=394 y=306 width=18 height=18 xoffset=3 yoffset=8 xadvance=18 page=0 chnl=0
|
||||
|
||||
kernings count=2
|
||||
kerning first=1059 second=1081 amount=-1
|
||||
kerning first=1043 second=1071 amount=-1
|
||||
)fnt";
|
||||
|
||||
const char* const mini_bad_fnt = R"fnt(
|
||||
info face="Arial" size=HELLO bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=0,0
|
||||
)fnt";
|
||||
}
|
||||
|
||||
TEST_CASE("font") {
|
||||
{
|
||||
font f;
|
||||
REQUIRE_FALSE(fonts::try_load_font(f, buffer(mini_bad_fnt, std::strlen(mini_bad_fnt))));
|
||||
REQUIRE_FALSE(fonts::try_load_font(f, make_memory_stream(buffer(mini_bad_fnt, std::strlen(mini_bad_fnt)))));
|
||||
}
|
||||
{
|
||||
font f, f2;
|
||||
REQUIRE(fonts::try_load_font(f, buffer(mini_fnt, std::strlen(mini_fnt))));
|
||||
REQUIRE(fonts::try_load_font(f2, make_memory_stream(buffer(mini_fnt, std::strlen(mini_fnt)))));
|
||||
REQUIRE(f == f2);
|
||||
|
||||
REQUIRE(f.info().atlas_file == "arial.png");
|
||||
REQUIRE(f.info().atlas_size == v2u(512,512));
|
||||
REQUIRE(f.info().font_size == 50);
|
||||
REQUIRE(f.info().line_height == 58);
|
||||
REQUIRE(f.info().glyph_ascent == 49);
|
||||
|
||||
REQUIRE(f.glyphs().size() == 3);
|
||||
REQUIRE_FALSE(f.find_glyph(100500));
|
||||
REQUIRE(f.find_glyph(33));
|
||||
{
|
||||
// char id=33 x=448 y=386 width=10 height=40 xoffset=5 yoffset=10 xadvance=14 page=0 chnl=0
|
||||
font::glyph_info c;
|
||||
c.offset = v2i(5, -50);
|
||||
c.tex_rect = b2u(448, 86, 10, 40);
|
||||
c.advance = 14;
|
||||
REQUIRE(*f.find_glyph(33) == c);
|
||||
}
|
||||
|
||||
REQUIRE(f.kernings().size() == 2);
|
||||
REQUIRE(f.get_kerning(1059, 1081) == -1);
|
||||
REQUIRE(f.get_kerning(1059, 100500) == 0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user