Exemplo n.º 1
0
        internal Rect BoundGlyph(uint glyphIndex, StyleSimulations style)
        {
            var recip = 1 / (float)FtFace.UnitsPerEM;
            //var strength = 0.02f;
            var trm = AdjustGlyphWidth(glyphIndex);
            var m   = new FTMatrix((int)trm.M11 * 65536, (int)trm.M21 * 65536, (int)trm.M12 * 65536, (int)trm.M22 * 65536);
            var v   = new FTVector(Fixed16Dot16.FromDouble(trm.OffsetX * 65536), Fixed16Dot16.FromDouble(trm.OffsetY * 65536));

            FtFace.SetCharSize(Fixed26Dot6.FromInt32(FtFace.UnitsPerEM), Fixed26Dot6.FromInt32(FtFace.UnitsPerEM), 72, 72);
            FtFace.SetTransform(m, v);
            FtFace.LoadGlyph(glyphIndex, LoadFlags.NoBitmap | LoadFlags.NoHinting, LoadTarget.Normal);

            /*if (style == StyleSimulations.BoldSimulation)
             * {
             *  FtFace.Glyph.Outline.Embolden(Fixed26Dot6.FromDouble(strength * FtFace.UnitsPerEM));
             *  FtFace.Glyph.Outline.Translate((int) (-strength * 0.5 * FtFace.UnitsPerEM), (int) (-strength * 0.5 * FtFace.UnitsPerEM));
             * }*/
            var box  = FtFace.Glyph.GetGlyph().GetCBox(GlyphBBoxMode.Pixels);
            var rect = new Rect(new Point(box.Left * recip, box.Top * recip), new Point(box.Right * recip, box.Bottom * recip));

            if (rect.IsEmpty)
            {
                rect = new Rect(new Point(trm.OffsetX, trm.OffsetY), new Point(trm.OffsetX, trm.OffsetY));
            }

            return(rect);
        }
Exemplo n.º 2
0
        public ExampleForm()
        {
            InitializeComponent();

            fontService = new FontService();
            fontFolder = "Fonts/";
            sampleText = "SharpFont";
            // Some variations of the character set shown by the Windows Font Viewer
            //sampleText = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890.:,;'\"(!?)+-*//=";
            //sampleText = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890";
            sampleText = "abcdefghijklmnopqrstuvwxyz";
            fontService.Size = 62f;
            fontSize = 62f;
            mainMenuFontSize.Text = fontService.Size.ToString("0.0");
            foreColor = Color.Black;
            backColor = Color.Transparent;

            decimal testValue = 12.1234567890123456M;
            Debug.Print("testValue  : {0}", (double)testValue);
            // none of these keep the precision I was expecting...
            var f26 = new Fixed26Dot6(testValue);
            Debug.Print("Fixed 26.6 : {0}", (double)f26);
            Debug.Print("Fixed 26.6 : {0}", f26);
            var f16 = new Fixed16Dot16(testValue);
            Debug.Print("Fixed 16.16: {0}", (double)f16);
            Debug.Print("Fixed 16.16: {0}", f16);
            var f2 = new Fixed2Dot14((double)testValue); // decimal constructor crashes here
            Debug.Print("Fixed  2.14: {0}", (double)f2);
            Debug.Print("Fixed  2.14: {0}", f2);
        }
Exemplo n.º 3
0
        public ExampleForm()
        {
            InitializeComponent();

            fontService = new FontService();
            fontFolder  = "Fonts/";
            sampleText  = "SharpFont";
            // Some variations of the character set shown by the Windows Font Viewer
            //sampleText = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890.:,;'\"(!?)+-*//=";
            //sampleText = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890";
            sampleText            = "abcdefghijklmnopqrstuvwxyz";
            fontService.Size      = 62f;
            fontSize              = 62f;
            mainMenuFontSize.Text = fontService.Size.ToString("0.0");
            foreColor             = Color.Black;
            backColor             = Color.Transparent;

            decimal testValue = 12.1234567890123456M;

            Debug.Print("testValue  : {0}", (double)testValue);
            // none of these keep the precision I was expecting...
            var f26 = new Fixed26Dot6(testValue);

            Debug.Print("Fixed 26.6 : {0}", (double)f26);
            Debug.Print("Fixed 26.6 : {0}", f26);
            var f16 = new Fixed16Dot16(testValue);

            Debug.Print("Fixed 16.16: {0}", (double)f16);
            Debug.Print("Fixed 16.16: {0}", f16);
            var f2 = new Fixed2Dot14((double)testValue);             // decimal constructor crashes here

            Debug.Print("Fixed  2.14: {0}", (double)f2);
            Debug.Print("Fixed  2.14: {0}", f2);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Get the thickness of the underline.
        /// </summary>
        /// <param name="characterSize">Reference character size.</param>
        /// <returns>Underline thickness, in pixels.</returns>
        public float GetUnderlineThickness(int characterSize)
        {
            if (_face != null && SetCurrentSize(characterSize))
            {
                // Return a fixed thickness if font is a bitmap font
                if (!_face.IsScalable)
                {
                    return(characterSize / 14f);
                }

                return(Fixed16Dot16.Multiply(_face.UnderlineThickness, _face.Size.Metrics.ScaleY).ToSingle());
            }
            else
            {
                return(0f);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Get the position of the underline.
        /// </summary>
        /// <param name="characterSize">Reference character size.</param>
        /// <returns>Underline position, in pixels.</returns>
        public float GetUnderlinePosition(int characterSize)
        {
            if (_face != null && SetCurrentSize(characterSize))
            {
                // Return a fixed position if font is a bitmap font
                if (!_face.IsScalable)
                {
                    return(characterSize / 10f);
                }

                return(-(Fixed16Dot16.Multiply(_face.UnderlinePosition, _face.Size.Metrics.ScaleY).ToSingle())); // / (float)(1 << 6);
            }
            else
            {
                return(0f);
            }
        }
Exemplo n.º 6
0
        public unsafe Fixed16Dot16[] GetAdvances(uint start, uint count, LoadFlags flags)
        {
            IntPtr advPtr;
            Error err = FT.FT_Get_Advances(Reference, start, count, flags, out advPtr);

            if (err != Error.Ok)
                throw new FreeTypeException(err);

            //create a new array and copy the data from the pointer over
            Fixed16Dot16[] advances = new Fixed16Dot16[count];
            IntPtr* ptr = (IntPtr*)advPtr;

            for (int i = 0; i < count; i++)
                advances[i] = Fixed16Dot16.FromRawValue((int)ptr[i]);

            return advances;
        }
Exemplo n.º 7
0
        /// <summary>
        /// Return the track kerning for a given face object at a given size.
        /// </summary>
        /// <param name="pointSize">The point size in 16.16 fractional points.</param>
        /// <param name="degree">The degree of tightness.</param>
        /// <returns>The kerning in 16.16 fractional points.</returns>
        public Fixed16Dot16 GetTrackKerning(Fixed16Dot16 pointSize, int degree)
        {
            if (disposed)
                throw new ObjectDisposedException("face", "Cannot access a disposed object.");

            IntPtr kerning;

            Error err = FT.FT_Get_Track_Kerning(Reference, (IntPtr)pointSize.Value, degree, out kerning);

            if (err != Error.Ok)
                throw new FreeTypeException(err);

            return Fixed16Dot16.FromRawValue((int)kerning);
        }
Exemplo n.º 8
0
        public void GetPfrMetrics(out uint outlineResolution, out uint metricsResolution, out Fixed16Dot16 metricsXScale, out Fixed16Dot16 metricsYScale)
        {
            IntPtr tmpXScale, tmpYScale;
            Error err = FT.FT_Get_PFR_Metrics(Reference, out outlineResolution, out metricsResolution, out tmpXScale, out tmpYScale);

            metricsXScale = Fixed16Dot16.FromRawValue((int)tmpXScale);
            metricsYScale = Fixed16Dot16.FromRawValue((int)tmpYScale);

            if (err != Error.Ok)
                throw new FreeTypeException(err);
        }
Exemplo n.º 9
0
		/// <summary>
		/// Reset a stroker object's attributes.
		/// </summary>
		/// <remarks>
		/// The radius is expressed in the same units as the outline coordinates.
		/// </remarks>
		/// <param name="radius">The border radius.</param>
		/// <param name="lineCap">The line cap style.</param>
		/// <param name="lineJoin">The line join style.</param>
		/// <param name="miterLimit">
		/// The miter limit for the <see cref="StrokerLineJoin.MiterFixed"/> and
		/// <see cref="StrokerLineJoin.MiterVariable"/> line join styles, expressed as 16.16 fixed point value.
		/// </param>
		public void Set(int radius, StrokerLineCap lineCap, StrokerLineJoin lineJoin, Fixed16Dot16 miterLimit)
		{
			if (disposed)
				throw new ObjectDisposedException("Stroker", "Cannot access a disposed object.");

			FT.FT_Stroker_Set(Reference, radius, lineCap, lineJoin, (IntPtr)miterLimit.Value);
		}
Exemplo n.º 10
0
 public static Fixed16Dot16 Cos(Fixed16Dot16 angle)
 {
     return Fixed16Dot16.FromRawValue((int)FT.FT_Cos((IntPtr)angle.Value));
 }
Exemplo n.º 11
0
 public static Fixed16Dot16 CeilFix(Fixed16Dot16 a)
 {
     return Fixed16Dot16.FromRawValue((int)FT.FT_CeilFix((IntPtr)a.Value));
 }
Exemplo n.º 12
0
 public static Fixed16Dot16 Atan2(Fixed16Dot16 x, Fixed16Dot16 y)
 {
     return Fixed16Dot16.FromRawValue((int)FT.FT_Atan2((IntPtr)x.Value, (IntPtr)y.Value));
 }
Exemplo n.º 13
0
 public static Fixed16Dot16 AngleDiff(Fixed16Dot16 angle1, Fixed16Dot16 angle2)
 {
     return Fixed16Dot16.FromRawValue((int)FT.FT_Angle_Diff((IntPtr)angle1.Value, (IntPtr)angle2.Value));
 }
Exemplo n.º 14
0
 public static Fixed16Dot16 MulFix(int a, Fixed16Dot16 b)
 {
     return Fixed16Dot16.FromRawValue((int)FT.FT_MulFix((IntPtr)a, (IntPtr)b.Value));
 }
Exemplo n.º 15
0
 public static Fixed16Dot16 MulDiv(Fixed16Dot16 a, Fixed16Dot16 b, Fixed16Dot16 c)
 {
     return Fixed16Dot16.FromRawValue((int)FT.FT_MulDiv((IntPtr)a.Value, (IntPtr)b.Value, (IntPtr)c.Value));
 }
Exemplo n.º 16
0
        private Glyph LoadGlyph(int codePoint, int characterSize, bool bold, float outlineThickness)
        {
            Glyph glyph = new Glyph();

            if (_face == null)
            {
                return(null);
            }

            // Set the character size
            if (!SetCurrentSize(characterSize))
            {
                return(glyph);
            }

            // Load the glyph corresponding to the code point
            var flags = LoadFlags.ForceAutohint;

            if (outlineThickness != 0)
            {
                flags |= LoadFlags.NoBitmap;
            }

            _face.LoadChar((uint)codePoint, flags, SharpFont.LoadTarget.Normal);

            // Retrieve the glyph
            SharpFont.Glyph glyphDesc = _face.Glyph.GetGlyph();

            // Apply bold if necessary -- first technique using outline (highest quality)
            SharpFont.Fixed26Dot6 weight = new SharpFont.Fixed26Dot6(1);
            bool outline = glyphDesc.Format == SharpFont.GlyphFormat.Outline;

            if (outline)
            {
                if (bold)
                {
                    SharpFont.OutlineGlyph outlineGlyph = glyphDesc.ToOutlineGlyph();
                    outlineGlyph.Outline.Embolden(weight);
                }

                if (outlineThickness != 0)
                {
                    _stroker.Set((int)(outlineThickness * Fixed26Dot6.FromInt32(1).Value),
                                 StrokerLineCap.Round, StrokerLineJoin.Round, Fixed16Dot16.FromSingle(0));

                    // This function returning a new instance of Glyph
                    // Because the pointer may changed upon applying stroke to the glyph
                    glyphDesc = glyphDesc.Stroke(_stroker, false);
                }
            }

            // Convert the glyph to a bitmap (i.e. rasterize it)
            glyphDesc.ToBitmap(SharpFont.RenderMode.Normal, new FTVector26Dot6(0, 0), true);
            SharpFont.FTBitmap bitmap = glyphDesc.ToBitmapGlyph().Bitmap;

            // Apply bold if necessary -- fallback technique using bitmap (lower quality)
            if (!outline)
            {
                if (bold)
                {
                    bitmap.Embolden(_library, weight, weight);
                }

                if (outlineThickness != 0)
                {
                    Logger.Warning("Failed to outline glyph (no fallback available)");
                }
            }

            // Compute the glyph's advance offset
            glyph.Advance = _face.Glyph.Metrics.HorizontalAdvance.ToSingle();
            if (bold)
            {
                glyph.Advance += weight.ToSingle();
            }

            int width  = bitmap.Width;
            int height = bitmap.Rows;

            if ((width > 0) && (height > 0))
            {
                // Leave a small padding around characters, so that filtering doesn't
                // pollute them with pixels from neighbors
                int padding = 1;

                // Get the glyphs page corresponding to the character size
                Page page = _pages[characterSize];

                // Find a good position for the new glyph into the texture
                glyph.TexCoords = FindGlyphRectangle(page, width + 2 * padding, height + 2 * padding);
                var texRect = glyph.TexCoords;

                // Make sure the texture data is positioned in the center
                // of the allocated texture rectangle
                glyph.TexCoords = new Rectangle(texRect.X + padding, texRect.Y + padding,
                                                texRect.Width - 2 * padding, texRect.Height - 2 * padding);

                // Compute the glyph's bounding box
                float boundsX      = (float)(_face.Glyph.Metrics.HorizontalBearingX);
                float boundsY      = -(float)(_face.Glyph.Metrics.HorizontalBearingY);
                float boundsWidth  = (float)(_face.Glyph.Metrics.Width) + outlineThickness * 2;
                float boundsHeight = (float)(_face.Glyph.Metrics.Height) + outlineThickness * 2;
                glyph.Bounds = new RectangleF(boundsX, boundsY, boundsWidth, boundsHeight);

                // Extract the glyph's pixels from the bitmap
                byte[] pixelBuffer = new byte[width * height * 4];
                for (int i = 0; i < pixelBuffer.Length; i++)
                {
                    pixelBuffer[i] = 255;
                }

                unsafe
                {
                    byte *pixels = (byte *)bitmap.Buffer.ToPointer();
                    if (bitmap.PixelMode == SharpFont.PixelMode.Mono)
                    {
                        // Pixels are 1 bit monochrome values
                        for (int y = 0; y < height; ++y)
                        {
                            for (int x = 0; x < width; ++x)
                            {
                                // The color channels remain white, just fill the alpha channel
                                int index = (x + y * width) * 4 + 3;
                                pixelBuffer[index] = (byte)((((pixels[x / 8]) & (1 << (7 - (x % 8)))) > 0) ? 255 : 0);
                            }
                            pixels += bitmap.Pitch;
                        }
                    }
                    else
                    {
                        // Pixels are 8 bits gray levels
                        for (int y = 0; y < height; ++y)
                        {
                            for (int x = 0; x < width; ++x)
                            {
                                // The color channels remain white, just fill the alpha channel
                                int index = (x + y * width) * 4 + 3;
                                pixelBuffer[index] = pixels[x];
                            }
                            pixels += bitmap.Pitch;
                        }
                    }
                }

                // Write the pixels to the texture
                int tx = glyph.TexCoords.Left;
                int ty = glyph.TexCoords.Top;
                int tw = glyph.TexCoords.Width;
                int th = glyph.TexCoords.Height;
                page.texture.Update(pixelBuffer, tx, ty, tw, th);
            }

            // Delete the FT glyph
            glyphDesc.Dispose();

            return(glyph);
        }