Upload files to "/"
This commit is contained in:
27
CMakeLists.txt
Normal file
27
CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
include_directories(../font)
|
||||
#include_directories(SYSTEM ${FREETYPE_INCLUDE_DIRS})
|
||||
|
||||
set(TTF_SOURCES glue.c schrift.c)
|
||||
|
||||
set(TTF_INCLUDE_FILES allegro5/allegro_schrift.h)
|
||||
|
||||
set_our_header_properties(${TTF_INCLUDE_FILES})
|
||||
|
||||
#configure_file(
|
||||
# allegro5/internal/aintern_ttf_cfg.h.cmake
|
||||
# ${PROJECT_BINARY_DIR}/include/allegro5/internal/aintern_ttf_cfg.h
|
||||
# )
|
||||
|
||||
add_our_addon_library(allegro_ttf
|
||||
AllegroTTF-${ALLEGRO_SOVERSION}
|
||||
"${TTF_SOURCES};${TTF_INCLUDE_FILES}"
|
||||
"-DALLEGRO_TTF_SRC"
|
||||
"${FONT_LINK_WITH};${TTF_LIBRARIES}"
|
||||
)
|
||||
|
||||
install_our_headers(${TTF_INCLUDE_FILES})
|
||||
|
||||
add_addon(ttf)
|
||||
|
||||
#-----------------------------------------------------------------------------#
|
||||
# vi: set ts=8 sts=4 sw=4 et:
|
||||
198
glue.c
Normal file
198
glue.c
Normal file
@@ -0,0 +1,198 @@
|
||||
#define ALLEGRO_INTERNAL_UNSTABLE
|
||||
|
||||
#include "allegro5/allegro.h"
|
||||
#include "allegro5/internal/aintern.h"
|
||||
#include "allegro5/internal/aintern_vector.h"
|
||||
|
||||
#include "allegro5/allegro_schrift.h"
|
||||
#include "allegro5/internal/aintern_font.h"
|
||||
#include "allegro5/internal/aintern_dtor.h"
|
||||
#include "allegro5/internal/aintern_system.h"
|
||||
#include "allegro5/internal/aintern_exitfunc.h"
|
||||
|
||||
#include "schrift.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
ALLEGRO_DEBUG_CHANNEL("font")
|
||||
#define CANI_ALLEGRO_SCHRIFT_VER 1
|
||||
|
||||
/* globals */
|
||||
static bool ttf_inited;
|
||||
|
||||
// Destroys the source bitmap and replaces it with a version
|
||||
// expanded downward by add no. of pixels.
|
||||
ALLEGRO_BITMAP *grow_bitmap(ALLEGRO_BITMAP *bmp, uint16_t add) {
|
||||
const uint32_t h = al_get_bitmap_height(bmp) + add;
|
||||
ALLEGRO_BITMAP *tgt = al_get_target_bitmap();
|
||||
ALLEGRO_BITMAP *grown = al_create_bitmap(al_get_bitmap_width(bmp), h);
|
||||
al_set_target_bitmap(grown);
|
||||
al_draw_bitmap(bmp, 0, 0, 0);
|
||||
al_set_target_bitmap(tgt);
|
||||
al_destroy_bitmap(bmp);
|
||||
return grown;
|
||||
}
|
||||
|
||||
ALLEGRO_FONT *al_load_ttf_font_f(ALLEGRO_FILE *file,
|
||||
char const *filename, int size, int flags)
|
||||
{
|
||||
#define CLEANUP free(filebuf); if (gtex) al_destroy_bitmap(gtex); al_set_target_bitmap(tgt)
|
||||
#define FAIL CLEANUP; return NULL
|
||||
|
||||
const int64_t filesize = al_fsize(file); // this should not be signed!
|
||||
if (filesize < 1) {
|
||||
ALLEGRO_ERROR("Can't load font %s: file is empty or unknown size.\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
void *filebuf = malloc(filesize);
|
||||
|
||||
SFT sft = { .flags = SFT_DOWNWARD_Y };
|
||||
ALLEGRO_FONT *f = NULL;
|
||||
ALLEGRO_BITMAP *gtex = NULL;
|
||||
int result = 0;
|
||||
ALLEGRO_BITMAP *tgt = al_get_target_bitmap();
|
||||
|
||||
ALLEGRO_CONFIG* system_cfg = al_get_system_config();
|
||||
const char* cache_text_str =
|
||||
al_get_config_value(system_cfg, "ttf", "cache_text");
|
||||
if (!cache_text_str) {
|
||||
ALLEGRO_ERROR("No characters defined in cache_text, no glyphs to bake!\n", filename);
|
||||
FAIL;
|
||||
}
|
||||
|
||||
// read font file
|
||||
#define chunksize 1024
|
||||
size_t offset = 0;
|
||||
while (!al_feof(file)) {
|
||||
if (al_ferror(file)) {
|
||||
ALLEGRO_ERROR("Can't load font %s: error reading file.\n", filename);
|
||||
FAIL;
|
||||
}
|
||||
|
||||
offset += al_fread(file, (uint8_t*)filebuf + offset, chunksize);
|
||||
}
|
||||
sft.xScale = size;
|
||||
sft.yScale = size;
|
||||
sft.font = sft_loadmem(filebuf, filesize);
|
||||
if (!sft.font) {
|
||||
ALLEGRO_ERROR("Can't load font %s: schrift error, is it a valid format?\n", filename);
|
||||
FAIL;
|
||||
}
|
||||
|
||||
// convert glyphs into textures todo
|
||||
gtex = al_create_bitmap(2048, 2048);
|
||||
uint16_t woff = 1, hoff = 0;
|
||||
al_set_target_bitmap(gtex);
|
||||
al_clear_to_color(al_map_rgba(0, 0, 0, 255));
|
||||
unsigned int i = 0;
|
||||
while (cache_text_str[i] != '\0') {
|
||||
ALLEGRO_INFO("generating glyph for %c\n", cache_text_str[i]);
|
||||
SFT_Glyph glyph;
|
||||
SFT_GMetrics geom;
|
||||
SFT_Image img;
|
||||
ALLEGRO_LOCKED_REGION *block = NULL;
|
||||
|
||||
if (0 > sft_lookup(&sft, cache_text_str[i], &glyph)) goto glyph_lookup_fail;
|
||||
ALLEGRO_INFO("got glyph\n");
|
||||
if (0 > sft_gmetrics(&sft, glyph, &geom)) goto glyph_lookup_fail;
|
||||
ALLEGRO_INFO("got geom\n");
|
||||
block =
|
||||
al_lock_bitmap_region(gtex, woff, hoff, geom.minWidth, geom.minHeight,
|
||||
ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8, ALLEGRO_LOCK_WRITEONLY);
|
||||
ALLEGRO_INFO("got lock\n");
|
||||
img.width = geom.minWidth;
|
||||
img.height = geom.minHeight;
|
||||
img.pixels = block->data;
|
||||
if (0 > sft_render(&sft, glyph, img)) goto glyph_lookup_fail;
|
||||
ALLEGRO_INFO("got raster\n");
|
||||
al_unlock_bitmap(gtex);
|
||||
ALLEGRO_INFO("unlock\n");
|
||||
|
||||
i++; continue;
|
||||
|
||||
glyph_lookup_fail:
|
||||
ALLEGRO_ERROR("Failure generating glyph %c in %s!\n", cache_text_str[i], filename);
|
||||
FAIL;
|
||||
}
|
||||
|
||||
// debug
|
||||
al_save_bitmap("schrift_test.png", gtex);
|
||||
|
||||
// convert texture to bitmap font
|
||||
const unsigned int ranges_size = i*2;
|
||||
int ranges[ranges_size];
|
||||
i = 0;
|
||||
while (i < ranges_size) {
|
||||
ranges[i] = (unsigned char)cache_text_str[i];
|
||||
ranges[i+1] = (unsigned char)cache_text_str[i];
|
||||
i++; i++;
|
||||
}
|
||||
f = al_grab_font_from_bitmap(gtex, ranges_size, ranges);
|
||||
f->dtor_item = _al_register_destructor(_al_dtor_list, "ttf_font", f,
|
||||
(void (*)(void *))al_destroy_font);
|
||||
ALLEGRO_DEBUG("Font %s loaded.\n", filename);
|
||||
|
||||
CLEANUP;
|
||||
return f;
|
||||
}
|
||||
|
||||
ALLEGRO_FONT *al_load_ttf_font(char const *filename, int size, int flags)
|
||||
{
|
||||
ALLEGRO_FILE *f;
|
||||
ALLEGRO_FONT *font;
|
||||
ASSERT(filename);
|
||||
|
||||
f = al_fopen(filename, "rb");
|
||||
if (!f) {
|
||||
ALLEGRO_ERROR("Unable to open file for reading: %s\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
font = al_load_ttf_font_f(f, filename, size, flags);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
bool al_init_ttf_addon(void)
|
||||
{
|
||||
if (ttf_inited) {
|
||||
ALLEGRO_WARN("TTF addon already initialised.\n");
|
||||
return true;
|
||||
}
|
||||
al_register_font_loader(".ttf", al_load_ttf_font);
|
||||
_al_add_exit_func(al_shutdown_ttf_addon, "al_shutdown_ttf_addon");
|
||||
ttf_inited = true;
|
||||
return ttf_inited;
|
||||
}
|
||||
|
||||
bool al_is_ttf_addon_initialized(void)
|
||||
{
|
||||
return ttf_inited;
|
||||
}
|
||||
|
||||
void al_shutdown_ttf_addon(void)
|
||||
{
|
||||
if (!ttf_inited) {
|
||||
ALLEGRO_ERROR("TTF addon not initialised.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
al_register_font_loader(".ttf", NULL);
|
||||
|
||||
ttf_inited = false;
|
||||
}
|
||||
|
||||
uint32_t al_get_allegro_ttf_version(void)
|
||||
{
|
||||
return CANI_ALLEGRO_SCHRIFT_VER;
|
||||
}
|
||||
|
||||
ALLEGRO_FONT *al_load_ttf_font_stretch(char const *filename, int w, int h, int flags) {
|
||||
ALLEGRO_WARN("Unimplemented function\n");
|
||||
al_load_ttf_font(filename, h, flags);
|
||||
}
|
||||
|
||||
ALLEGRO_FONT *al_load_ttf_font_stretch_f(ALLEGRO_FILE *file, char const *filename, int w, int h, int flags) {
|
||||
ALLEGRO_WARN("Unimplemented function\n");
|
||||
al_load_ttf_font_f(file, filename, h, flags);
|
||||
}
|
||||
95
schrift.h
Normal file
95
schrift.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* This file is part of libschrift.
|
||||
*
|
||||
* © 2019-2022 Thomas Oltmann and contributors
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef SCHRIFT_H
|
||||
#define SCHRIFT_H 1
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
#include <stdint.h> /* uint_fast32_t, uint_least32_t */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SFT_DOWNWARD_Y 0x01
|
||||
|
||||
typedef struct SFT SFT;
|
||||
typedef struct SFT_Font SFT_Font;
|
||||
typedef uint_least32_t SFT_UChar; /* Guaranteed to be compatible with char32_t. */
|
||||
typedef uint_fast32_t SFT_Glyph;
|
||||
typedef struct SFT_LMetrics SFT_LMetrics;
|
||||
typedef struct SFT_GMetrics SFT_GMetrics;
|
||||
typedef struct SFT_Kerning SFT_Kerning;
|
||||
typedef struct SFT_Image SFT_Image;
|
||||
|
||||
struct SFT
|
||||
{
|
||||
SFT_Font *font;
|
||||
double xScale;
|
||||
double yScale;
|
||||
double xOffset;
|
||||
double yOffset;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct SFT_LMetrics
|
||||
{
|
||||
double ascender;
|
||||
double descender;
|
||||
double lineGap;
|
||||
};
|
||||
|
||||
struct SFT_GMetrics
|
||||
{
|
||||
double advanceWidth;
|
||||
double leftSideBearing;
|
||||
int yOffset;
|
||||
int minWidth;
|
||||
int minHeight;
|
||||
};
|
||||
|
||||
struct SFT_Kerning
|
||||
{
|
||||
double xShift;
|
||||
double yShift;
|
||||
};
|
||||
|
||||
struct SFT_Image
|
||||
{
|
||||
void *pixels;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
const char *sft_version(void);
|
||||
|
||||
SFT_Font *sft_loadmem (const void *mem, size_t size);
|
||||
SFT_Font *sft_loadfile(const char *filename);
|
||||
void sft_freefont(SFT_Font *font);
|
||||
|
||||
int sft_lmetrics(const SFT *sft, SFT_LMetrics *metrics);
|
||||
int sft_lookup (const SFT *sft, SFT_UChar codepoint, SFT_Glyph *glyph);
|
||||
int sft_gmetrics(const SFT *sft, SFT_Glyph glyph, SFT_GMetrics *metrics);
|
||||
int sft_kerning (const SFT *sft, SFT_Glyph leftGlyph, SFT_Glyph rightGlyph,
|
||||
SFT_Kerning *kerning);
|
||||
int sft_render (const SFT *sft, SFT_Glyph glyph, SFT_Image image);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user