/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes. * Copyright (C) 2010-2011 - Hans-Kristian Arntzen * * Some code herein may be based on code found in BSNES. * * SSNES is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with SSNES. * If not, see . */ #include "fonts.h" #include "file.h" #include #include #include #include #include FT_FREETYPE_H struct font_renderer { FT_Library lib; FT_Face face; }; font_renderer_t *font_renderer_new(const char *font_path, unsigned font_size) { (void)font_size; font_renderer_t *handle = calloc(1, sizeof(*handle)); if (!handle) goto error; FT_Error err = FT_Init_FreeType(&handle->lib); if (err) goto error; err = FT_New_Face(handle->lib, font_path, 0, &handle->face); if (err) goto error; err = FT_Set_Pixel_Sizes(handle->face, 0, font_size); if (err) goto error; return handle; error: if (handle) { if (handle->face) FT_Done_Face(handle->face); if (handle->lib) FT_Done_FreeType(handle->lib); free(handle); } return NULL; } void font_renderer_msg(font_renderer_t *handle, const char *msg, struct font_output_list *output) { output->head = NULL; FT_GlyphSlot slot = handle->face->glyph; struct font_output *cur = NULL; size_t len = strlen(msg); int off_x = 0, off_y = 0; for (size_t i = 0; i < len; i++) { FT_Error err = FT_Load_Char(handle->face, msg[i], FT_LOAD_RENDER); if (!err) { struct font_output *tmp = calloc(1, sizeof(*tmp)); if (!tmp) break; tmp->output = malloc(slot->bitmap.pitch * slot->bitmap.rows); if (!tmp->output) { free(tmp); break; } memcpy(tmp->output, slot->bitmap.buffer, slot->bitmap.pitch * slot->bitmap.rows); tmp->width = slot->bitmap.width; tmp->height = slot->bitmap.rows; tmp->pitch = slot->bitmap.pitch; tmp->off_x = off_x + slot->bitmap_left; tmp->off_y = off_y + slot->bitmap_top - slot->bitmap.rows; tmp->next = NULL; if (i == 0) output->head = tmp; else cur->next = tmp; cur = tmp; } off_x += slot->advance.x >> 6; off_y += slot->advance.y >> 6; } } void font_renderer_free_output(struct font_output_list *output) { struct font_output *itr = output->head; struct font_output *tmp = NULL; while (itr != NULL) { free(itr->output); tmp = itr; itr = itr->next; free(tmp); } output->head = NULL; } void font_renderer_free(font_renderer_t *handle) { if (handle->face) FT_Done_Face(handle->face); if (handle->lib) FT_Done_FreeType(handle->lib); } // Not the cleanest way to do things for sure, but should hopefully work ... :) #if defined(_WIN32) static const char *font_paths[] = { "C:\\Windows\\Fonts\\consola.ttf", "C:\\Windows\\Fonts\\verdana.ttf", #elif defined(__APPLE__) static const char *font_paths[] = { "/Library/Fonts/Microsoft/Candara.ttf", #else static const char *font_paths[] = { "/usr/share/fonts/TTF/DejaVuSansMono.ttf", "/usr/share/fonts/TTF/DejaVuSans.ttf", #endif "osd-font.ttf", // Magic font to search for, useful for distribution. }; // Highly OS/platform dependent. const char *font_renderer_get_default_font(void) { for (unsigned i = 0; i < sizeof(font_paths) / sizeof(font_paths[0]); i++) { if (path_file_exists(font_paths[i])) return font_paths[i]; } return NULL; }