Ejemplo n.º 1
0
        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++;
            }
        }
Ejemplo n.º 2
0
        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];
                    }
                }
            }
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
 public void ReleaseFace()
 {
     if (m_pFTFace != null)
     {
         ANT.ANT_Done_Face(ref m_pFTFace);
         m_pFTFace = null;
     }
 }
Ejemplo n.º 5
0
 public void ReleaseGlyph()
 {
     if (m_pGlyph != null)
     {
         ANT.ANT_Done_Glyph(ref m_pGlyph);
         m_pGlyph = null;
     }
 }
Ejemplo n.º 6
0
 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;
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        public void FinishCreating()
        {
            bool hasKerning = false;

            if (m_pFTFace != null)
            {
                hasKerning = ANT.ANT_HAS_KERNING(m_pFTFace);
            }
            if (!hasKerning || !m_pFontAtlas.UseKerning)
            {
                ReleaseFace();
            }
        }
Ejemplo n.º 10
0
 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);
     }
 }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
        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();
            }
        }
Ejemplo n.º 14
0
        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;
        }
Ejemplo n.º 15
0
        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);
            }
        }
Ejemplo n.º 16
0
        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);
        }
Ejemplo n.º 17
0
        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);
        }
Ejemplo n.º 21
0
        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);
                    }
                }
            }
        }
Ejemplo n.º 22
0
        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);
        }