s32 cellFontOpenFontMemory(vm::ptr<CellFontLibrary> library, u32 fontAddr, u32 fontSize, u32 subNum, u32 uniqueId, vm::ptr<CellFont> font) { cellFont.warning("cellFontOpenFontMemory(library=*0x%x, fontAddr=0x%x, fontSize=%d, subNum=%d, uniqueId=%d, font=*0x%x)", library, fontAddr, fontSize, subNum, uniqueId, font); font->stbfont = (stbtt_fontinfo*)((u8*)&(font->stbfont) + sizeof(void*)); // hack: use next bytes of the struct if (!stbtt_InitFont(font->stbfont, vm::_ptr<unsigned char>(fontAddr), 0)) return CELL_FONT_ERROR_FONT_OPEN_FAILED; font->renderer_addr = 0; font->fontdata_addr = fontAddr; font->origin = CELL_FONT_OPEN_MEMORY; return CELL_OK; }
void *textLoadFont(const char *fname, int size, int tex_w, int tex_h) { TEXT_FONT *font; FILESYSTEM_FILE *fp; int flen, asc, desc, linegap; if ((font = malloc(sizeof(TEXT_FONT))) == NULL) { return NULL; } if ((fp = fsFileOpen(fname, "rb")) == NULL) { fprintf(stderr, "Unable to open file %s\n", fname); free(font); return NULL; } fsFileSeek(fp, 0, SEEK_END); flen = fsFileTell(fp); fsFileSeek(fp, 0, SEEK_SET); if ((font->font_data = malloc(flen)) == NULL) { fsFileClose(fp); free(font); return NULL; } fsFileRead(font->font_data, flen, fp); font->font_data_len = flen; fsFileClose(fp); if (stbtt_InitFont(&font->face, font->font_data, 0) == 0) { free(font->font_data); free(font); return NULL; } font->cache = NULL; font->font_height = size; font->tex_w = bitwiseRoundUpToPow2(tex_w); font->tex_h = bitwiseRoundUpToPow2(tex_h); font->scale = stbtt_ScaleForPixelHeight(&font->face, font->font_height); stbtt_GetFontVMetrics(&font->face, &asc, &desc, &linegap); font->line_gap = font->scale * linegap; font->ascent = font->scale * asc; font->descent = font->scale * desc; return font; }
void DynamicFontData::lock() { fr=font_data.read(); if (fr.ptr()!=last_data_ptr) { last_data_ptr=fr.ptr(); if (!stbtt_InitFont(&info, last_data_ptr, 0)) { valid=false; } else { valid=true; } last_data_ptr=fr.ptr(); } }
fm::Result FontRenderer::loadFromFile(const std::string &fileName,unsigned int size) { clean(); m_ownData = true; std::ifstream in(fileName.c_str(), std::fstream::in | std::fstream::binary); if (!in) { clean(); return fm::Result("IOError",fm::Result::OPFailed,"FileNotFound","loadFromFile",__FILE__,__LINE__,fileName); } in.seekg(0, std::ios::end); m_fileSize = in.tellg(); if (in.fail()) { clean(); return fm::Result("IOError",fm::Result::OPFailed,"FileNotReadable","loadFromFile",__FILE__,__LINE__,fileName); } m_fileContent = new fm::Uint8[m_fileSize]; in.seekg(0, std::ios::beg); in.read((char*)m_fileContent, m_fileSize); if (in.fail()) { clean(); return fm::Result("IOError",fm::Result::OPFailed,"FileNotReadable","loadFromFile",__FILE__,__LINE__,fileName); } in.close(); if (!stbtt_InitFont((stbtt_fontinfo*)m_stbFontInfo, m_fileContent, stbtt_GetFontOffsetForIndex(m_fileContent,0))) { clean(); return fm::Result("TTFError",fm::Result::OPFailed,"InvalidFont","loadFromFile",__FILE__,__LINE__,fileName); } setCharacterSize(size); return fm::Result(); }
struct font *load_font_from_memory(const char *filename, unsigned char *data, int len) { struct font *font; int ok; font = malloc(sizeof(struct font)); font->tag = TAG_FONT; font->data = malloc(len); memcpy(font->data, data, len); ok = stbtt_InitFont(&font->info, font->data, 0); if (!ok) { warn("error: cannot init font file: '%s'", filename); return NULL; } return font; }
static inline jlong wrapped_Java_com_badlogic_gdx_graphics_g2d_stbtt_StbTrueType_initFont (JNIEnv* env, jclass clazz, jbyteArray obj_data, jint offset, jint len, char* data) { //@line:30 stbtt_fontinfo* info = (stbtt_fontinfo*)malloc(sizeof(stbtt_fontinfo)); unsigned char* dataCopy = (unsigned char*)malloc(sizeof(unsigned char) * len); memcpy(dataCopy, data, sizeof(unsigned char) * len); int result = stbtt_InitFont(info, (const unsigned char*)dataCopy, 0); if(!result) { free(info); free(dataCopy); return 0; } else { return (jlong)info; } }
fm::Result FontRenderer::loadFromMemory(const fm::Uint8 *fileContent,fm::Size fileSizeInBytes,unsigned int size) { clean(); m_ownData = false; m_fileSize = fileSizeInBytes; m_fileContent = fileContent; if (!stbtt_InitFont((stbtt_fontinfo*)m_stbFontInfo, m_fileContent, stbtt_GetFontOffsetForIndex(m_fileContent,0))) { clean(); return fm::Result("FTError",fm::Result::OPFailed,"InvalidFont","loadFromMemory",__FILE__,__LINE__); } setCharacterSize(size); return fm::Result(); }
int cellFontOpenFontMemory(vm::ptr<CellFontLibrary> library, u32 fontAddr, u32 fontSize, u32 subNum, u32 uniqueId, vm::ptr<CellFont> font) { cellFont->Warning("cellFontOpenFontMemory(library_addr=0x%x, fontAddr=0x%x, fontSize=%d, subNum=%d, uniqueId=%d, font_addr=0x%x)", library.addr(), fontAddr, fontSize, subNum, uniqueId, font.addr()); if (!s_fontInternalInstance->m_bInitialized) return CELL_FONT_ERROR_UNINITIALIZED; font->stbfont = (stbtt_fontinfo*)((u8*)&(font->stbfont) + sizeof(void*)); // hack: use next bytes of the struct if (!stbtt_InitFont(font->stbfont, (unsigned char*)Memory.VirtualToRealAddr(fontAddr), 0)) return CELL_FONT_ERROR_FONT_OPEN_FAILED; font->renderer_addr = 0; font->fontdata_addr = fontAddr; font->origin = CELL_FONT_OPEN_MEMORY; return CELL_FONT_OK; }
void Ibex::TextRenderer::initializeFont() { unsigned char *ttf_buffer = new unsigned char[1<<22]; unsigned char *temp_bitmap = new unsigned char[1024*256];//512*512]; #ifdef WIN32 //size_t read = fread(ttf_buffer, 1, 1<<22, fopen("c:/windows/fonts/times.ttf", "rb")); //size_t read = fread(ttf_buffer, 1, 1<<22, fopen("c:/windows/fonts/Courbd.ttf", "rb")); size_t read = fread(ttf_buffer, 1, 1<<22, fopen("c:/windows/fonts/L_10646.ttf", "rb")); #else //size_t read = fread(ttf_buffer, 1, 1<<22, fopen("/Library/Fonts/Georgia.ttf", "rb")); size_t read = fread(ttf_buffer, 1, 1<<22, fopen("/Library/Fonts/Andale Mono.ttf", "rb")); //size_t read = fread(ttf_buffer, 1, 1<<22, fopen("/Library/Fonts/OsakaMono.ttf", "rb")); #endif std::cerr << "Read font bytes: " << read << std::endl; stbtt_fontinfo font; stbtt_InitFont(&font, ttf_buffer, 0); int r = stbtt_BakeFontBitmap(ttf_buffer,0, 32.0, temp_bitmap,1024,256, 32,96, cdata); // no guarantee this fits! if(r <= 0) { std::cerr << "stbtt_BackFontBitmap r: " << r << std::endl; exit(0); } scale = stbtt_ScaleForPixelHeight(&font, 32); stbtt_GetFontVMetrics(&font, &ascent,&descent,&lineGap); baseline = (int) (ascent*scale); // can free ttf_buffer at this point if(ftex == 0) glGenTextures(1, &ftex); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)1024); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glBindTexture(GL_TEXTURE_2D, ftex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1024,256, 0, GL_RED, GL_UNSIGNED_BYTE, temp_bitmap); // can free temp_bitmap at this point if(!checkForErrors()) { exit(1); } delete []ttf_buffer; delete []temp_bitmap; }
float* get_font_data(const char *font_file, float *font_height){ float *data = 0; stbtt_bakedchar *baked; File_Data file = get_file(font_file); if (!file.data) exit(1); if (file.data){ int size = sizeof(*baked)*256; baked = (stbtt_bakedchar*)malloc(size); memset_4tech(baked, 0, sizeof(*baked)*256); stbtt_fontinfo font; if (stbtt_InitFont(&font, (unsigned char*)file.data, 0)){ float scale; int a,d,g; scale = stbtt_ScaleForPixelHeight(&font, 17.f); stbtt_GetFontVMetrics(&font, &a, &d, &g); *font_height = scale*(a - d + g); int w, h; w = 10*256; h = 25; unsigned char *pixels = (unsigned char*)malloc(w * h); stbtt_BakeFontBitmap((unsigned char*)file.data, 0, 17.f, pixels, w, h, 0, 128, baked); free(pixels); free_file(file); data = (float*)malloc(sizeof(float)*256); memset_4tech(data, 0, sizeof(float)*256); stbtt_bakedchar *baked_ptr = baked; for (int i = 0; i < 128; ++i, ++baked_ptr){ data[i] = baked_ptr->xadvance; } } free(baked); } else{ printf("error: cannot continue without font\n"); } return data; }
static void *font_renderer_stb_init(const char *font_path, float font_size) { int ascent, descent, line_gap; stbtt_fontinfo info; uint8_t *font_data = NULL; stb_font_renderer_t *self = (stb_font_renderer_t*) calloc(1, sizeof(*self)); /* See https://github.com/nothings/stb/blob/master/stb_truetype.h#L539 */ font_size = STBTT_POINT_SIZE(font_size); if (!self) goto error; if (!filestream_read_file(font_path, (void**)&font_data, NULL)) goto error; if (!font_renderer_stb_create_atlas(self, font_data, font_size, 512, 512)) goto error; if (!stbtt_InitFont(&info, font_data, stbtt_GetFontOffsetForIndex(font_data, 0))) goto error; stbtt_GetFontVMetrics(&info, &ascent, &descent, &line_gap); self->line_height = ascent - descent; if (font_size < 0) self->line_height *= stbtt_ScaleForMappingEmToPixels(&info, -font_size); else self->line_height *= stbtt_ScaleForPixelHeight(&info, font_size); free(font_data); return self; error: if (font_data) free(font_data); if (self) font_renderer_stb_free(self); return NULL; }
bool stash::add_font( const std::vector<unsigned char> &data, const std::string &alias ) { if( !tex ) { // Create texture for the cache. glGenTextures(1, &tex); if( !tex ) return false; glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tw,th, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } sth_font fnt(tex, &rows, tw, th); // Init stb_truetype if( data.size() && stbtt_InitFont(&fnt.font, &data[0], 0) ) { // Read in the font data. fnt.data = data; // Store normalized line height. The real line height is got // by multiplying the lineh by font size. int ascent, descent, lineGap; stbtt_GetFontVMetrics(&fnt.font, &ascent, &descent, &lineGap); int fh = ascent - descent; fnt.ascender = (float)ascent / (float)fh; fnt.descender = (float)descent / (float)fh; fnt.lineh = (float)(fh + lineGap) / (float)fh; fonts.push_back( fnt ); aliases[ alias ] = fonts.size() - 1; // refresh data pointers because of std::vector reordering for( size_t i = 0; i < fonts.size(); ++i ) fonts[i].font.data = &fonts[i].data[0]; return true; } return false; }
Purity::Font::Font(const std::string& fontFileName) : mFontFileName(fontFileName) { loadFont(); if (!stbtt_InitFont(&mFontInfo, mFontData.data(), 0)) { std::cerr << "Failed to initialize font" << std::endl; } int w, h; auto bitmap = stbtt_GetCodepointBitmap(&mFontInfo, 0, stbtt_ScaleForPixelHeight(&mFontInfo, 30), 'D', &w, &h, 0, 0); for (int j = 0; j < h; ++j) { for (int i = 0; i < w; ++i) putchar(" .:ioVM@"[bitmap[j * w + i] >> 5]); putchar('\n'); } }
int cellFontOpenFontMemory(mem_ptr_t<CellFontLibrary> library, u32 fontAddr, u32 fontSize, u32 subNum, u32 uniqueId, mem_ptr_t<CellFont> font) { cellFont->Warning("cellFontOpenFontMemory(library_addr=0x%x, fontAddr=0x%x, fontSize=%d, subNum=%d, uniqueId=%d, font_addr=0x%x)", library.GetAddr(), fontAddr, fontSize, subNum, uniqueId, font.GetAddr()); if (!s_fontInternalInstance->m_bInitialized) return CELL_FONT_ERROR_UNINITIALIZED; if (!library.IsGood() || !font.IsGood()) return CELL_FONT_ERROR_INVALID_PARAMETER; if (!Memory.IsGoodAddr(fontAddr)) return CELL_FONT_ERROR_FONT_OPEN_FAILED; if (!stbtt_InitFont(&(font->stbfont), (unsigned char*)Memory.VirtualToRealAddr(fontAddr), 0)) return CELL_FONT_ERROR_FONT_OPEN_FAILED; font->renderer_addr = 0; font->fontdata_addr = fontAddr; font->origin = CELL_FONT_OPEN_MEMORY; return CELL_FONT_OK; }
static void *font_renderer_stb_init(const char *font_path, float font_size) { uint8_t *font_data = NULL; int ascent, descent, line_gap; stbtt_fontinfo info; stb_font_renderer_t *self = (stb_font_renderer_t*) calloc(1, sizeof(*self)); /* prevent warnings */ (void)rect_width_compare; if (!self) goto error; if (!read_file(font_path, (void**)&font_data, NULL)) goto error; if (!font_renderer_stb_create_atlas(self, font_data, font_size)) goto error; if (!stbtt_InitFont(&info, font_data, stbtt_GetFontOffsetForIndex(font_data, 0))) goto error; stbtt_GetFontVMetrics(&info, &ascent, &descent, &line_gap); self->line_height = ascent - descent;// + line_gap; if (font_size < 0) self->line_height *= stbtt_ScaleForMappingEmToPixels(&info, -font_size); else self->line_height *= stbtt_ScaleForPixelHeight(&info, font_size); free(font_data); return self; error: if (font_data) free(font_data); font_renderer_stb_free(self); return NULL; }
fm::Result FontRenderer::copyFromMemory(const fm::Uint8 *fileContent,fm::Size fileSizeInBytes,unsigned int size) { clean(); m_ownData = true; m_fileSize = fileSizeInBytes; fm::Uint8 *buf = new fm::Uint8[fileSizeInBytes]; std::memcpy(buf,fileContent,fileSizeInBytes); m_fileContent = buf; if (!stbtt_InitFont((stbtt_fontinfo*)m_stbFontInfo, m_fileContent, stbtt_GetFontOffsetForIndex(m_fileContent,0))) { clean(); return fm::Result("FTError",fm::Result::OPFailed,"InvalidFont","copyFromMemory",__FILE__,__LINE__); } setCharacterSize(size); return fm::Result(); }
FontRenderer &FontRenderer::operator=(const FontRenderer &renderer) { if (m_ownData) delete m_fileContent; m_currentSize = renderer.m_currentSize; m_metrics = renderer.m_metrics; m_fileSize = renderer.m_fileSize; m_ownData = renderer.m_ownData; if (m_ownData) { fm::Uint8 *buf = new fm::Uint8[m_fileSize]; std::memcpy(buf,renderer.m_fileContent,m_fileSize); m_fileContent = buf; } else { m_fileContent = renderer.m_fileContent; } if (m_fileContent) stbtt_InitFont((stbtt_fontinfo*)m_stbFontInfo, m_fileContent, stbtt_GetFontOffsetForIndex(m_fileContent,0)); }
void MakeBitmapCodepoint(char Letter, platform_read_file *ReadFile, game_state *GameState) { read_file_result FontFile = PlatformReadFile("../Assets/Gotham-Medium.ttf"); Assert(FontFile.Contents > 0); int Width, Height, XOffset, YOffset; stbtt_fontinfo FontInfo; stbtt_InitFont(&FontInfo, (uint8 *)FontFile.Contents, stbtt_GetFontOffsetForIndex((uint8 *)FontFile.Contents, 0)); uint8 *MonoBitmap = stbtt_GetCodepointBitmap(&FontInfo, 0, stbtt_ScaleForPixelHeight(&FontInfo, (float)GlobalFontRenderSize), Letter, &Width, &Height, &XOffset, &YOffset); font_codepoint *NextCodepoint = &GameState->AlphabetBitmaps[GameState->AlphabetBitmapsCount]; GameState->AlphabetBitmapsCount++; NextCodepoint->BaselineFactor = YOffset; NextCodepoint->Bitmap.Width = Width; NextCodepoint->Bitmap.Height = Height; NextCodepoint->Bitmap.GLTexture = (GLuint)VirtualAlloc(0, sizeof(*MonoBitmap), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); SIZE_T BitmapSize = sizeof(uint32) * Width * Height; void *ConvertedBitmap = malloc(BitmapSize); uint32 Pitch = Width * sizeof(uint32); uint8 *Source = (uint8 *)MonoBitmap; uint8 *DestRow = (uint8 *)ConvertedBitmap + ((Height - 1) * Pitch); for (uint32 Y = 0; Y < (uint32)Height; ++Y) { uint32 *Dest = (uint32 *)DestRow; for (uint32 X = 0; X < (uint32)Width; ++X) { uint8 MonoAlpha = *Source++; uint8 Bit2 = MonoAlpha; // A uint8 Bit3 = MonoAlpha; // R uint8 Bit0 = MonoAlpha; // G uint8 Bit1 = MonoAlpha; // B *Dest++ = ((Bit0 << 24) | (Bit1 << 16) | (Bit2 << 8) | (Bit3 << 0)); } DestRow -= Pitch; } //TODO pull this out into a separate GL function to keep gl code separate from game code. glGenTextures(1, &NextCodepoint->Bitmap.GLTexture); glBindTexture(GL_TEXTURE_2D, NextCodepoint->Bitmap.GLTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ConvertedBitmap); VirtualFree(ConvertedBitmap, BitmapSize, MEM_RELEASE); stbtt_FreeBitmap(MonoBitmap, 0); }
bool Font::load(std::string path, AssetManager& manager) { mName = getFileNameFromPath(path); mPath = getPathFromFilePath(path); FILE* file = fopen(path.c_str(), "rb"); size_t fSize = 0; U8* buffer = nullptr; if (!file) return false; fseek(file, 0, SEEK_END); fSize = ftell(file); rewind(file); buffer = new U8[fSize]; const U32 TATLAS_SIZE = 512; size_t result = fread(buffer, sizeof(U8), fSize, file); if (result != fSize) return false; stbtt_fontinfo fontInfo; stbtt_InitFont(&fontInfo, buffer, stbtt_GetFontOffsetForIndex(buffer, 0)); U8* img = new U8[TATLAS_SIZE * TATLAS_SIZE]; U8* rgbaImg = new U8[TATLAS_SIZE * TATLAS_SIZE * 4]; stbtt_pack_context pack; stbtt_packedchar pcdata[96]; stbtt_packedchar tabData; int packSuccess = stbtt_PackBegin(&pack, img, TATLAS_SIZE, TATLAS_SIZE, 0, 1, NULL); int rangeSuc = stbtt_PackFontRange(&pack, buffer, 0, mSize, 32, 95, pcdata); int tabSuc = stbtt_PackFontRange(&pack, buffer, 0, mSize, '\t', 1, &tabData); stbtt_PackEnd(&pack); I32 largestY = 0; I32 tabSize = 0; mTabWidth = tabData.xadvance; for (int i = 0; i < 96; ++i) { mGlyphs[i].x0 = pcdata[i].x0; mGlyphs[i].y0 = pcdata[i].y0; mGlyphs[i].x1 = pcdata[i].x1; mGlyphs[i].y1 = pcdata[i].y1; mGlyphs[i].xoff = pcdata[i].xoff; mGlyphs[i].yoff = pcdata[i].yoff; mGlyphs[i].xoff2 = pcdata[i].xoff2; mGlyphs[i].yoff2 = pcdata[i].yoff2; mGlyphs[i].xadvance = pcdata[i].xadvance; vec2 tl = GET_UV(mGlyphs[i].x0, TATLAS_SIZE, mGlyphs[i].y0, TATLAS_SIZE); vec2 br = GET_UV(mGlyphs[i].x1, TATLAS_SIZE, mGlyphs[i].y1, TATLAS_SIZE); mGlyphs[i].u0 = tl.x(); mGlyphs[i].v0 = tl.y(); mGlyphs[i].u1 = br.x(); mGlyphs[i].v1 = br.y(); mGlyphs[i].w = mGlyphs[i].x1 - mGlyphs[i].x0; mGlyphs[i].h = abs(mGlyphs[i].y1 - mGlyphs[i].y0); if (mGlyphs[i].y1 - mGlyphs[i].y0 > largestY) largestY = (mGlyphs[i].y1 - mGlyphs[i].y0); } mMaxGlyphHeight = largestY; for (int i = 0; i < TATLAS_SIZE * TATLAS_SIZE; ++i) { rgbaImg[(i * 4) + 0] = 255; //r rgbaImg[(i * 4) + 1] = 255; //g rgbaImg[(i * 4) + 2] = 255; //b rgbaImg[(i * 4) + 3] = img[i]; //a } glGenTextures(1, &glTex); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, glTex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TATLAS_SIZE, TATLAS_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaImg); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); fclose(file); delete[] buffer; delete[] img; delete[] rgbaImg; return true; }
bool D3D9DebugManager::InitFontRendering() { HRESULT hr = S_OK; int width = FONT_TEX_WIDTH; int height = FONT_TEX_HEIGHT; string font = GetEmbeddedResource(sourcecodepro_ttf); byte *ttfdata = (byte *)font.c_str(); const int firstChar = int(' ') + 1; const int lastChar = 127; const int numChars = lastChar - firstChar; byte *buf = new byte[width * height]; const float pixelHeight = 20.0f; stbtt_BakeFontBitmap(ttfdata, 0, pixelHeight, buf, width, height, firstChar, numChars, m_Font.charData); stbtt_fontinfo f = {0}; stbtt_InitFont(&f, ttfdata, 0); int ascent = 0; stbtt_GetFontVMetrics(&f, &ascent, NULL, NULL); m_Font.maxHeight = float(ascent) * stbtt_ScaleForPixelHeight(&f, pixelHeight); IDirect3DTexture9 *fontTex = NULL; hr = m_WrappedDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fontTex, NULL); if(FAILED(hr)) { RDCERR("Failed to create font texture %08x", hr); } D3DLOCKED_RECT lockedRegion; hr = fontTex->LockRect(0, &lockedRegion, NULL, D3DLOCK_DISCARD); if(FAILED(hr)) { RDCERR("Failed to lock font texture %08x", hr); } else { BYTE *texBase = (BYTE *)lockedRegion.pBits; for(int y = 0; y < height; y++) { byte *curRow = (texBase + (y * lockedRegion.Pitch)); for(int x = 0; x < width; x++) { curRow[x * 4 + 0] = buf[(y * width) + x]; curRow[x * 4 + 1] = buf[(y * width) + x]; curRow[x * 4 + 2] = buf[(y * width) + x]; curRow[x * 4 + 3] = buf[(y * width) + x]; } } hr = fontTex->UnlockRect(0); if(hr != S_OK) { RDCERR("Failed to unlock font texture %08x", hr); } } m_Font.Tex = fontTex; delete[] buf; return true; }
int main(int argc, char **argv) { stbtt_fontinfo font; unsigned char *bitmap; int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 34807), s = (argc > 2 ? atoi(argv[2]) : 32); //debug(); // @TODO: why is minglui.ttc failing? fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/mingliu.ttc", "rb")); //fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/x/DroidSansMono.ttf", "rb")); { static stbtt_pack_context pc; static stbtt_packedchar cd[256]; static unsigned char atlas[1024*1024]; stbtt_PackBegin(&pc, atlas, 1024,1024,1024,1,NULL); stbtt_PackFontRange(&pc, ttf_buffer, 0, 32.0, 0, 256, cd); stbtt_PackEnd(&pc); } #if 0 stbtt_BakeFontBitmap(ttf_buffer,stbtt_GetFontOffsetForIndex(ttf_buffer,0), 40.0, temp_bitmap[0],BITMAP_W,BITMAP_H, 32,96, cdata); // no guarantee this fits! stbi_write_png("fonttest1.png", BITMAP_W, BITMAP_H, 1, temp_bitmap, 0); { stbtt_pack_context pc; stbtt_PackBegin(&pc, temp_bitmap[0], BITMAP_W, BITMAP_H, 0, 1, NULL); stbtt_PackFontRange(&pc, ttf_buffer, 0, 20.0, 32, 95, pdata); stbtt_PackFontRange(&pc, ttf_buffer, 0, 20.0, 0xa0, 0x100-0xa0, pdata); stbtt_PackEnd(&pc); stbi_write_png("fonttest2.png", BITMAP_W, BITMAP_H, 1, temp_bitmap, 0); } { stbtt_pack_context pc; stbtt_pack_range pr[2]; stbtt_PackBegin(&pc, temp_bitmap[0], BITMAP_W, BITMAP_H, 0, 1, NULL); pr[0].chardata_for_range = pdata; pr[0].first_unicode_char_in_range = 32; pr[0].num_chars_in_range = 95; pr[0].font_size = 20.0f; pr[1].chardata_for_range = pdata+256; pr[1].first_unicode_char_in_range = 0xa0; pr[1].num_chars_in_range = 0x100 - 0xa0; pr[1].font_size = 20.0f; stbtt_PackSetOversampling(&pc, 2, 2); stbtt_PackFontRanges(&pc, ttf_buffer, 0, pr, 2); stbtt_PackEnd(&pc); stbi_write_png("fonttest3.png", BITMAP_W, BITMAP_H, 1, temp_bitmap, 0); } return 0; #endif stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0)); bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, (float)s), c, &w, &h, 0,0); for (j=0; j < h; ++j) { for (i=0; i < w; ++i) putchar(" .:ioVM@"[bitmap[j*w+i]>>5]); putchar('\n'); } return 0; }