aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/Graphics/FontData.cpp
blob: 1b66b121ba31a7ca80d1fe607d56eff3df067dff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "FontData.h"
#define STB_TRUETYPE_IMPLEMENTATION
#include "../3rdparty/stb/stb_truetype.h"
#include <stdio.h>

namespace jin
{
namespace graphics
{

    FontData* FontData::createFontData(const unsigned char* data, unsigned int size)
    {
        FontData* font = nullptr;
        try
        {
            font = new FontData(data, size);
            return font;
        }
        catch (...)
        {
            return nullptr;
        }
    }

    FontData::FontData(const unsigned char* d, unsigned int s)
    {
        raw.size = s;
        raw.data = (unsigned char*)malloc(s);
        memcpy(raw.data, d, s);
        if (!stbtt_InitFont(&info, (const unsigned char*)raw.data, 0))
        {
            delete raw.data;
            throw 0;
        }
        /* push default fontsize */
        pushFontsize(FONT_SIZE);
    }

    FontData::~FontData()
    {
        free(raw.data);
    }

    /*
    * (0, 0)
    *    +--------------+ ascent
    *    |  +--------+  |
    *    |  |        |  |
    *    |  | bitmap |  |
    *    +--|--------|--+ baseline
    *    |  +--------+  |
    *    +--|-----------+ decent
    *       |           |
    * leftSideBearing   |
    *                   |
    *             advanceWidth
    */
    void FontData::getVMetrics(int* baseline, int* descent)
    {
        float scale = scales.back();
        int ascent;
        stbtt_GetFontVMetrics(&info, &ascent, descent, 0);
        *baseline = (int)(ascent*scale) + 1; // slight adjustment
        *descent = *baseline - (int)(*descent*scale) + 1;
    }

    void FontData::getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing)
    {
        float scale = scales.back();
        int adw, lsb;
        stbtt_GetCodepointHMetrics(&info, codepoint, &adw, &lsb);
        *advanceWidth = (int)(adw*scale);
        *leftSideBearing = (int)(lsb*scale);
    }

    void FontData::pushFontsize(unsigned int fs)
    {
        float sc = stbtt_ScaleForPixelHeight(&info, fs);
        scales.push_back(sc);
    }

    void FontData::popFontsize()
    {
        /* always keep default font size on the bottom of stack */
        if(scales.size() > 1)
            scales.pop_back();
    }

    Channel* FontData::getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const
    {
        float scale = scales.back();
        Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff);
        return bitmap;
    }

    Color* FontData::getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const
    {
        float scale = scales.back();
        Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff);
        int w = *width, h = *height;
        //int xo = *xoff, yo = *yoff;
        Color* bitmap32 = new Color[w*h];
        for (int y = 0; y < h; ++y)
        {
            for (int x = 0; x < w; ++x)
            {
                bitmap32[x + y * w].set(0xff, 0xff, 0xff, bitmap[x + y * w]);
            }
        }
        free(bitmap);
        return bitmap32;
    }

}
}