void UpdateSignature() { if (m_CurrentFace != null && m_Name != null) { m_Signature = Alt.StringFormatter.sprintf("%s,%u,%d,%d:%dx%d,%d,%d", m_Name, m_CharMap, (int)m_GlyphRenderType, m_Resolution, m_Height, m_Width, m_Hinting ? 1 : 0, m_FlipY ? 1 : 0); if (m_GlyphRenderType == GlyphRenderType.Outline) { m_Signature += Alt.StringFormatter.sprintf(",%08X%08X%08X%08X%08X%08X", ANT.ANT_double_to_int16p16(m_Matrix.sx), ANT.ANT_double_to_int16p16(m_Matrix.shy), ANT.ANT_double_to_int16p16(m_Matrix.shx), ANT.ANT_double_to_int16p16(m_Matrix.sy), ANT.ANT_double_to_int16p16(m_Matrix.tx), ANT.ANT_double_to_int16p16(m_Matrix.ty)); } m_ChangeStamp++; } }
public void DrawToBitmap(byte[] pData, int texWidth, int texHeight) { if (IsEmpty()) { return; } // Convert The Glyph To A Bitmap. ANT_Error error = ANT.ANT_Glyph_To_Bitmap(ref m_pGlyph, ANT_Render_Mode.ANT_RENDER_MODE_NORMAL, null, true); if (error == ANT_Error.ANT_Err_Ok) { ANT_BitmapGlyph bitmap_glyph = (ANT_BitmapGlyph)m_pGlyph; // This Reference Will Make Accessing The Bitmap Easier. ANT_Bitmap bitmap = bitmap_glyph.bitmap; int x, y = 0; int index; for (y = 0; y < bitmap.rows; y++) { for (x = 0; x < bitmap.width; x++) { index = (m_y + y) * texWidth + m_x + x; pData[index] = bitmap.buffer[y * bitmap.width + x]; } } } }
public bool AddKerning(int first, int second, ref double x, ref double y) { if (m_CurrentFace != null && first != 0 && second != 0 && ANT.ANT_HAS_KERNING(m_CurrentFace.face_flags)) { ANT_Vector add_kerning_delta = new ANT_Vector(); ANT.ANT_Get_Kerning(m_CurrentFace, first, second, ANT_Kerning_Mode.ANT_KERNING_DEFAULT, add_kerning_delta); double dx = ANT.ANT_int26p6_to_double(add_kerning_delta.x); double dy = ANT.ANT_int26p6_to_double(add_kerning_delta.y); if (m_GlyphRenderType == GlyphRenderType.Outline) { m_Matrix.Transform2x2(ref dx, ref dy); } x += dx; y += dy; return(true); } return(false); }
public void ReleaseFace() { if (m_pFTFace != null) { ANT.ANT_Done_Face(ref m_pFTFace); m_pFTFace = null; } }
public void ReleaseGlyph() { if (m_pGlyph != null) { ANT.ANT_Done_Glyph(ref m_pGlyph); m_pGlyph = null; } }
public void ReleaseLibrary() { if (m_Library != null) { ANT.ANT_Done_AltNETType(ref m_Library); m_Library = null; } }
void compute_string_bbox(out ANT_BBox abbox) { ANT_BBox bbox = new ANT_BBox(); ANT_BBox glyph_bbox = new ANT_BBox(); // initialize string bbox to "empty" values bbox.xMin = bbox.yMin = 32000; bbox.xMax = bbox.yMax = -32000; // for each glyph image, compute its bounding box, // translate it, and grow the string bbox for (int n = 0; n < num_glyphs; n++) { TGlyph glyph = glyphs[n]; ANT.ANT_Glyph_Get_CBox(glyph.image, ANT_Glyph_BBox_Mode.ANT_GLYPH_BBOX_PIXELS, glyph_bbox); glyph_bbox.xMin += glyph.pos.x; glyph_bbox.xMax += glyph.pos.x; glyph_bbox.yMin += glyph.pos.y; glyph_bbox.yMax += glyph.pos.y; if (glyph_bbox.xMin < bbox.xMin) { bbox.xMin = glyph_bbox.xMin; } if (glyph_bbox.yMin < bbox.yMin) { bbox.yMin = glyph_bbox.yMin; } if (glyph_bbox.xMax > bbox.xMax) { bbox.xMax = glyph_bbox.xMax; } if (glyph_bbox.yMax > bbox.yMax) { bbox.yMax = glyph_bbox.yMax; } } // check that we really grew the string bbox if (bbox.xMin > bbox.xMax) { bbox.xMin = 0; bbox.yMin = 0; bbox.xMax = 0; bbox.yMax = 0; } // return string bbox abbox = bbox; }
public bool Attach(string file_name) { if (m_CurrentFace != null) { m_ANTLastError = ANT.ANT_Attach_File(m_CurrentFace, file_name); return(m_ANTLastError == ANT_Error.ANT_Err_Ok); } return(false); }
public void FinishCreating() { bool hasKerning = false; if (m_pFTFace != null) { hasKerning = ANT.ANT_HAS_KERNING(m_pFTFace); } if (!hasKerning || !m_pFontAtlas.UseKerning) { ReleaseFace(); } }
private void Tramp_Connect_Click(object sender, RoutedEventArgs e) { GlobalData.Tramp_num = Convert.ToUInt16(this.Tramp_num.Text); ANT.USER_DEVICENUM_tramp = GlobalData.Tramp_num; try { ANT.Tramp_Init(); ANT.Tramp_Start(); } catch (Exception ex) { MessageBox.Show("Connect failed with exception: \n" + ex.Message); } }
public int DrawString(Graphics graphics, Bitmap bitmap, int x, int y, string text) { char c; int currX = x; int n = 0; ANT_Vector kerning = new ANT_Vector(); int ixGlyph; int ixGlyphPrev = 0; bool hasKerning = false; if (m_pFTFace != null) { hasKerning = ANT.ANT_HAS_KERNING(m_pFTFace); } int len = text.Length; while (n < len) { c = text[n]; ANTBitmapChar iter; if (m_mapBitmapChar.TryGetValue(c, out iter)) { if (hasKerning) { // get kerning ixGlyph = ANT.ANT_Get_Char_Index(m_pFTFace, c); if (hasKerning && ixGlyphPrev != 0 && ixGlyph != 0) { ANT.ANT_Get_Kerning(m_pFTFace, ixGlyphPrev, ixGlyph, ANT_Kerning_Mode.ANT_KERNING_DEFAULT, kerning); currX += kerning.x >> 6; } ixGlyphPrev = ixGlyph; } iter.Render(graphics, bitmap, currX, y); currX += iter.GetXAdvance(); } n++; } return(currX); }
public int GetWidth(string text) { int currX = 0; int n = 0; char c; ANT_Vector kerning = new ANT_Vector(); int ixGlyph; int ixGlyphPrev = 0; bool hasKerning = false; if (m_pFTFace != null) { hasKerning = ANT.ANT_HAS_KERNING(m_pFTFace); } while (text[n] != 0) { c = text[n]; ANTBitmapChar iter; if (m_mapBitmapChar.TryGetValue(c, out iter)) { if (hasKerning) { // get kerning ixGlyph = ANT.ANT_Get_Char_Index(m_pFTFace, c); if (hasKerning && ixGlyphPrev != 0 && ixGlyph != 0) { ANT.ANT_Get_Kerning(m_pFTFace, ixGlyphPrev, ixGlyph, ANT_Kerning_Mode.ANT_KERNING_DEFAULT, kerning); currX += kerning.x >> 6; } ixGlyphPrev = ixGlyph; } currX += iter.GetXAdvance(); } n++; } return(currX); }
void UpdateCharSize() { if (m_CurrentFace != null) { if (m_Resolution != 0) { ANT.ANT_Set_Char_Size(m_CurrentFace, (int)m_Width, // char_width in 1/64th of points (int)m_Height, // char_height in 1/64th of points m_Resolution, // horizontal device resolution m_Resolution); // vertical device resolution } else { ANT.ANT_Set_Pixel_Sizes(m_CurrentFace, (int)(m_Width >> 6), // pixel_width (int)(m_Height >> 6)); // pixel_height } UpdateSignature(); } }
public void Dispose() { if (m_Faces != null) { foreach (ANT_Face face in m_Faces.Values) { ANT_Face f = face; ANT.ANT_Done_Face(ref f); } m_Faces.Clear(); m_Faces = null; } if (m_FaceNames != null) { m_FaceNames.Clear(); m_FaceNames = null; } m_Signature = null; }
private void ANT_Connect_Click(object sender, RoutedEventArgs e) { bool flag = this.Heart_num.Text == null; if (flag) { MessageBox.Show("请输入设备号!"); } else { GlobalData.Heart_num = Convert.ToUInt16(this.Heart_num.Text); } ANT.USER_DEVICENUM = GlobalData.Tramp_num; try { ANT.Init(); ANT.Start(); } catch (Exception ex) { MessageBox.Show("Connect failed with exception: \n" + ex.Message); } }
public bool PrepareGlyph(int glyph_code) { m_GlyphIndex = (int)ANT.ANT_Get_Char_Index(m_CurrentFace, glyph_code); m_ANTLastError = ANT.ANT_Load_Glyph(m_CurrentFace, m_GlyphIndex, m_Hinting ? ANT_LOAD.ANT_LOAD_DEFAULT : ANT_LOAD.ANT_LOAD_NO_HINTING); if (m_ANTLastError == ANT_Error.ANT_Err_Ok) { m_AdvanceX = ANT.ANT_int26p6_to_double(m_CurrentFace.glyph.advance.x); m_AdvanceY = ANT.ANT_int26p6_to_double(m_CurrentFace.glyph.advance.y); switch (m_GlyphRenderType) { case GlyphRenderType.Mono: case GlyphRenderType.Gray8: m_ANTLastError = ANT.ANT_Render_Glyph(m_CurrentFace.glyph, m_GlyphRenderType == GlyphRenderType.Mono ? ANT_Render_Mode.ANT_RENDER_MODE_MONO : ANT_Render_Mode.ANT_RENDER_MODE_NORMAL); if (m_ANTLastError == ANT_Error.ANT_Err_Ok) { m_CurrentBitmap = ANTExt.ToBitmap(m_CurrentFace.glyph.bitmap, m_FlipY); if (m_CurrentBitmap != null) { m_Bounds.Left = m_CurrentFace.glyph.bitmap_left; m_Bounds.Top = m_CurrentFace.glyph.bitmap_top; m_Bounds.Right = m_CurrentBitmap.PixelWidth + 1; m_Bounds.Bottom = m_CurrentBitmap.PixelHeight + 1; } } else { m_Bounds = new Rect(0, 0, m_AdvanceX, m_AdvanceY); } m_GlyphDataType = m_GlyphRenderType == GlyphRenderType.Mono ? GlyphDataType.Mono : GlyphDataType.Gray8; return(true); case GlyphRenderType.Outline: m_CurrentGeometry = ANTExt.ANT_Outline_ToGeometry(m_CurrentFace.glyph.outline, m_FlipY, m_Matrix); if (m_CurrentGeometry != null) { m_Bounds = m_CurrentGeometry.Bounds; //m_Bounds.BoundFloorCeiling(); m_GlyphDataType = GlyphDataType.Outline; m_Matrix.Transform(ref m_AdvanceX, ref m_AdvanceY); return(true); } m_Bounds = Rect.Empty; break; } } return(false); }
public bool LoadFont(string font_name, GlyphRenderType ren_type, byte[] font_mem, int font_mem_size) { int face_index = 0; bool ret = false; ANT_Library library = Library; if (library != null) { m_ANTLastError = ANT_Error.ANT_Err_Ok; int idx = FindFace(font_name); if (idx >= 0) { if (m_CurrentFace == m_Faces[idx] && m_GlyphRenderType == ren_type) { return(true); } m_CurrentFace = m_Faces[idx]; m_Name = font_name; } else { ANT_Face face; if (font_mem != null && font_mem_size != 0) { m_ANTLastError = ANT.ANT_New_Memory_Face(library, font_mem, font_mem_size, face_index, out face); } else { m_ANTLastError = ANT.ANT_New_Face(library, font_name, face_index, out face); } if (m_ANTLastError == ANT_Error.ANT_Err_Ok) { m_FaceIndex++; m_Faces.Add(m_FaceIndex, face); m_FaceNames.Add(font_name, m_FaceIndex); m_CurrentFace = face; m_Name = font_name; UpdateCharSize(); } else { m_CurrentFace = null; m_Name = null; } } if (m_ANTLastError == ANT_Error.ANT_Err_Ok) { ret = true; switch (ren_type) { case GlyphRenderType.Mono: m_GlyphRenderType = GlyphRenderType.Mono; break; case GlyphRenderType.Gray8: m_GlyphRenderType = GlyphRenderType.Gray8; break; case GlyphRenderType.Outline: if (ANT.ANT_IS_SCALABLE(m_CurrentFace.face_flags)) { m_GlyphRenderType = GlyphRenderType.Outline; } else { m_GlyphRenderType = GlyphRenderType.Gray8; } break; } UpdateSignature(); } } return(ret); }
void DoWork() { ANT_Library library; ANT_Face face; ANT_GlyphSlot slot; // transformation matrix ANT_Matrix matrix = new ANT_Matrix(); // untransformed origin ANT_Vector pen = new ANT_Vector(); ANT_Error error; string filename; string text; double angle; int target_height; int n, num_chars; filename = Common.Example_AltNETType_FontFileName; text = "AltNETType = FreeType.NET"; num_chars = text.Length; // use 25 degrees angle = (25.0 / 360) * 3.14159 * 2; target_height = HEIGHT; // initialize library error = ANT.ANT_Init_AltNETType(out library); // error handling omitted // create face object error = ANT.ANT_New_Face(library, filename, 0, out face); // error handling omitted if (error != ANT_Error.ANT_Err_Ok) { return; } // use 50pt at 100dpi // set character size error = ANT.ANT_Set_Char_Size(face, 50 * 64, 0, 96, 0); // error handling omitted slot = face.glyph; // set up matrix matrix.xx = (int)(Math.Cos(angle) * 0x10000L); matrix.xy = (int)(-Math.Sin(angle) * 0x10000L); matrix.yx = (int)(Math.Sin(angle) * 0x10000L); matrix.yy = (int)(Math.Cos(angle) * 0x10000L); // the pen position in 26.6 cartesian space coordinates; // start at (25, 503) relative to the upper left corner pen.x = 15 * 64; pen.y = (target_height - (HEIGHT - 20)) * 64; for (n = 0; n < num_chars; n++) { // set transformation ANT.ANT_Set_Transform(face, matrix, pen); // load glyph image into the slot (erase previous one) error = ANT.ANT_Load_Char(face, text[n], ANT_LOAD.ANT_LOAD_RENDER); if (error != ANT_Error.ANT_Err_Ok) { // ignore errors continue; } // now, draw to our target surface (convert position) draw_bitmap(slot.bitmap, slot.bitmap_left, target_height - slot.bitmap_top); // increment pen position pen.x += slot.advance.x; pen.y += slot.advance.y; } show_image(); ANT.ANT_Done_Face(ref face); ANT.ANT_Done_AltNETType(ref library); }
void DoWork() { ANT_Library library; ANT_Face face; ANT_GlyphSlot slot; ANT_Error error; string filename; string text; int num_chars; int glyph_index; bool use_kerning; int previous; int pen_x, pen_y, n; filename = Common.Example_AltNETType_FontFileName; text = "AltNETType (kerning + centering)";// Common.Pangram; num_chars = text.Length; // ... initialize library ... // ... create face object ... // ... set character size ... { // initialize library error = ANT.ANT_Init_AltNETType(out library); // error handling omitted // create face object error = ANT.ANT_New_Face(library, filename, 0, out face); // error handling omitted if (error != ANT_Error.ANT_Err_Ok) { return; } // use 36pt at 100dpi // set character size error = ANT.ANT_Set_Char_Size(face, 36 * 64, 0, 96, 0); // error handling omitted } // a small shortcut slot = face.glyph; // start at (0,0) pen_x = 0; pen_y = 0; num_glyphs = 0; use_kerning = ANT.ANT_HAS_KERNING(face); previous = 0; ANT_Vector delta = new ANT_Vector(); for (n = 0; n < num_chars; n++) { // convert character code to glyph index glyph_index = ANT.ANT_Get_Char_Index(face, text[n]); // retrieve kerning distance and move pen position if (use_kerning && previous != 0 && glyph_index != 0) { ANT.ANT_Get_Kerning(face, previous, glyph_index, ANT_Kerning_Mode.ANT_KERNING_DEFAULT, delta); pen_x += delta.x >> 6; } // store current pen position if (pos[num_glyphs] == null) { pos[num_glyphs] = new ANT_Vector(); } pos[num_glyphs].x = pen_x; pos[num_glyphs].y = pen_y; // load glyph image into the slot without rendering error = ANT.ANT_Load_Glyph(face, glyph_index, ANT_LOAD.ANT_LOAD_DEFAULT); if (error != ANT_Error.ANT_Err_Ok) { // ignore errors, jump to next glyph continue; } // extract glyph image and store it in our table error = ANT.ANT_Get_Glyph(face.glyph, out glyphs[num_glyphs]); if (error != ANT_Error.ANT_Err_Ok) { // ignore errors, jump to next glyph continue; } // increment pen position pen_x += slot.advance.x >> 6; // record current glyph index previous = glyph_index; // increment number of glyphs num_glyphs++; } ANT_BBox string_bbox; compute_string_bbox(out string_bbox); int my_target_width = WIDTH; int my_target_height = HEIGHT; // compute string dimensions in integer pixels int string_width = string_bbox.xMax - string_bbox.xMin; int string_height = string_bbox.yMax - string_bbox.yMin; // compute start pen position in 26.6 cartesian pixels int start_x = ((my_target_width - string_width) / 2) * 64; // int start_y = ((my_target_height - string_height) / 2) * 64; // need to center bitmaps (not base line) int start_y = ((my_target_height - string_height) / 2 - string_bbox.yMin) * 64; ANT_Vector pen = new ANT_Vector(); for (n = 0; n < num_glyphs; n++) { ANT_Glyph image = glyphs[n]; pen.x = start_x + pos[n].x * 64; pen.y = start_y + pos[n].y * 64; error = ANT.ANT_Glyph_To_Bitmap(ref image, ANT_Render_Mode.ANT_RENDER_MODE_NORMAL, pen, false); if (error == ANT_Error.ANT_Err_Ok) { ANT_BitmapGlyph bit = (ANT_BitmapGlyph)image; draw_bitmap(bit.bitmap, bit.left, my_target_height - bit.top); ANT.ANT_Done_Glyph(ref image); } } // show_image(); ANT.ANT_Done_Face(ref face); ANT.ANT_Done_AltNETType(ref library); }
void DoWork() { ANT_Library library; ANT_Face face; ANT_GlyphSlot slot; ANT_Error error; string filename; string text; int num_chars; bool use_kerning; int previous; int pen_x, pen_y, n; filename = Common.Example_AltNETType_FontFileName; text = "AltNETType (transformation + centering + kerning)";// Common.Pangram; num_chars = text.Length; // ... initialize library ... // ... create face object ... // ... set character size ... { // initialize library error = ANT.ANT_Init_AltNETType(out library); // error handling omitted // create face object error = ANT.ANT_New_Face(library, filename, 0, out face); // error handling omitted if (error != ANT_Error.ANT_Err_Ok) { return; } // use 50pt at 100dpi // set character size error = ANT.ANT_Set_Char_Size(face, 28 * 64, 0, 96, 0); // error handling omitted } // a small shortcut slot = face.glyph; // start at (0,0) pen_x = 0; pen_y = 0; num_glyphs = 0; use_kerning = ANT.ANT_HAS_KERNING(face); previous = 0; ANT_Vector delta = new ANT_Vector(); for (n = 0; n < num_chars; n++) { glyph = glyphs[n]; if (glyph == null) { glyphs[n] = glyph = new TGlyph(); } // convert character code to glyph index glyph.index = ANT.ANT_Get_Char_Index(face, text[n]); // retrieve kerning distance and move pen position if (use_kerning && previous != 0 && glyph.index != 0) { ANT.ANT_Get_Kerning(face, previous, glyph.index, ANT_Kerning_Mode.ANT_KERNING_DEFAULT, delta); pen_x += delta.x >> 6; } // store current pen position if (glyph.pos == null) { glyph.pos = new ANT_Vector(); } glyph.pos.x = pen_x; glyph.pos.y = pen_y; // load glyph image into the slot without rendering error = ANT.ANT_Load_Glyph(face, glyph.index, ANT_LOAD.ANT_LOAD_DEFAULT); if (error != ANT_Error.ANT_Err_Ok) { // ignore errors, jump to next glyph continue; } // extract glyph image and store it in our table error = ANT.ANT_Get_Glyph(face.glyph, out glyph.image); if (error != ANT_Error.ANT_Err_Ok) { // ignore errors, jump to next glyph continue; } // translate the glyph image now ANT.ANT_Glyph_Transform(glyph.image, null, glyph.pos); // increment pen position pen_x += slot.advance.x >> 6; // record current glyph index previous = glyph.index; // increment number of glyphs num_glyphs++; } ANT_Vector start = new ANT_Vector(); // transformation matrix ANT_Matrix matrix = new ANT_Matrix(); ANT_Glyph image; ANT_Vector pen = new ANT_Vector(); ANT_BBox bbox = new ANT_BBox(); double angle; ANT_BBox string_bbox; compute_string_bbox(out string_bbox); int my_target_width = WIDTH; int my_target_height = HEIGHT; // compute string dimensions in integer pixels int string_width = string_bbox.xMax - string_bbox.xMin; int string_height = string_bbox.yMax - string_bbox.yMin; // use -30 degrees angle = (330.0 / 360) * 3.14159 * 2; // compute start pen position in 26.6 cartesian pixels start.x = (int)(((my_target_width - string_width * Math.Cos(angle) - string_height * Math.Sin(angle)) / 2 + string_bbox.yMax * Math.Sin(angle)) * 64); // start.y = ((my_target_height - string_height) / 2) * 64; // need to center bitmaps (not base line) start.y = (int)(((my_target_height - string_height * Math.Cos(angle) - string_width * Math.Sin(angle)) / 2 - string_bbox.yMin * Math.Cos(angle)) * 64); // set up transform (a rotation here) matrix.xx = (int)(Math.Cos(angle) * 0x10000L); matrix.xy = (int)(-Math.Sin(angle) * 0x10000L); matrix.yx = (int)(Math.Sin(angle) * 0x10000L); matrix.yy = (int)(Math.Cos(angle) * 0x10000L); pen.CopyFrom(start); for (n = 0; n < num_glyphs; n++) { // create a copy of the original glyph error = ANT.ANT_Glyph_Copy(glyphs[n].image, out image); if (error != ANT_Error.ANT_Err_Ok) { continue; } // transform copy (this will also translate it to the // correct position ANT.ANT_Glyph_Transform(image, matrix, pen); // check bounding box; if the transformed glyph image // is not in our target surface, we can avoid rendering it ANT.ANT_Glyph_Get_CBox(image, ANT_Glyph_BBox_Mode.ANT_GLYPH_BBOX_PIXELS, bbox); if (bbox.xMax <= 0 || bbox.xMin >= my_target_width || bbox.yMax <= 0 || bbox.yMin >= my_target_height) { //continue; } else { // convert glyph image to bitmap (destroy the glyph copy!) error = ANT.ANT_Glyph_To_Bitmap(ref image, ANT_Render_Mode.ANT_RENDER_MODE_NORMAL, null, // no additional translation true); // destroy copy in "image" if (error == ANT_Error.ANT_Err_Ok) { ANT_BitmapGlyph bit = (ANT_BitmapGlyph)image; draw_bitmap(bit.bitmap, bit.left, my_target_height - bit.top); } } // increment pen position -- // we don't have access to a slot structure, // so we have to use advances from glyph structure // (which are in 16.16 fixed float format) pen.x += image.advance.x >> 10; pen.y += image.advance.y >> 10; ANT.ANT_Done_Glyph(ref image); } // show_image(); ANT.ANT_Done_Face(ref face); ANT.ANT_Done_AltNETType(ref library); }
public void AddFont(string strFileName, int size, string szLetters) { if (string.IsNullOrEmpty(strFileName) || !Alt.IO.VirtualFile.Exists(strFileName)) { return; } if (m_Library == null) { if (ANT.ANT_Init_AltNETType(out m_Library) != ANT_Error.ANT_Err_Ok) { throw new Exception("ANT_Init_FreeType failed"); } } // The Object In Which FreeType Holds Information On A Given // Font Is Called A "face". ANT_Face face; string file = strFileName; // This Is Where We Load In The Font Information From The File. if (ANT.ANT_New_Face(m_Library, file, 0, out face) != ANT_Error.ANT_Err_Ok) { throw new Exception("no font: " + file); } // FreeType Measures Font Size In Terms Of 1/64ths Of Pixels. ANT.ANT_Set_Char_Size(face, size * 64, size * 64, 72, 72); int len = szLetters.Length; int n; ANTBitmapChar pFTBitmapChar; ANT_Glyph pGlyph; ANTBitmapFont pANTBitmapFont = new ANTBitmapFont(this); pANTBitmapFont.LineHeight = face.size.metrics.height >> 6; pANTBitmapFont.SetFTFace(face); m_BitmapFonts.Add(pANTBitmapFont); char c; int height; int yOffset; int ixGlyph; for (n = 0; n < len; n++) { c = szLetters[n]; // check that the character hasn't already been processed if (pANTBitmapFont.GetChar(c) == null) { // Load The Glyph For Our Character. ixGlyph = ANT.ANT_Get_Char_Index(face, c); if (ixGlyph == 0) { Console.WriteLine("character doesn't exist in font: '" + c + "'"); } else { if (ANT.ANT_Load_Glyph(face, ixGlyph, ANT_LOAD.ANT_LOAD_DEFAULT) != ANT_Error.ANT_Err_Ok) { throw new Exception("ANT_Load_Glyph failed"); } // Move The Face's Glyph Into A Glyph Object. if (ANT.ANT_Get_Glyph(face.glyph, out pGlyph) != ANT_Error.ANT_Err_Ok) { throw new Exception("ANT_Get_Glyph failed"); } pFTBitmapChar = new ANTBitmapChar(c); // all metrics dimensions are multiplied by 64, so we have to divide by 64 height = face.glyph.metrics.height >> 6; yOffset = pANTBitmapFont.LineHeight - (face.glyph.metrics.horiBearingY >> 6); pFTBitmapChar.SetOffsets(face.glyph.metrics.horiBearingX >> 6, yOffset); pFTBitmapChar.SetSize(face.glyph.metrics.width >> 6, height); pFTBitmapChar.SetXAdvance(face.glyph.metrics.horiAdvance >> 6); pFTBitmapChar.SetGlyph(pGlyph); m_BitmapChars.Add(pFTBitmapChar); pANTBitmapFont.AddChar(c, pFTBitmapChar); } } } }
public static Geometry ANT_Outline_ToGeometry(ANT_Outline outline, bool flipY, Matrix4 mtx) { if (outline == null) { return(null); } ANTOutlineGeometry path = new ANTOutlineGeometry(); double x1, y1, x2, y2, x3, y3; int n; // index of contour in outline int first; // index of first point in contour int tag; // current point's state first = 0; ANT_Vector_Array points = outline.points; for (n = 0; n < outline.n_contours; n++) { int last; // index of last point in contour last = outline.contours[n]; int limit = last; outline_v_start.CopyFrom(points[first]); outline_v_last.CopyFrom(points[last]); outline_v_control.CopyFrom(outline_v_start); int point_index = first; ANT_Byte_Array tags_buf = outline.tags; int tags_index = first; tag = ANT.ANT_CURVE_TAG(tags_buf[tags_index + 0]); // A contour cannot start with a cubic control point! if (tag == ANT_CURVE_Tag.ANT_CURVE_TAG_CUBIC) { return(null); } // check first point to determine origin if (tag == ANT_CURVE_Tag.ANT_CURVE_TAG_CONIC) { // first point is conic control. Yes, this happens. if (ANT.ANT_CURVE_TAG(tags_buf[last]) == ANT_CURVE_Tag.ANT_CURVE_TAG_ON) { // start at last point if it is on the curve outline_v_start.CopyFrom(outline_v_last); limit--; } else { // if both first and last points are conic, // start at their middle and record its position // for closure outline_v_start.x = (outline_v_start.x + outline_v_last.x) / 2; outline_v_start.y = (outline_v_start.y + outline_v_last.y) / 2; outline_v_last.CopyFrom(outline_v_start); } point_index--; tags_index--; } x1 = ANT.ANT_int26p6_to_double(outline_v_start.x); y1 = ANT.ANT_int26p6_to_double(outline_v_start.y); if (flipY) { y1 = -y1; } mtx.Transform(ref x1, ref y1); path.MoveTo(x1, y1); while (point_index < limit) { point_index++; ANT_Vector point = points[point_index]; tags_index++; tag = ANT.ANT_CURVE_TAG(tags_buf[tags_index + 0]); switch (tag) { case ANT_CURVE_Tag.ANT_CURVE_TAG_ON: // emit a single line_to { x1 = ANT.ANT_int26p6_to_double(point.x); y1 = ANT.ANT_int26p6_to_double(point.y); if (flipY) { y1 = -y1; } mtx.Transform(ref x1, ref y1); path.LineTo(x1, y1); continue; } case ANT_CURVE_Tag.ANT_CURVE_TAG_CONIC: // consume conic arcs { outline_v_control.x = point.x; outline_v_control.y = point.y; Do_Conic: if (point_index < limit) { point_index++; point = points[point_index]; tags_index++; tag = ANT.ANT_CURVE_TAG(tags_buf[tags_index + 0]); outline_vec.CopyFrom(point); if (tag == ANT_CURVE_Tag.ANT_CURVE_TAG_ON) { x1 = ANT.ANT_int26p6_to_double(outline_v_control.x); y1 = ANT.ANT_int26p6_to_double(outline_v_control.y); x2 = ANT.ANT_int26p6_to_double(outline_vec.x); y2 = ANT.ANT_int26p6_to_double(outline_vec.y); if (flipY) { y1 = -y1; y2 = -y2; } mtx.Transform(ref x1, ref y1); mtx.Transform(ref x2, ref y2); path.Сurve3(x1, y1, x2, y2); continue; } if (tag != ANT_CURVE_Tag.ANT_CURVE_TAG_CONIC) { return(null); } outline_v_middle.x = (outline_v_control.x + outline_vec.x) / 2; outline_v_middle.y = (outline_v_control.y + outline_vec.y) / 2; x1 = ANT.ANT_int26p6_to_double(outline_v_control.x); y1 = ANT.ANT_int26p6_to_double(outline_v_control.y); x2 = ANT.ANT_int26p6_to_double(outline_v_middle.x); y2 = ANT.ANT_int26p6_to_double(outline_v_middle.y); if (flipY) { y1 = -y1; y2 = -y2; } mtx.Transform(ref x1, ref y1); mtx.Transform(ref x2, ref y2); path.Сurve3(x1, y1, x2, y2); outline_v_control.CopyFrom(outline_vec); goto Do_Conic; } x1 = ANT.ANT_int26p6_to_double(outline_v_control.x); y1 = ANT.ANT_int26p6_to_double(outline_v_control.y); x2 = ANT.ANT_int26p6_to_double(outline_v_start.x); y2 = ANT.ANT_int26p6_to_double(outline_v_start.y); if (flipY) { y1 = -y1; y2 = -y2; } mtx.Transform(ref x1, ref y1); mtx.Transform(ref x2, ref y2); path.Сurve3(x1, y1, x2, y2); goto Close; } default: { if (point_index + 1 > limit || ANT.ANT_CURVE_TAG(tags_buf[tags_index + 1]) != ANT_CURVE_Tag.ANT_CURVE_TAG_CUBIC) { return(null); } outline_vec1.x = points[point_index + 0].x; outline_vec1.y = points[point_index + 0].y; outline_vec2.x = points[point_index + 1].x; outline_vec2.y = points[point_index + 1].y; point_index += 2; { point = points[point_index]; } tags_index += 2; if (point_index <= limit) { outline_vec.CopyFrom(point); x1 = ANT.ANT_int26p6_to_double(outline_vec1.x); y1 = ANT.ANT_int26p6_to_double(outline_vec1.y); x2 = ANT.ANT_int26p6_to_double(outline_vec2.x); y2 = ANT.ANT_int26p6_to_double(outline_vec2.y); x3 = ANT.ANT_int26p6_to_double(outline_vec.x); y3 = ANT.ANT_int26p6_to_double(outline_vec.y); if (flipY) { y1 = -y1; y2 = -y2; y3 = -y3; } mtx.Transform(ref x1, ref y1); mtx.Transform(ref x2, ref y2); mtx.Transform(ref x3, ref y3); path.Сurve4(x1, y1, x2, y2, x3, y3); continue; } x1 = ANT.ANT_int26p6_to_double(outline_vec1.x); y1 = ANT.ANT_int26p6_to_double(outline_vec1.y); x2 = ANT.ANT_int26p6_to_double(outline_vec2.x); y2 = ANT.ANT_int26p6_to_double(outline_vec2.y); x3 = ANT.ANT_int26p6_to_double(outline_v_start.x); y3 = ANT.ANT_int26p6_to_double(outline_v_start.y); if (flipY) { y1 = -y1; y2 = -y2; y3 = -y3; } mtx.Transform(ref x1, ref y1); mtx.Transform(ref x2, ref y2); mtx.Transform(ref x3, ref y3); path.Сurve4(x1, y1, x2, y2, x3, y3); goto Close; } } } path.ClosePolygon(); Close: first = last + 1; } return(path); }