示例#1
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);
        }
示例#2
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);
        }
示例#3
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);
        }
        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);
        }
        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);
        }