|
|
@ -91,7 +91,7 @@ |
|
|
|
// #include "stb_rect_pack.h" -- optional, but you really want it
|
|
|
|
// #include "stb_rect_pack.h" -- optional, but you really want it
|
|
|
|
// stbtt_PackBegin()
|
|
|
|
// stbtt_PackBegin()
|
|
|
|
// stbtt_PackSetOversample() -- for improved quality on small fonts
|
|
|
|
// stbtt_PackSetOversample() -- for improved quality on small fonts
|
|
|
|
// stbtt_PackFontRanges()
|
|
|
|
// stbtt_PackFontRanges() -- pack and renders
|
|
|
|
// stbtt_PackEnd()
|
|
|
|
// stbtt_PackEnd()
|
|
|
|
// stbtt_GetPackedQuad()
|
|
|
|
// stbtt_GetPackedQuad()
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -493,6 +493,7 @@ typedef struct |
|
|
|
} stbtt_packedchar; |
|
|
|
} stbtt_packedchar; |
|
|
|
|
|
|
|
|
|
|
|
typedef struct stbtt_pack_context stbtt_pack_context; |
|
|
|
typedef struct stbtt_pack_context stbtt_pack_context; |
|
|
|
|
|
|
|
typedef struct stbtt_fontinfo stbtt_fontinfo; |
|
|
|
|
|
|
|
|
|
|
|
extern int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); |
|
|
|
extern int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); |
|
|
|
// Initializes a packing context stored in the passed-in stbtt_pack_context.
|
|
|
|
// Initializes a packing context stored in the passed-in stbtt_pack_context.
|
|
|
@ -538,6 +539,12 @@ extern int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdat |
|
|
|
// ranges. This will usually create a better-packed bitmap than multiple
|
|
|
|
// ranges. This will usually create a better-packed bitmap than multiple
|
|
|
|
// calls to stbtt_PackFontRange.
|
|
|
|
// calls to stbtt_PackFontRange.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); |
|
|
|
|
|
|
|
extern int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); |
|
|
|
|
|
|
|
// Those functions are called by stbtt_PackFontRanges(). If you want to
|
|
|
|
|
|
|
|
// pack multiple fonts or custom data into a same texture, you may copy
|
|
|
|
|
|
|
|
// the contents of stbtt_PackFontRanges() and create a custom version
|
|
|
|
|
|
|
|
// using those functions.
|
|
|
|
|
|
|
|
|
|
|
|
extern void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); |
|
|
|
extern void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); |
|
|
|
// Oversampling a font increases the quality by allowing higher-quality subpixel
|
|
|
|
// Oversampling a font increases the quality by allowing higher-quality subpixel
|
|
|
@ -2158,6 +2165,7 @@ int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int |
|
|
|
|
|
|
|
|
|
|
|
stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); |
|
|
|
stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pixels) |
|
|
|
STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
|
|
|
|
STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
|
|
|
|
|
|
|
|
|
|
|
|
return 1; |
|
|
|
return 1; |
|
|
@ -2301,41 +2309,19 @@ static float stbtt__oversample_shift(int oversample) |
|
|
|
return (float)-(oversample - 1) / (2.0f * (float)oversample); |
|
|
|
return (float)-(oversample - 1) / (2.0f * (float)oversample); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) |
|
|
|
// rects array must be big enough to accommodate all characters in the given ranges
|
|
|
|
|
|
|
|
int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) |
|
|
|
{ |
|
|
|
{ |
|
|
|
stbtt_fontinfo info; |
|
|
|
int i,j,k; |
|
|
|
float recip_h = 1.0f / spc->h_oversample; |
|
|
|
|
|
|
|
float recip_v = 1.0f / spc->v_oversample; |
|
|
|
|
|
|
|
float sub_x = stbtt__oversample_shift(spc->h_oversample); |
|
|
|
|
|
|
|
float sub_y = stbtt__oversample_shift(spc->v_oversample); |
|
|
|
|
|
|
|
int i,j,k,n, return_value = 1; |
|
|
|
|
|
|
|
stbrp_context *context = (stbrp_context *) spc->pack_info; |
|
|
|
|
|
|
|
stbrp_rect *rects; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// flag all characters as NOT packed
|
|
|
|
|
|
|
|
for (i=0; i < num_ranges; ++i) |
|
|
|
|
|
|
|
for (j=0; j < ranges[i].num_chars_in_range; ++j) |
|
|
|
|
|
|
|
ranges[i].chardata_for_range[j].x0 = |
|
|
|
|
|
|
|
ranges[i].chardata_for_range[j].y0 = |
|
|
|
|
|
|
|
ranges[i].chardata_for_range[j].x1 = |
|
|
|
|
|
|
|
ranges[i].chardata_for_range[j].y1 = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n = 0; |
|
|
|
|
|
|
|
for (i=0; i < num_ranges; ++i) |
|
|
|
|
|
|
|
n += ranges[i].num_chars_in_range; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); |
|
|
|
|
|
|
|
if (rects == NULL) |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index)); |
|
|
|
|
|
|
|
k=0; |
|
|
|
k=0; |
|
|
|
for (i=0; i < num_ranges; ++i) { |
|
|
|
for (i=0; i < num_ranges; ++i) { |
|
|
|
float fh = ranges[i].font_size; |
|
|
|
float fh = ranges[i].font_size; |
|
|
|
float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh); |
|
|
|
float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); |
|
|
|
for (j=0; j < ranges[i].num_chars_in_range; ++j) { |
|
|
|
for (j=0; j < ranges[i].num_chars_in_range; ++j) { |
|
|
|
int x0,y0,x1,y1; |
|
|
|
int x0,y0,x1,y1; |
|
|
|
stbtt_GetCodepointBitmapBoxSubpixel(&info, ranges[i].first_unicode_char_in_range + j, |
|
|
|
int glyph = stbtt_FindGlyphIndex(info,ranges[i].first_unicode_char_in_range + j); |
|
|
|
|
|
|
|
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, |
|
|
|
scale * spc->h_oversample, |
|
|
|
scale * spc->h_oversample, |
|
|
|
scale * spc->v_oversample, |
|
|
|
scale * spc->v_oversample, |
|
|
|
0,0, |
|
|
|
0,0, |
|
|
@ -2346,18 +2332,28 @@ int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int f |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
stbrp_pack_rects(context, rects, k); |
|
|
|
return k; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// rects array must be big enough to accommodate all characters in the given ranges
|
|
|
|
|
|
|
|
int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
float recip_h = 1.0f / spc->h_oversample; |
|
|
|
|
|
|
|
float recip_v = 1.0f / spc->v_oversample; |
|
|
|
|
|
|
|
float sub_x = stbtt__oversample_shift(spc->h_oversample); |
|
|
|
|
|
|
|
float sub_y = stbtt__oversample_shift(spc->v_oversample); |
|
|
|
|
|
|
|
int i,j,k, return_value = 1; |
|
|
|
|
|
|
|
|
|
|
|
k = 0; |
|
|
|
k = 0; |
|
|
|
for (i=0; i < num_ranges; ++i) { |
|
|
|
for (i=0; i < num_ranges; ++i) { |
|
|
|
float fh = ranges[i].font_size; |
|
|
|
float fh = ranges[i].font_size; |
|
|
|
float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh); |
|
|
|
float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); |
|
|
|
for (j=0; j < ranges[i].num_chars_in_range; ++j) { |
|
|
|
for (j=0; j < ranges[i].num_chars_in_range; ++j) { |
|
|
|
stbrp_rect *r = &rects[k]; |
|
|
|
stbrp_rect *r = &rects[k]; |
|
|
|
if (r->was_packed) { |
|
|
|
if (r->was_packed) { |
|
|
|
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; |
|
|
|
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; |
|
|
|
int advance, lsb, x0,y0,x1,y1; |
|
|
|
int advance, lsb, x0,y0,x1,y1; |
|
|
|
int glyph = stbtt_FindGlyphIndex(&info, ranges[i].first_unicode_char_in_range + j); |
|
|
|
int glyph = stbtt_FindGlyphIndex(info, ranges[i].first_unicode_char_in_range + j); |
|
|
|
stbrp_coord pad = (stbrp_coord) spc->padding; |
|
|
|
stbrp_coord pad = (stbrp_coord) spc->padding; |
|
|
|
|
|
|
|
|
|
|
|
// pad on left and top
|
|
|
|
// pad on left and top
|
|
|
@ -2365,12 +2361,12 @@ int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int f |
|
|
|
r->y += pad; |
|
|
|
r->y += pad; |
|
|
|
r->w -= pad; |
|
|
|
r->w -= pad; |
|
|
|
r->h -= pad; |
|
|
|
r->h -= pad; |
|
|
|
stbtt_GetGlyphHMetrics(&info, glyph, &advance, &lsb); |
|
|
|
stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb); |
|
|
|
stbtt_GetGlyphBitmapBox(&info, glyph, |
|
|
|
stbtt_GetGlyphBitmapBox(info, glyph, |
|
|
|
scale * spc->h_oversample, |
|
|
|
scale * spc->h_oversample, |
|
|
|
scale * spc->v_oversample, |
|
|
|
scale * spc->v_oversample, |
|
|
|
&x0,&y0,&x1,&y1); |
|
|
|
&x0,&y0,&x1,&y1); |
|
|
|
stbtt_MakeGlyphBitmapSubpixel(&info, |
|
|
|
stbtt_MakeGlyphBitmapSubpixel(info, |
|
|
|
spc->pixels + r->x + r->y*spc->stride_in_bytes, |
|
|
|
spc->pixels + r->x + r->y*spc->stride_in_bytes, |
|
|
|
r->w - spc->h_oversample+1, |
|
|
|
r->w - spc->h_oversample+1, |
|
|
|
r->h - spc->v_oversample+1, |
|
|
|
r->h - spc->v_oversample+1, |
|
|
@ -2410,6 +2406,40 @@ int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int f |
|
|
|
return return_value; |
|
|
|
return return_value; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
stbtt_fontinfo info; |
|
|
|
|
|
|
|
int i,j,n, return_value = 1; |
|
|
|
|
|
|
|
stbrp_context *context = (stbrp_context *) spc->pack_info; |
|
|
|
|
|
|
|
stbrp_rect *rects; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// flag all characters as NOT packed
|
|
|
|
|
|
|
|
for (i=0; i < num_ranges; ++i) |
|
|
|
|
|
|
|
for (j=0; j < ranges[i].num_chars_in_range; ++j) |
|
|
|
|
|
|
|
ranges[i].chardata_for_range[j].x0 = |
|
|
|
|
|
|
|
ranges[i].chardata_for_range[j].y0 = |
|
|
|
|
|
|
|
ranges[i].chardata_for_range[j].x1 = |
|
|
|
|
|
|
|
ranges[i].chardata_for_range[j].y1 = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n = 0; |
|
|
|
|
|
|
|
for (i=0; i < num_ranges; ++i) |
|
|
|
|
|
|
|
n += ranges[i].num_chars_in_range; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); |
|
|
|
|
|
|
|
if (rects == NULL) |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stbrp_pack_rects(context, rects, n); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return return_value; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, |
|
|
|
int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, |
|
|
|
int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) |
|
|
|
int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) |
|
|
|
{ |
|
|
|
{ |
|
|
|