Skip to main content
Join the official 2019 Python Developers SurveyStart the survey!

Bitmap Font Library

Project description

yup
===

[![Build Status](https://travis-ci.org/esoma/yup.svg?branch=master)](
https://travis-ci.org/esoma/yup
)

yup is a [library](#libyup) and [application](#yupify) for generating and using
bitmap fonts from standard font formats.

build
-----

[libyup](#libyup) and [yupify](#yupify) have been built and tested with gcc and
clang on windows and linux for x86 and x64.

To build [library](#libyup) and [application](#yupify):
```
make all
```

To run tests:
```
make test
```

The resulting applications will be found in the /build directory.

#### dependencies

- [yupify](#yupify) depends on freetype (tested with 2.6.3)
- [libyup](#libyup) has no dependencies

yupify
------

**yupify** is an application that converts font files (.ttf, .otf, etc) into
a [format](#yup-format) that the [yup library](#libyup) can read.

```
Usage: yupify font_file_path font_size page_size padding < characters
```

- *font_file_path* is the path to the font file you want to convert
- *font_size* is the pixel size that you want to render the font at
- *page_size* is the the size of the textures to render the font to (both width
and height)
- *padding* is the number of pixels between rendered glyphs
- *characters* is a string of utf8 encoded characters that you want to render

For convenience, the [utf](..utf) directory has some pre-defined
character lists that you can use, most commonly
[utf/ascii-common.txt](../blob/master/utf/ascii-common.txt). Also, a python
script, [utf/generate.py](..utf/generate.py), is provided to easily
generate new character lists.

stdout yields the converted font so it is easiest to add
```... > font-name.yup``` to save the file.

libyup
------

**libyup** is a shared library that provides a simple API for reading the
[yup format](#yup-format).

A short example that does nothing but read the contents of a file:
```c
#include <stdlib.h>
#include <stdio.h>
#include "yup.h"
int main(int argc, const char* argv[])
{
FILE* file = fopen("font.yup", "rb");
if (!file){ return EXIT_FAILURE; }
YupFont* font = yup_new();
if (!font){ return EXIT_FAILURE; }
YupPrResult yup_result = yup_parse(font, file);
if (yup_result != YUP_PR_OKAY){ return EXIT_FAILURE; }
fclose(file);
yup_delete(font);
return EXIT_SUCCESS;
}
```

### API

```c
Yup* yup_new();
```
**yup_new** returns a pointer to a new **YupFont** object or *NULL* if it was
unable to, like **malloc**.

```c
void yup_delete(YupFont* font);
```
**yup_delete** frees a **YupFont** object previously created by **yup_new**,
like **free**.

```c
typedef int (*YupGetChar)(void*);
typedef int (*YupGetIsEnd)(void*);
YupParseResult yup_parse(Yup*, void*, YupGetChar, YupGetIsEnd);
```
**yup_parse** reads a stream (*void**) using the supplied **YupGetChar** and
**YupGetIsEnd** and parses that stream into a **YupFont** object. Note that the
**YupFont** object should not have any previous data in it.

**YupGetChar** is passed the stream and should return a single character. If
there is an error or no more characters it should return YUP_STREAM_ERROR.

**YupGetIsEnd** is passed the stream and should return 0 if the stream still
has data and 1 if the stream is finished. If there are is an error it should
return YUP_STREAM_ERROR.

```c
const char* yup_parse_result_string(YupParseResult result)
```
**yup_parse_result_string** gets a human readable string for why a call to
**yup_parse** failed.

```c
struct YupFont
{
uint32_t size;
uint32_t page_size;
YupGlyph* glyphs;
YupPage* pages;
};
```
A **YupFont** object is created using the **yup_new** function and deleted using
the **yup_delete** function.

- *size* is the size the font was rendered at
- *page_size* is the size of the textures that the font was rendered too (both
width and height)
- *glyphs* is a linked list of glyphs
- *pages* is a linked list of pages

```c
struct YupGlyph
{
YupGlyph* next;
uint32_t index;
uint64_t dimensions[2];
int64_t offset[2];
int64_t advance;
size_t page_index;
float top_left_uv[2];
float bottom_right_uv[2];
YupKerning* kerning;
};
```
A **YupGlyph** is an item in a linked list of glyphs and their properties.

- *next* is the next **YupGlyph** in the linked list
- *index* is the utf8 encoding of the character represented by the glyph
- *dimensions* is the pixel width and height of the rendered glyph
- *offset* is the number of pixels to render the glyph from the origin
- *advance* is the number of pixels to advance the cursor when rendering the
glyph
- *page_index* is the index of the **YupPage** which the glyph has been rendered
to
- *top_left_uv* is the position of the top left corner of the glyph in the
page's texture represented in uv coordinates
- *bottom_right_uv* is the position of the bottom right corner of the glyph in
the page's texture represented in uv coordinates
- *kerning* is a linked list of kerning properties

```c
struct YupKerning
{
YupKerning* next;
uint32_t glyph_index;
int64_t offset[2];
};
```
A **YupKerning** is an item in a linked list which describes the special kerning
conditions between two glyphs.

- *next* is the next **YupKerning** in the linked list
- *glyph_index* is the utf8 encoding of the character to the left of the parent
when the *offset* should be applied to the parent glyph when rendering
- *offset* is the number of additional pixels to render the glyph from the
origin

```c
struct YupPage
{
YupPage* next;
size_t index;
unsigned char* texture;
};
```
A **YupPage** is an item in al inked list of pages and their properties.

- *next* is the next **YupPage** in the linked list
- *index* is a unique id for the page which can match against a **YupGlyph**'s
*page_index* property
- *texture* is a bitmap texture in which each byte represents an alpha value,
the data is stored by row such that each row is a *page_size* in length and
there are *page_size* rows

yup format
----------
The format for yup files is a mix of text and binary data. Conceptually it's
more like instructions for a state machine, rather than a straight file format.
It's designed such that it is easy to open and inspect in a standard text
editor.

python
------
A python API can be found in the /py directory. You will need to generate a part
of the API using:

```c
make python
```

Generating the API requires [toe](https://github.com/esoma/toe/) and for the
*TOE* environment variable to be set to the toe executable script.

The [library](#libyup) will need to be on the path for the API to work.

examples
--------
An [example](/py/yup/examples/gl.py) for rendering via OpenGL is provided in the
python API.

Project details


Release history Release notifications

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page