|
@ -126,7 +126,7 @@ namespace |
|
|
void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size
|
|
|
void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size
|
|
|
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint); |
|
|
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint); |
|
|
const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info); |
|
|
const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info); |
|
|
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = NULL); |
|
|
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = NULL); |
|
|
~FreeTypeFont() { CloseFont(); } |
|
|
~FreeTypeFont() { CloseFont(); } |
|
|
|
|
|
|
|
|
// [Internals]
|
|
|
// [Internals]
|
|
@ -173,6 +173,9 @@ namespace |
|
|
else |
|
|
else |
|
|
RenderMode = FT_RENDER_MODE_NORMAL; |
|
|
RenderMode = FT_RENDER_MODE_NORMAL; |
|
|
|
|
|
|
|
|
|
|
|
if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor) |
|
|
|
|
|
LoadFlags |= FT_LOAD_COLOR; |
|
|
|
|
|
|
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -253,7 +256,7 @@ namespace |
|
|
return ft_bitmap; |
|
|
return ft_bitmap; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void FreeTypeFont::BlitGlyph(const FT_Bitmap* ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table) |
|
|
void FreeTypeFont::BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table) |
|
|
{ |
|
|
{ |
|
|
IM_ASSERT(ft_bitmap != NULL); |
|
|
IM_ASSERT(ft_bitmap != NULL); |
|
|
const uint32_t w = ft_bitmap->width; |
|
|
const uint32_t w = ft_bitmap->width; |
|
@ -268,13 +271,18 @@ namespace |
|
|
if (multiply_table == NULL) |
|
|
if (multiply_table == NULL) |
|
|
{ |
|
|
{ |
|
|
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) |
|
|
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) |
|
|
memcpy(dst, src, w); |
|
|
{ |
|
|
|
|
|
for (uint32_t x = 0; x < w; x++) |
|
|
|
|
|
dst[x] = IM_COL32(255, 255, 255, src[x]); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) |
|
|
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) |
|
|
|
|
|
{ |
|
|
for (uint32_t x = 0; x < w; x++) |
|
|
for (uint32_t x = 0; x < w; x++) |
|
|
dst[x] = multiply_table[src[x]]; |
|
|
dst[x] = IM_COL32(255, 255, 255, multiply_table[src[x]]); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
@ -290,9 +298,41 @@ namespace |
|
|
{ |
|
|
{ |
|
|
if ((x & 7) == 0) |
|
|
if ((x & 7) == 0) |
|
|
bits = *bits_ptr++; |
|
|
bits = *bits_ptr++; |
|
|
dst[x] = (bits & 0x80) ? color1 : color0; |
|
|
dst[x] = IM_COL32(255, 255, 255, (bits & 0x80) ? color1 : color0); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
case FT_PIXEL_MODE_BGRA: |
|
|
|
|
|
{ |
|
|
|
|
|
#define DE_MULTIPLY(color, alpha) (ImU32)(255.0f * (float)color / (float)alpha + 0.5f) |
|
|
|
|
|
|
|
|
|
|
|
if (multiply_table == NULL) |
|
|
|
|
|
{ |
|
|
|
|
|
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) |
|
|
|
|
|
{ |
|
|
|
|
|
for (uint32_t x = 0; x < w; x++) |
|
|
|
|
|
dst[x] = IM_COL32( |
|
|
|
|
|
DE_MULTIPLY(src[x * 4 + 2], src[x * 4 + 3]), |
|
|
|
|
|
DE_MULTIPLY(src[x * 4 + 1], src[x * 4 + 3]), |
|
|
|
|
|
DE_MULTIPLY(src[x * 4], src[x * 4 + 3]), |
|
|
|
|
|
src[x * 4 + 3]); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) |
|
|
|
|
|
{ |
|
|
|
|
|
for (uint32_t x = 0; x < w; x++) |
|
|
|
|
|
dst[x] = IM_COL32( |
|
|
|
|
|
multiply_table[DE_MULTIPLY(src[x * 4 + 2], src[x * 4 + 3])], |
|
|
|
|
|
multiply_table[DE_MULTIPLY(src[x * 4 + 1], src[x * 4 + 3])], |
|
|
|
|
|
multiply_table[DE_MULTIPLY(src[x * 4], src[x * 4 + 3])], |
|
|
|
|
|
multiply_table[src[x * 4 + 3]]); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#undef DE_MULTIPLY |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
default: |
|
|
default: |
|
@ -318,7 +358,7 @@ struct ImFontBuildSrcGlyphFT |
|
|
{ |
|
|
{ |
|
|
GlyphInfo Info; |
|
|
GlyphInfo Info; |
|
|
uint32_t Codepoint; |
|
|
uint32_t Codepoint; |
|
|
unsigned char* BitmapData; // Point within one of the dst_tmp_bitmap_buffers[] array
|
|
|
unsigned int* BitmapData; // Point within one of the dst_tmp_bitmap_buffers[] array
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
struct ImFontBuildSrcDataFT |
|
|
struct ImFontBuildSrcDataFT |
|
@ -498,7 +538,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u |
|
|
IM_ASSERT(ft_bitmap); |
|
|
IM_ASSERT(ft_bitmap); |
|
|
|
|
|
|
|
|
// Allocate new temporary chunk if needed
|
|
|
// Allocate new temporary chunk if needed
|
|
|
const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height; |
|
|
const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height * 4; |
|
|
if (buf_bitmap_current_used_bytes + bitmap_size_in_bytes > BITMAP_BUFFERS_CHUNK_SIZE) |
|
|
if (buf_bitmap_current_used_bytes + bitmap_size_in_bytes > BITMAP_BUFFERS_CHUNK_SIZE) |
|
|
{ |
|
|
{ |
|
|
buf_bitmap_current_used_bytes = 0; |
|
|
buf_bitmap_current_used_bytes = 0; |
|
@ -506,9 +546,9 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Blit rasterized pixels to our temporary buffer and keep a pointer to it.
|
|
|
// Blit rasterized pixels to our temporary buffer and keep a pointer to it.
|
|
|
src_glyph.BitmapData = buf_bitmap_buffers.back() + buf_bitmap_current_used_bytes; |
|
|
src_glyph.BitmapData = (unsigned int*)(buf_bitmap_buffers.back() + buf_bitmap_current_used_bytes); |
|
|
buf_bitmap_current_used_bytes += bitmap_size_in_bytes; |
|
|
buf_bitmap_current_used_bytes += bitmap_size_in_bytes; |
|
|
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width * 1, multiply_enabled ? multiply_table : NULL); |
|
|
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width, multiply_enabled ? multiply_table : NULL); |
|
|
|
|
|
|
|
|
src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + padding); |
|
|
src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + padding); |
|
|
src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + padding); |
|
|
src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + padding); |
|
@ -555,8 +595,16 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u |
|
|
// 7. Allocate texture
|
|
|
// 7. Allocate texture
|
|
|
atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight); |
|
|
atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight); |
|
|
atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); |
|
|
atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); |
|
|
atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight); |
|
|
if (extra_flags & ImGuiFreeTypeBuilderFlags_LoadColor) |
|
|
memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight); |
|
|
{ |
|
|
|
|
|
atlas->TexPixelsRGBA32 = (unsigned int*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight * 4); |
|
|
|
|
|
memset(atlas->TexPixelsRGBA32, 0, atlas->TexWidth * atlas->TexHeight * 4); |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight); |
|
|
|
|
|
memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 8. Copy rasterized font characters back into the main texture
|
|
|
// 8. Copy rasterized font characters back into the main texture
|
|
|
// 9. Setup ImFont and glyphs for runtime
|
|
|
// 9. Setup ImFont and glyphs for runtime
|
|
@ -596,10 +644,21 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u |
|
|
// Blit from temporary buffer to final texture
|
|
|
// Blit from temporary buffer to final texture
|
|
|
size_t blit_src_stride = (size_t)src_glyph.Info.Width; |
|
|
size_t blit_src_stride = (size_t)src_glyph.Info.Width; |
|
|
size_t blit_dst_stride = (size_t)atlas->TexWidth; |
|
|
size_t blit_dst_stride = (size_t)atlas->TexWidth; |
|
|
unsigned char* blit_src = src_glyph.BitmapData; |
|
|
unsigned int* blit_src = src_glyph.BitmapData; |
|
|
unsigned char* blit_dst = atlas->TexPixelsAlpha8 + (ty * blit_dst_stride) + tx; |
|
|
if (atlas->TexPixelsAlpha8 != NULL) |
|
|
for (int y = info.Height; y > 0; y--, blit_dst += blit_dst_stride, blit_src += blit_src_stride) |
|
|
{ |
|
|
memcpy(blit_dst, blit_src, blit_src_stride); |
|
|
unsigned char* blit_dst = atlas->TexPixelsAlpha8 + (ty * blit_dst_stride) + tx; |
|
|
|
|
|
for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride) |
|
|
|
|
|
for (int x = 0; x < info.Width; x++) |
|
|
|
|
|
blit_dst[x] = (unsigned char)((blit_src[x] >> IM_COL32_A_SHIFT) & 0xFF); |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
unsigned int* blit_dst = atlas->TexPixelsRGBA32 + (ty * blit_dst_stride) + tx; |
|
|
|
|
|
for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride) |
|
|
|
|
|
for (int x = 0; x < info.Width; x++) |
|
|
|
|
|
blit_dst[x] = blit_src[x]; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Register glyph
|
|
|
// Register glyph
|
|
|
float x0 = info.OffsetX + font_off_x; |
|
|
float x0 = info.OffsetX + font_off_x; |
|
|