(VITA) USE STB FONT

This commit is contained in:
frangarcj 2016-09-19 14:14:11 +02:00
parent df4a1cc502
commit d46a40e3c4
13 changed files with 11045 additions and 11756 deletions

View File

@ -210,13 +210,13 @@ else ifeq ($(platform), vita)
EXT_INTER_TARGET := $(TARGET_NAME)_$(platform).elf
MACHDEP := -DVITA
WANT_ZLIB := 1
INCLUDE += -I$(VITASDK)/arm-vita-eabi/include/freetype2 -Ideps/libvita2d/include
INCLUDE += -Ideps/libvita2d/include
INCLUDE += -Ideps/zlib
PLATCFLAGS := -mthumb -mfloat-abi=hard -ffast-math -fsingle-precision-constant -mword-relocations
LIBS += -lSceKernel_stub -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub\
-lSceSysmodule_stub -lSceCtrl_stub -lSceAudio_stub -lSceFiber_stub\
-lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub \
-lSceMotion_stub -lSceAppMgr_stub -lfreetype -lpng -lm -lc
-lSceMotion_stub -lSceAppMgr_stub -lpng -lm -lc
PLATEXTRA := deps/libvita2d/shader/compiled/clear_v_gxp.o \
deps/libvita2d/shader/compiled/clear_f_gxp.o \
@ -247,6 +247,7 @@ else ifeq ($(platform), vita)
HAVE_OVERLAY := 1
HAVE_MATERIALUI := 1
HAVE_XMB := 1
HAVE_STB_FONT :=1
RARCH_CONSOLE = 1
HAVE_THREADS := 1
endif
@ -365,6 +366,10 @@ ifeq ($(HAVE_XMB), 1)
CFLAGS += -DHAVE_XMB
endif
ifeq ($(HAVE_STB_FONT), 1)
CFLAGS += -DHAVE_STB_FONT
endif
ifeq ($(HAVE_LANGEXTRA), 1)
CFLAGS += -DHAVE_LANGEXTRA
endif

View File

@ -1,37 +0,0 @@
#ifndef BIN_PACKING_2D_H
#define BIN_PACKING_2D_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct bp2d_position {
int x, y;
} bp2d_position;
typedef struct bp2d_size {
int w, h;
} bp2d_size;
typedef struct bp2d_rectangle {
int x, y, w, h;
} bp2d_rectangle;
typedef struct bp2d_node {
struct bp2d_node *left;
struct bp2d_node *right;
bp2d_rectangle rect;
int filled;
} bp2d_node;
bp2d_node *bp2d_create(const bp2d_rectangle *rect);
void bp2d_free(bp2d_node *node);
// 1 success, 0 failure
int bp2d_insert(bp2d_node *node, const bp2d_size *in_size, bp2d_position *out_pos, bp2d_node **out_node);
int bp2d_delete(bp2d_node *root, bp2d_node *node);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,34 +0,0 @@
#ifndef INT_HTAB_H
#define INT_HTAB_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#define INT_HTAB_MAX_LOAD (70) // over 100
typedef struct int_htab_entry {
unsigned int key;
void *value;
} int_htab_entry;
typedef struct int_htab {
size_t size;
size_t used;
int_htab_entry *entries;
} int_htab;
int_htab *int_htab_create(size_t size);
void int_htab_free(int_htab *htab);
int int_htab_insert(int_htab *htab, unsigned int key, void *value);
void *int_htab_find(const int_htab *htab, unsigned int key);
int int_htab_erase(const int_htab *htab, unsigned int key);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,47 +0,0 @@
#ifndef TEXTURE_ATLAS_H
#define TEXTURE_ATLAS_H
#include "vita2d.h"
#include "bin_packing_2d.h"
#include "int_htab.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct texture_atlas_entry_data {
int bitmap_left;
int bitmap_top;
int advance_x;
int advance_y;
int glyph_size;
} texture_atlas_entry_data;
typedef struct texture_atlas_htab_entry {
bp2d_rectangle rect;
texture_atlas_entry_data data;
} atlas_htab_entry;
typedef struct texture_atlas {
vita2d_texture *texture;
bp2d_node *bp_root;
int_htab *htab;
} texture_atlas;
texture_atlas *texture_atlas_create(int width, int height, SceGxmTextureFormat format);
void texture_atlas_free(texture_atlas *atlas);
int texture_atlas_insert(texture_atlas *atlas, unsigned int character,
const bp2d_size *size,
const texture_atlas_entry_data *data,
bp2d_position *inserted_pos);
int texture_atlas_exists(texture_atlas *atlas, unsigned int character);
int texture_atlas_get(texture_atlas *atlas, unsigned int character,
bp2d_rectangle *rect, texture_atlas_entry_data *data);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -101,25 +101,6 @@ void vita2d_draw_texture_tint_part_scale(const vita2d_texture *texture, float x,
void vita2d_draw_texture_tint_scale_rotate_hotspot(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, float center_x, float center_y, unsigned int color);
void vita2d_draw_texture_tint_scale_rotate(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, unsigned int color);
vita2d_font *vita2d_load_font_file(const char *filename);
vita2d_font *vita2d_load_font_mem(const void *buffer, unsigned int size);
void vita2d_free_font(vita2d_font *font);
int vita2d_font_draw_text(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text);
int vita2d_font_draw_textf(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text, ...);
void vita2d_font_text_dimensions(vita2d_font *font, unsigned int size, const char *text, int *width, int *height);
int vita2d_font_text_width(vita2d_font *font, unsigned int size, const char *text);
int vita2d_font_text_height(vita2d_font *font, unsigned int size, const char *text);
/* PGF functions are weak imports at the moment, they have to be resolved manually */
vita2d_pgf *vita2d_load_default_pgf();
void vita2d_free_pgf(vita2d_pgf *font);
int vita2d_pgf_draw_text(vita2d_pgf *font, int x, int y, unsigned int color, float scale, const char *text);
int vita2d_pgf_draw_textf(vita2d_pgf *font, int x, int y, unsigned int color, float scale, const char *text, ...);
void vita2d_pgf_text_dimensions(vita2d_pgf *font, float scale, const char *text, int *width, int *height);
int vita2d_pgf_text_width(vita2d_pgf *font, float scale, const char *text);
int vita2d_pgf_text_height(vita2d_pgf *font, float scale, const char *text);
/** ADVANCED **/
void vita2d_texture_set_wvp(float x, float y, float width, float height);
void vita2d_texture_set_program();

View File

@ -1,106 +0,0 @@
#include <stdlib.h>
#include "bin_packing_2d.h"
bp2d_node *bp2d_create(const bp2d_rectangle *rect)
{
bp2d_node *node = malloc(sizeof(*node));
if (!node)
return NULL;
node->left = NULL;
node->right = NULL;
node->rect.x = rect->x;
node->rect.y = rect->y;
node->rect.w = rect->w;
node->rect.h = rect->h;
node->filled = 0;
return node;
}
void bp2d_free(bp2d_node *node)
{
if (node) {
if (node->left) {
bp2d_free(node->left);
}
if (node->right) {
bp2d_free(node->right);
}
free(node);
}
}
int bp2d_insert(bp2d_node *node, const bp2d_size *in_size, bp2d_position *out_pos, bp2d_node **out_node)
{
if (node->left != NULL || node->right != NULL) {
int ret = bp2d_insert(node->left, in_size, out_pos, out_node);
if (ret == 0) {
return bp2d_insert(node->right, in_size, out_pos, out_node);
}
return ret;
} else {
if (node->filled)
return 0;
if (in_size->w > node->rect.w || in_size->h > node->rect.h)
return 0;
if (in_size->w == node->rect.w && in_size->h == node->rect.h) {
out_pos->x = node->rect.x;
out_pos->y = node->rect.y;
node->filled = 1;
if (out_node)
*out_node = node;
return 1;
}
int dw = node->rect.w - in_size->w;
int dh = node->rect.h - in_size->h;
bp2d_rectangle left_rect, right_rect;
if (dw > dh) {
left_rect.x = node->rect.x;
left_rect.y = node->rect.y;
left_rect.w = in_size->w;
left_rect.h = node->rect.h;
right_rect.x = node->rect.x + in_size->w;
right_rect.y = node->rect.y;
right_rect.w = node->rect.w - in_size->w;
right_rect.h = node->rect.h;
} else {
left_rect.x = node->rect.x;
left_rect.y = node->rect.y;
left_rect.w = node->rect.w;
left_rect.h = in_size->h;
right_rect.x = node->rect.x;
right_rect.y = node->rect.y + in_size->h;
right_rect.w = node->rect.w;
right_rect.h = node->rect.h - in_size->h;
}
node->left = bp2d_create(&left_rect);
node->right = bp2d_create(&right_rect);
return bp2d_insert(node->left, in_size, out_pos, out_node);
}
}
int bp2d_delete(bp2d_node *root, bp2d_node *node)
{
if (root == NULL || node == NULL)
return 0;
else if (root == node) {
bp2d_free(root->left);
bp2d_free(root->right);
root->left = NULL;
root->right = NULL;
root->filled = 0;
return 1;
}
return bp2d_delete(root->left, node) || bp2d_delete(root->right, node);
}

View File

@ -1,124 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "int_htab.h"
static inline unsigned int FNV_1a(unsigned int key)
{
unsigned char *bytes = (unsigned char *)&key;
unsigned int hash = 2166136261U;
hash = (16777619U * hash) ^ bytes[0];
hash = (16777619U * hash) ^ bytes[1];
hash = (16777619U * hash) ^ bytes[2];
hash = (16777619U * hash) ^ bytes[3];
return hash;
}
int_htab *int_htab_create(size_t size)
{
int_htab *htab = malloc(sizeof(*htab));
if (!htab)
return NULL;
htab->size = size;
htab->used = 0;
htab->entries = malloc(htab->size * sizeof(*htab->entries));
memset(htab->entries, 0, htab->size * sizeof(*htab->entries));
return htab;
}
void int_htab_free(int_htab *htab)
{
int i;
for (i = 0; i < htab->size; i++) {
if (htab->entries[i].value != NULL)
free(htab->entries[i].value);
}
free(htab);
}
void int_htab_resize(int_htab *htab, unsigned int new_size)
{
int i;
int_htab_entry *old_entries;
unsigned int old_size;
old_entries = htab->entries;
old_size = htab->size;
htab->size = new_size;
htab->used = 0;
htab->entries = malloc(new_size * sizeof(*htab->entries));
memset(htab->entries, 0, new_size * sizeof(*htab->entries));
for (i = 0; i < old_size; i++) {
if (old_entries[i].value != NULL) {
int_htab_insert(htab, old_entries[i].key, old_entries[i].value);
}
}
free(old_entries);
}
int int_htab_insert(int_htab *htab, unsigned int key, void *value)
{
if (value == NULL)
return 0;
/* Calculate the current load factor */
if (((htab->used + 1)*100)/htab->size > INT_HTAB_MAX_LOAD) {
int_htab_resize(htab, 2*htab->size);
}
unsigned int mask = htab->size - 1;
unsigned int idx = FNV_1a(key) & mask;
/* Open addressing, linear probing */
while (htab->entries[idx].value != NULL) {
idx = (idx + 1) & mask;
}
htab->entries[idx].key = key;
htab->entries[idx].value = value;
htab->used++;
return 1;
}
void *int_htab_find(const int_htab *htab, unsigned int key)
{
unsigned int mask = htab->size - 1;
unsigned int idx = FNV_1a(key) & mask;
/* Open addressing, linear probing */
while (htab->entries[idx].key != key && htab->entries[idx].value != NULL) {
idx = (idx + 1) & mask;
}
/* Found the key */
if (htab->entries[idx].key == key) {
return htab->entries[idx].value;
}
return NULL;
}
int int_htab_erase(const int_htab *htab, unsigned int key)
{
unsigned int mask = htab->size - 1;
unsigned int idx = FNV_1a(key) & mask;
/* Open addressing, linear probing */
while (htab->entries[idx].key != key && htab->entries[idx].value != NULL) {
idx = (idx + 1) & mask;
}
/* Found the key */
if (htab->entries[idx].key == key) {
htab->entries[idx].value = NULL;
return 1;
}
return 0;
}

View File

@ -1,86 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "texture_atlas.h"
texture_atlas *texture_atlas_create(int width, int height, SceGxmTextureFormat format)
{
texture_atlas *atlas = malloc(sizeof(*atlas));
if (!atlas)
return NULL;
bp2d_rectangle rect;
rect.x = 0;
rect.y = 0;
rect.w = width;
rect.h = height;
atlas->texture = vita2d_create_empty_texture_format(width,
height,
format);
if (!atlas->texture) {
free(atlas);
return NULL;
}
atlas->bp_root = bp2d_create(&rect);
atlas->htab = int_htab_create(256);
vita2d_texture_set_filters(atlas->texture,
SCE_GXM_TEXTURE_FILTER_POINT,
SCE_GXM_TEXTURE_FILTER_LINEAR);
return atlas;
}
void texture_atlas_free(texture_atlas *atlas)
{
vita2d_free_texture(atlas->texture);
bp2d_free(atlas->bp_root);
int_htab_free(atlas->htab);
free(atlas);
}
int texture_atlas_insert(texture_atlas *atlas, unsigned int character,
const bp2d_size *size,
const texture_atlas_entry_data *data,
bp2d_position *inserted_pos)
{
atlas_htab_entry *entry;
bp2d_node *new_node;
if (!bp2d_insert(atlas->bp_root, size, inserted_pos, &new_node))
return 0;
entry = malloc(sizeof(*entry));
entry->rect.x = inserted_pos->x;
entry->rect.y = inserted_pos->y;
entry->rect.w = size->w;
entry->rect.h = size->h;
entry->data = *data;
if (!int_htab_insert(atlas->htab, character, entry)) {
bp2d_delete(atlas->bp_root, new_node);
return 0;
}
return 1;
}
int texture_atlas_exists(texture_atlas *atlas, unsigned int character)
{
return int_htab_find(atlas->htab, character) != NULL;
}
int texture_atlas_get(texture_atlas *atlas, unsigned int character,
bp2d_rectangle *rect, texture_atlas_entry_data *data)
{
atlas_htab_entry *entry = int_htab_find(atlas->htab, character);
if (!entry)
return 0;
*rect = entry->rect;
*data = entry->data;
return 1;
}

View File

@ -1,354 +0,0 @@
#include <psp2/kernel/sysmem.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <freetype2/ft2build.h>
#include FT_CACHE_H
#include FT_FREETYPE_H
#include "vita2d.h"
#include "texture_atlas.h"
#include "bin_packing_2d.h"
#include "utils.h"
#include "shared.h"
#define ATLAS_DEFAULT_W 512
#define ATLAS_DEFAULT_H 512
typedef enum {
VITA2D_LOAD_FONT_FROM_FILE,
VITA2D_LOAD_FONT_FROM_MEM
} vita2d_load_font_from;
typedef struct vita2d_font {
vita2d_load_font_from load_from;
union {
char *filename;
struct {
const void *font_buffer;
unsigned int buffer_size;
};
};
FT_Library ftlibrary;
FTC_Manager ftcmanager;
FTC_CMapCache cmapcache;
FTC_ImageCache imagecache;
texture_atlas *atlas;
} vita2d_font;
static FT_Error ftc_face_requester(FTC_FaceID face_id, FT_Library library,
FT_Pointer request_data, FT_Face *face)
{
vita2d_font *font = (vita2d_font *)face_id;
FT_Error error = FT_Err_Cannot_Open_Resource;
if (font->load_from == VITA2D_LOAD_FONT_FROM_FILE) {
error = FT_New_Face(
font->ftlibrary,
font->filename,
0,
face);
} else if (font->load_from == VITA2D_LOAD_FONT_FROM_MEM) {
error = FT_New_Memory_Face(
font->ftlibrary,
font->font_buffer,
font->buffer_size,
0,
face);
}
return error;
}
vita2d_font *vita2d_load_font_file(const char *filename)
{
FT_Error error;
vita2d_font *font = malloc(sizeof(*font));
if (!font)
return NULL;
error = FT_Init_FreeType(&font->ftlibrary);
if (error != FT_Err_Ok) {
free(font);
return NULL;
}
error = FTC_Manager_New(
font->ftlibrary,
0, /* use default */
0, /* use default */
0, /* use default */
&ftc_face_requester, /* use our requester */
NULL, /* user data */
&font->ftcmanager);
if (error != FT_Err_Ok) {
FT_Done_FreeType(font->ftlibrary);
free(font);
return NULL;
}
font->filename = strdup(filename);
FTC_CMapCache_New(font->ftcmanager, &font->cmapcache);
FTC_ImageCache_New(font->ftcmanager, &font->imagecache);
font->load_from = VITA2D_LOAD_FONT_FROM_FILE;
font->atlas = texture_atlas_create(ATLAS_DEFAULT_W, ATLAS_DEFAULT_H,
SCE_GXM_TEXTURE_FORMAT_U8_R111);
return font;
}
vita2d_font *vita2d_load_font_mem(const void *buffer, unsigned int size)
{
FT_Error error;
vita2d_font *font = malloc(sizeof(*font));
if (!font)
return NULL;
error = FT_Init_FreeType(&font->ftlibrary);
if (error != FT_Err_Ok) {
free(font);
return NULL;
}
error = FTC_Manager_New(
font->ftlibrary,
0, /* use default */
0, /* use default */
0, /* use default */
&ftc_face_requester, /* use our requester */
NULL, /* user data */
&font->ftcmanager);
if (error != FT_Err_Ok) {
FT_Done_FreeType(font->ftlibrary);
free(font);
return NULL;
}
font->font_buffer = buffer;
font->buffer_size = size;
FTC_CMapCache_New(font->ftcmanager, &font->cmapcache);
FTC_ImageCache_New(font->ftcmanager, &font->imagecache);
font->load_from = VITA2D_LOAD_FONT_FROM_MEM;
font->atlas = texture_atlas_create(ATLAS_DEFAULT_W, ATLAS_DEFAULT_H,
SCE_GXM_TEXTURE_FORMAT_U8_R111);
return font;
}
void vita2d_free_font(vita2d_font *font)
{
if (font) {
FTC_FaceID face_id = (FTC_FaceID)font;
FTC_Manager_RemoveFaceID(font->ftcmanager, face_id);
FTC_Manager_Done(font->ftcmanager);
if (font->load_from == VITA2D_LOAD_FONT_FROM_FILE) {
free(font->filename);
}
texture_atlas_free(font->atlas);
free(font);
}
}
static int atlas_add_glyph(texture_atlas *atlas, unsigned int glyph_index,
const FT_BitmapGlyph bitmap_glyph, int glyph_size)
{
int ret;
int i, j;
bp2d_position position;
void *texture_data;
unsigned int tex_width;
const FT_Bitmap *bitmap = &bitmap_glyph->bitmap;
unsigned int w = bitmap->width;
unsigned int h = bitmap->rows;
unsigned char buffer[w * h];
bp2d_size size = {
bitmap->width,
bitmap->rows
};
texture_atlas_entry_data data = {
bitmap_glyph->left,
bitmap_glyph->top,
bitmap_glyph->root.advance.x,
bitmap_glyph->root.advance.y,
glyph_size
};
ret = texture_atlas_insert(atlas, glyph_index, &size, &data,
&position);
if (!ret)
return 0;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO) {
buffer[i*w + j] =
(bitmap->buffer[i*bitmap->pitch + j/8] & (1 << (7 - j%8)))
? 0xFF : 0;
} else if (bitmap->pixel_mode == FT_PIXEL_MODE_GRAY) {
buffer[i*w + j] = bitmap->buffer[i*bitmap->pitch + j];
}
}
}
texture_data = vita2d_texture_get_datap(atlas->texture);
tex_width = vita2d_texture_get_width(atlas->texture);
for (i = 0; i < size.h; i++) {
memcpy(texture_data + (position.x + (position.y + i) * tex_width),
buffer + i * size.w, size.w);
}
return 1;
}
static int generic_font_draw_text(vita2d_font *font, int draw,
int *height, int x, int y,
unsigned int color,
unsigned int size,
const char *text)
{
const FT_ULong flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL;
FT_Face face;
FT_Int charmap_index;
FT_Glyph glyph;
FT_UInt glyph_index;
FT_Bool use_kerning;
FTC_FaceID face_id = (FTC_FaceID)font;
FT_UInt previous = 0;
vita2d_texture *tex = font->atlas->texture;
unsigned int character;
int start_x = x;
int max_x = 0;
int pen_x = x;
int pen_y = y;
bp2d_rectangle rect;
texture_atlas_entry_data data;
FTC_ScalerRec scaler;
scaler.face_id = face_id;
scaler.width = size;
scaler.height = size;
scaler.pixel = 1;
FTC_Manager_LookupFace(font->ftcmanager, face_id, &face);
use_kerning = FT_HAS_KERNING(face);
charmap_index = FT_Get_Charmap_Index(face->charmap);
while (text[0]) {
character = utf8_character(&text);
if (character == '\n') {
if (pen_x > max_x)
max_x = pen_x;
pen_x = start_x;
pen_y += size;
continue;
}
glyph_index = FTC_CMapCache_Lookup(font->cmapcache,
(FTC_FaceID)font,
charmap_index,
character);
if (use_kerning && previous && glyph_index) {
FT_Vector delta;
FT_Get_Kerning(face, previous, glyph_index,
FT_KERNING_DEFAULT, &delta);
pen_x += delta.x >> 6;
}
if (!texture_atlas_get(font->atlas, glyph_index, &rect, &data)) {
FTC_ImageCache_LookupScaler(font->imagecache,
&scaler,
flags,
glyph_index,
&glyph,
NULL);
if (!atlas_add_glyph(font->atlas, glyph_index,
(FT_BitmapGlyph)glyph, size)) {
continue;
}
if (!texture_atlas_get(font->atlas, glyph_index, &rect, &data))
continue;
}
const float draw_scale = size / (float)data.glyph_size;
if (draw) {
vita2d_draw_texture_tint_part_scale(tex,
pen_x + data.bitmap_left * draw_scale,
pen_y - data.bitmap_top * draw_scale,
rect.x, rect.y, rect.w, rect.h,
draw_scale,
draw_scale,
color);
}
pen_x += (data.advance_x >> 16) * draw_scale;
}
if (pen_x > max_x)
max_x = pen_x;
if (height)
*height = pen_y + size - y;
return max_x - x;
}
int vita2d_font_draw_text(vita2d_font *font, int x, int y, unsigned int color,
unsigned int size, const char *text)
{
return generic_font_draw_text(font, 1, NULL, x, y, color, size, text);
}
int vita2d_font_draw_textf(vita2d_font *font, int x, int y, unsigned int color,
unsigned int size, const char *text, ...)
{
char buf[1024];
va_list argptr;
va_start(argptr, text);
vsnprintf(buf, sizeof(buf), text, argptr);
va_end(argptr);
return vita2d_font_draw_text(font, x, y, color, size, buf);
}
void vita2d_font_text_dimensions(vita2d_font *font, unsigned int size,
const char *text, int *width, int *height)
{
int w;
w = generic_font_draw_text(font, 0, height, 0, 0, 0, size, text);
if (width)
*width = w;
}
int vita2d_font_text_width(vita2d_font *font, unsigned int size, const char *text)
{
int width;
vita2d_font_text_dimensions(font, size, text, &width, NULL);
return width;
}
int vita2d_font_text_height(vita2d_font *font, unsigned int size, const char *text)
{
int height;
vita2d_font_text_dimensions(font, size, text, NULL, &height);
return height;
}

View File

@ -1,230 +0,0 @@
#include <psp2/pgf.h>
#include <psp2/kernel/sysmem.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <malloc.h>
#include <math.h>
#include "vita2d.h"
#include "texture_atlas.h"
#include "bin_packing_2d.h"
#include "utils.h"
#include "shared.h"
#define ATLAS_DEFAULT_W 512
#define ATLAS_DEFAULT_H 512
typedef struct vita2d_pgf {
SceFontLibHandle lib_handle;
SceFontHandle font_handle;
texture_atlas *atlas;
float vsize;
} vita2d_pgf;
static void *pgf_alloc_func(void *userdata, unsigned int size)
{
return memalign(sizeof(int), size + sizeof(int));
}
static void pgf_free_func(void *userdata, void *p)
{
free(p);
}
vita2d_pgf *vita2d_load_default_pgf()
{
unsigned int error;
SceFontInfo fontinfo;
vita2d_pgf *font = malloc(sizeof(*font));
if (!font)
return NULL;
SceFontNewLibParams params = {
font,
1,
NULL,
pgf_alloc_func,
pgf_free_func,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
font->lib_handle = sceFontNewLib(&params, &error);
if (error != 0) {
free(font);
return NULL;
}
font->font_handle = sceFontOpen(font->lib_handle, 0, 0, &error);
if (error != 0) {
sceFontDoneLib(font->lib_handle);
free(font);
return NULL;
}
sceFontGetFontInfo(font->font_handle, &fontinfo);
font->vsize = (fontinfo.fontStyle.fontV / fontinfo.fontStyle.fontVRes)
* SCREEN_DPI;
font->atlas = texture_atlas_create(ATLAS_DEFAULT_W, ATLAS_DEFAULT_H,
SCE_GXM_TEXTURE_FORMAT_U8_R111);
return font;
}
void vita2d_free_pgf(vita2d_pgf *font)
{
if (font) {
sceFontClose(font->font_handle);
sceFontDoneLib(font->lib_handle);
texture_atlas_free(font->atlas);
free(font);
}
}
static int atlas_add_glyph_pgf(vita2d_pgf *font, unsigned int character)
{
SceFontCharInfo char_info;
bp2d_position position;
void *texture_data;
vita2d_texture *tex = font->atlas->texture;
if (sceFontGetCharInfo(font->font_handle, character, &char_info) < 0)
return 0;
bp2d_size size = {
char_info.bitmapWidth,
char_info.bitmapHeight
};
texture_atlas_entry_data data = {
char_info.bitmapLeft,
char_info.bitmapTop,
char_info.sfp26AdvanceH,
char_info.sfp26AdvanceV,
0
};
if (!texture_atlas_insert(font->atlas, character, &size, &data,
&position))
return 0;
texture_data = vita2d_texture_get_datap(tex);
SceFontGlyphImage glyph_image;
glyph_image.pixelFormat = SCE_FONT_PIXELFORMAT_8;
glyph_image.xPos64 = position.x << 6;
glyph_image.yPos64 = position.y << 6;
glyph_image.bufWidth = vita2d_texture_get_width(tex);
glyph_image.bufHeight = vita2d_texture_get_height(tex);
glyph_image.bytesPerLine = vita2d_texture_get_stride(tex);
glyph_image.pad = 0;
glyph_image.bufferPtr = (unsigned int)texture_data;
return sceFontGetCharGlyphImage(font->font_handle, character, &glyph_image) == 0;
}
int generic_pgf_draw_text(vita2d_pgf *font, int draw, int *height,
int x, int y, unsigned int color, float scale,
const char *text)
{
unsigned int character;
bp2d_rectangle rect;
texture_atlas_entry_data data;
vita2d_texture *tex = font->atlas->texture;
int start_x = x;
int max_x = 0;
int pen_x = x;
int pen_y = y;
while (*text) {
character = utf8_character(&text);
if (character == '\n') {
if (pen_x > max_x)
max_x = pen_x;
pen_x = start_x;
pen_y += font->vsize * scale;
continue;
}
if (!texture_atlas_get(font->atlas, character, &rect, &data)) {
if (!atlas_add_glyph_pgf(font, character)) {
continue;
}
if (!texture_atlas_get(font->atlas, character,
&rect, &data))
continue;
}
if (draw) {
vita2d_draw_texture_tint_part_scale(tex,
pen_x + data.bitmap_left * scale,
pen_y - data.bitmap_top * scale,
rect.x, rect.y, rect.w, rect.h,
scale,
scale,
color);
}
pen_x += (data.advance_x >> 6) * scale;
}
if (pen_x > max_x)
max_x = pen_x;
if (height)
*height = pen_y + font->vsize * scale - y;
return max_x - x;
}
int vita2d_pgf_draw_text(vita2d_pgf *font, int x, int y,
unsigned int color, float scale,
const char *text)
{
return generic_pgf_draw_text(font, 1, NULL, x, y, color, scale, text);
}
int vita2d_pgf_draw_textf(vita2d_pgf *font, int x, int y,
unsigned int color, float scale,
const char *text, ...)
{
char buf[1024];
va_list argptr;
va_start(argptr, text);
vsnprintf(buf, sizeof(buf), text, argptr);
va_end(argptr);
return vita2d_pgf_draw_text(font, x, y, color, scale, buf);
}
void vita2d_pgf_text_dimensions(vita2d_pgf *font, float scale,
const char *text, int *width, int *height)
{
int w;
w = generic_pgf_draw_text(font, 0, height, 0, 0, 0, scale, text);
if (width)
*width = w;
}
int vita2d_pgf_text_width(vita2d_pgf *font, float scale, const char *text)
{
int width;
vita2d_pgf_text_dimensions(font, scale, text, &width, NULL);
return width;
}
int vita2d_pgf_text_height(vita2d_pgf *font, float scale, const char *text)
{
int height;
vita2d_pgf_text_dimensions(font, scale, text, NULL, &height);
return height;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -337,11 +337,6 @@ VIDEO DRIVER
#include "../deps/libvita2d/source/vita2d_texture.c"
#include "../deps/libvita2d/source/vita2d_draw.c"
#include "../deps/libvita2d/source/utils.c"
#include "../deps/libvita2d/source/vita2d_font.c"
#include "../deps/libvita2d/source/vita2d_pgf.c"
#include "../deps/libvita2d/source/bin_packing_2d.c"
#include "../deps/libvita2d/source/texture_atlas.c"
#include "../deps/libvita2d/source/int_htab.c"
#include "../gfx/drivers/vita2d_gfx.c"
#elif defined(_3DS)