internal GlyphSlot(IntPtr reference, Face parentFace, Library parentLibrary) { this.reference = reference; rec = PInvokeHelper.PtrToStructure <GlyphSlotRec>(reference); this.parentFace = parentFace; this.parentLibrary = parentLibrary; }
private void GetCurrentGlyph(out GlyphSlotRec glyph) { glyph = PInvokeHelper.PtrToStructure <GlyphSlotRec>(_rec.glyph); }
public bool buildFont() { int error = 0; IntPtr libptr = IntPtr.Zero; IntPtr faceptr = IntPtr.Zero; error = FT.Init_FreeType(out libptr); if (error != 0) { System.Console.WriteLine("FT_Init_FreeType failed"); return(false); } int[] maj = new int[1]; int[] min = new int[1]; int[] patch = new int[1]; FT.Library_Version(libptr, maj, min, patch); System.Console.WriteLine("Freetype Version {0}.{1}.{2}", maj[0], min[0], patch[0]); error = FT.New_Face(libptr, myFilename, 0, out faceptr); if (error == FT.Err_Unknown_File_Format) { System.Console.WriteLine("FT_New_Face Failed: Unknown Font Format"); return(false); } else if (error != 0) { System.Console.WriteLine("FT_New_Face Failed: Unknown Error: " + error); return(false); } //set the size of the Font in pixels error = FT.Set_Pixel_Sizes(faceptr, (uint)0, (uint)mySize); if (error != 0) { System.Console.WriteLine("FT_Set_Pixel_Sizes Failed: Unknown Error: " + error); return(false); } texture = new Texture(1024, 1024); //should be big enough for most sized fonts uint glyphIndex; uint asciiCounter; //only going to get ascii characters at this time //32 128 for (asciiCounter = 32; asciiCounter < 128; asciiCounter++) { //get the character loaded glyphIndex = FT.Get_Char_Index(faceptr, asciiCounter); error = FT.Load_Glyph(faceptr, glyphIndex, FT.LOAD_RENDER); if (error != 0) { System.Console.WriteLine("FT_Load_Glyph Failed: Unknown Error: " + error); return(false); } //copy to our Texture and update the myGlyph data structure FaceRec f = (FaceRec)Marshal.PtrToStructure(faceptr, typeof(FaceRec)); GlyphSlotRec g = (GlyphSlotRec)Marshal.PtrToStructure(f.glyph, typeof(GlyphSlotRec)); addGlyph(g, (int)asciiCounter); } FT.Done_Face(faceptr); FT.Done_FreeType(libptr); return(true); }
bool addGlyph(GlyphSlotRec glyph, int ascii) { if (glyph.bitmap.pixel_mode != (sbyte)Pixel_Mode.PIXEL_MODE_GRAY && glyph.bitmap.num_grays != 256) { System.Console.WriteLine("TtfFont::addGlyph Error: source data is wrong format "); return(false); } if (xCounter + glyph.bitmap.width > texture.width) { xCounter = 0; yCounter += (int)mySize; } if (yCounter + glyph.bitmap.rows > texture.height) { System.Console.WriteLine("TtfFont::addGlyph Error: no room in Texture "); return(false); } int byteCount = glyph.bitmap.rows * glyph.bitmap.width; Byte[] pixels = new Byte[byteCount * 4]; Byte[] buffer = new Byte[glyph.bitmap.rows * glyph.bitmap.width]; //copy the data to a managed buffer for use if (byteCount > 0) { Marshal.Copy(glyph.bitmap.buffer, buffer, 0, byteCount); } for (int y = 0; y < glyph.bitmap.rows; y++) { for (int x = 0; x < glyph.bitmap.width; x++) { int index = (y * glyph.bitmap.width) + x; pixels[index * 4] = buffer[index]; pixels[index * 4 + 1] = buffer[index]; pixels[index * 4 + 2] = buffer[index]; pixels[index * 4 + 3] = buffer[index]; //pixels[index * 4 + 3] = 0; } } //copy bitmap to the Texture if (byteCount > 0) { texture.paste(pixels, new Vector2((float)xCounter, (float)yCounter), new Vector2((float)glyph.bitmap.width, (float)glyph.bitmap.rows), PixelFormat.Rgba); } Glyph g = new Glyph(); g.minTexCoord.X = (float)xCounter / (float)texture.width; g.minTexCoord.Y = (float)(yCounter + glyph.bitmap.rows) / (float)texture.height; g.maxTexCoord.X = (float)(xCounter + glyph.bitmap.width) / (float)texture.width; g.maxTexCoord.Y = (float)yCounter / (float)texture.height; g.size.X = (float)glyph.bitmap.width; g.size.Y = (float)glyph.bitmap.rows; g.offset.X = (float)glyph.bitmap_left; g.offset.Y = (float)glyph.bitmap_top - (float)glyph.bitmap.rows; g.advance.X = (float)glyph.advance.x / (float)64; g.advance.Y = (float)glyph.advance.y / (float)64; myGlyphs[ascii] = g; xCounter += glyph.bitmap.width; xCounter += 2; //for spacing between letters in bitmap; return(true); }