예제 #1
0
 public void SetGlyphRun(float x, float y, int glyphCount, short[] glyphIndices, float[] glyphAdvances, GlyphOffset[] glyphOffsets, FontFace fontface, float fontEmSize, int BidiLevel, bool isSideways)
 {
     // Append this glyph run to the list.
     int glyphStart = glyphAdvances_.Count;
     glyphAdvances_.AddRange(glyphAdvances);
     glyphIndices_.AddRange(glyphIndices);
     glyphOffsets_.AddRange(glyphOffsets);
     glyphRuns_.Add(new CustomGlyphRun(fontface, fontEmSize, x, y, glyphStart, glyphCount, BidiLevel, isSideways));
 }
예제 #2
0
 public CustomGlyphRun(FontFace _fontFace, float _fontEmSize, float _x, float _y, int _glyphStart, int _glyphCount, int _bidiLevel, bool _isSideways)
 {
     fontFace = _fontFace;
     fontEmSize = _fontEmSize;
     x = _x;
     y = _y;
     glyphStart = _glyphStart;
     glyphCount = _glyphCount;
     bidiLevel = _bidiLevel;
     isSideways = _isSideways;
 }
예제 #3
0
            private (DWrite.Font font, DWrite.FontFace fontFace) GetOrAdd(DWrite.FontWeight weight, DWrite.FontStyle style)
            {
                if (!this.fontCache.TryGetValue((weight, style), out var v))
                {
                    var font     = this.fontFamily.GetFirstMatchingFont(weight, DWrite.FontStretch.Normal, style);
                    var fontFace = new DWrite.FontFace(font);
                    v = (font, fontFace);
                    this.fontCache.Add((weight, style), v);
                }

                return(v);
            }
예제 #4
0
파일: FontHandler.cs 프로젝트: pcdummy/Eto
        private void Create(string familyName, float sizeInPoints, FontStyle style)
        {
            // family name
            this.familyName = familyName;

            // font style
            this.style = style;

            sw.FontStyle  s;
            sw.FontWeight w;
            Conversions.Convert(style, out s, out w);

            this.textFormat =
                new sw.TextFormat(
                    Factory,
                    familyName,
                    null, // font collection
                    w,
                    s,
                    sw.FontStretch.Normal,
                    sizeInPoints, // TODO: should this be in pixels? The documentation says device-independent pixels.
                    "en-us");

            // Create a font collection
            var collection = FontCollection();

            int index = 0;

            if (collection.FindFamilyName(
                    familyName: familyName,
                    index: out index))
            {
                // font family
                var fontFamily =
                    collection.GetFontFamily(index);

                Conversions.Convert(
                    style,
                    out fontStyle,
                    out fontWeight);

                // font
                this.Control =
                    fontFamily.GetFirstMatchingFont(
                        fontWeight,
                        sw.FontStretch.Normal,
                        fontStyle);

                // finally, the font face
                this.fontFace = new sw.FontFace(Control);
            }
        }
예제 #5
0
파일: FontHandler.cs 프로젝트: pcdummy/Eto
        protected override void Dispose(bool disposing)
        {
            if (this.textFormat != null)
            {
                this.textFormat.Dispose();
                this.textFormat = null;
            }

            if (this.fontFace != null)
            {
                this.fontFace.Dispose();
                this.fontFace = null;
            }

            base.Dispose(disposing);
        }
예제 #6
0
        static void Main(string[] args)
        {

            Console.WriteLine("Press enter to exit");

            var factory = new Factory();
            var fontCollection = factory.GetSystemFontCollection(false);
            var familyCount = fontCollection.FontFamilyCount;
            for (int i = 0; i < familyCount; i++)
            {
                var fontFamily = fontCollection.GetFontFamily(i);
                var familyNames = fontFamily.FamilyNames;
                int index;

                if (!familyNames.FindLocaleName(CultureInfo.CurrentCulture.Name, out index))
                    familyNames.FindLocaleName("en-us", out index);

                string name = familyNames.GetString(index);
                Console.WriteLine(name);

                var fontCount = fontFamily.FontCount;
                for (int fontIndex = 0; fontIndex < fontCount; fontIndex++)
                {
                    var font = fontFamily.GetFont(fontIndex);
                    var fontFace = new FontFace(font);
                    var files = fontFace.GetFiles();
                    foreach (var file in files)
                    {
                        var referenceKey = file.GetReferenceKey();
                        var originalLoader = (FontFileLoaderNative)file.Loader;
                        var loader = originalLoader.QueryInterface<LocalFontFileLoader>();

                        var fontFilePath = loader.GetFilePath(referenceKey);
                        Console.WriteLine("\tFile path: {0}", fontFilePath);
                    }
                }
            }

            Console.WriteLine("Press enter to exit");
            Console.In.ReadLine();
        }
예제 #7
0
        private static void GetKerningInfo(CCRawList<char> charset)
        {
            _abcValues.Clear();

            var fontFace = new FontFace(_currentFont);
            
            var value = new ABCFloat[1];

            var glyphRun = new GlyphRun();
            glyphRun.FontFace = fontFace;
            glyphRun.FontSize = _currentDIP;

            var BrushColor = SharpDX.Color.White;
            /*
            SharpDX.DirectWrite.Matrix mtrx = new SharpDX.DirectWrite.Matrix();
            mtrx.M11 = 1F;
            mtrx.M12 = 0;
            mtrx.M21 = 0;
            mtrx.M22 = 1F;
            mtrx.Dx = 0;
            mtrx.Dy = 0;
            */
            //GlyphMetrics[] metrics = fontFace.GetGdiCompatibleGlyphMetrics(23, 1, mtrx, false, glyphIndices, false);

            //FontMetrics metr = fontFace.GetGdiCompatibleMetrics(23, 1, new SharpDX.DirectWrite.Matrix());
            //_pRenderTarget.DrawGlyphRun(new SharpDX.DrawingPointF(left, top), glyphRun, new SharpDX.Direct2D1.SolidColorBrush(_pRenderTarget, BrushColor), MeasuringMode.GdiClassic);
            int[] codePoints = new int[1];
            var unitsPerEm = fontFace.Metrics.DesignUnitsPerEm;
            var familyName = _currentFont.ToString();

            
            for (int i = 0; i < charset.Count; i++)
            {
                var ch = charset[i];
                if (!_abcValues.ContainsKey(ch))
                {
                    var textLayout = new TextLayout(FactoryDWrite, ch.ToString(), textFormat, unitsPerEm, unitsPerEm);

                    var tlMetrics = textLayout.Metrics;
                    var tlmWidth = tlMetrics.Width;
                    var tllWidth = tlMetrics.LayoutWidth;

                    codePoints[0] = (int)ch;
                    short[] glyphIndices = fontFace.GetGlyphIndices(codePoints);
                    glyphRun.Indices = glyphIndices;

                    var metrics = fontFace.GetDesignGlyphMetrics(glyphIndices, false);
                    
                    //var width = metrics[0].AdvanceWidth + metrics[0].LeftSideBearing + metrics[0].RightSideBearing;
                    //var glyphWidth = _currentFontSizeEm * (float)metrics[0].AdvanceWidth / unitsPerEm;
                    //var abcWidth = _currentDIP * (float)width / unitsPerEm;

                    //value[0].abcfA = _currentFontSizeEm * (float)metrics[0].LeftSideBearing / unitsPerEm;
                    //value[0].abcfB = _currentFontSizeEm * (float)metrics[0].AdvanceWidth / unitsPerEm;
                    //value[0].abcfC = _currentFontSizeEm * (float)metrics[0].RightSideBearing / unitsPerEm;

                    // The A and C values are throwing the spacing off
                    //value[0].abcfA = _currentDIP * (float)metrics[0].LeftSideBearing / unitsPerEm;
                    value[0].abcfB = _currentDIP * (float)metrics[0].AdvanceWidth / unitsPerEm;
                    //value[0].abcfC = _currentDIP * (float)metrics[0].RightSideBearing / unitsPerEm;

                    _abcValues.Add(
                        ch,
                        new KerningInfo()
                        {
                            A = value[0].abcfA,
                            B = value[0].abcfB,
                            C = value[0].abcfC
                        });
                }
            }

        }
예제 #8
0
        private Glyph ImportGlyph(Factory factory, FontFace fontFace, char character, FontMetrics fontMetrics, float fontSize, FontAntiAliasMode antiAliasMode)
        {
            var indices = fontFace.GetGlyphIndices(new int[] { character });

            var metrics = fontFace.GetDesignGlyphMetrics(indices, false);
            var metric = metrics[0];

            var width = (float)(metric.AdvanceWidth - metric.LeftSideBearing - metric.RightSideBearing) / fontMetrics.DesignUnitsPerEm * fontSize;
            var height = (float)(metric.AdvanceHeight - metric.TopSideBearing - metric.BottomSideBearing) / fontMetrics.DesignUnitsPerEm * fontSize;

            var xOffset = (float)metric.LeftSideBearing / fontMetrics.DesignUnitsPerEm * fontSize;
            var yOffset = (float)(metric.TopSideBearing - metric.VerticalOriginY) / fontMetrics.DesignUnitsPerEm * fontSize;

            var advanceWidth = (float)metric.AdvanceWidth / fontMetrics.DesignUnitsPerEm * fontSize;
            //var advanceHeight = (float)metric.AdvanceHeight / fontMetrics.DesignUnitsPerEm * fontSize;

            var pixelWidth = (int)Math.Ceiling(width + 4);
            var pixelHeight = (int)Math.Ceiling(height + 4);

            var matrix = new RawMatrix3x2
            {
                M11 = 1,
                M22 = 1,
                M31 = -(float)Math.Floor(xOffset) + 1,
                M32 = -(float)Math.Floor(yOffset) + 1
            };

            Bitmap bitmap;
            if (char.IsWhiteSpace(character))
            {
                bitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
            }
            else
            {
                var glyphRun = new GlyphRun
                {
                    FontFace = fontFace,
                    Advances = new[] { (float)Math.Ceiling(advanceWidth) },
                    FontSize = fontSize,
                    BidiLevel = 0,
                    Indices = indices,
                    IsSideways = false,
                    Offsets = new[] { new GlyphOffset() }
                };


                RenderingMode renderingMode;
                if (antiAliasMode != FontAntiAliasMode.Aliased)
                {
                    var rtParams = new RenderingParams(factory);
                    renderingMode = fontFace.GetRecommendedRenderingMode(fontSize, 1.0f, MeasuringMode.Natural, rtParams);
                    rtParams.Dispose();
                }
                else
                {
                    renderingMode = RenderingMode.Aliased;
                }

                using (var runAnalysis = new GlyphRunAnalysis(factory,
                    glyphRun,
                    1.0f,
                    matrix,
                    renderingMode,
                    MeasuringMode.Natural,
                    0.0f,
                    0.0f))
                {

                    var bounds = new RawRectangle(0, 0, pixelWidth, pixelHeight);
                    bitmap = new Bitmap(pixelWidth, pixelHeight, PixelFormat.Format32bppArgb);

                    if (renderingMode == RenderingMode.Aliased)
                    {

                        var texture = new byte[pixelWidth * pixelHeight];
                        runAnalysis.CreateAlphaTexture(TextureType.Aliased1x1, bounds, texture, texture.Length);
                        for (int y = 0; y < pixelHeight; y++)
                        {
                            for (int x = 0; x < pixelWidth; x++)
                            {
                                int pixelX = y * pixelWidth + x;
                                var grey = texture[pixelX];
                                var color = Color.FromArgb(grey, grey, grey);

                                bitmap.SetPixel(x, y, color);
                            }
                        }
                    }
                    else
                    {
                        var texture = new byte[pixelWidth * pixelHeight * 3];
                        runAnalysis.CreateAlphaTexture(TextureType.Cleartype3x1, bounds, texture, texture.Length);
                        for (int y = 0; y < pixelHeight; y++)
                        {
                            for (int x = 0; x < pixelWidth; x++)
                            {
                                int pixelX = (y * pixelWidth + x) * 3;
                                var red = LinearToGamma(texture[pixelX]);
                                var green = LinearToGamma(texture[pixelX + 1]);
                                var blue = LinearToGamma(texture[pixelX + 2]);
                                var color = Color.FromArgb(red, green, blue);

                                bitmap.SetPixel(x, y, color);
                            }
                        }
                    }
                }
            }

            var glyph = new Glyph(character, bitmap)
            {
                XOffset = -matrix.M31,
                XAdvance = advanceWidth,
                YOffset = -matrix.M32,
            };
            return glyph;
        }
        /// <summary>
        /// Imports a single glyph as a bitmap using the msdfgen to convert it to a signed distance field image
        /// </summary>
        /// <param name="fontFace">FontFace, use to obtain the metrics for the glyph</param>
        /// <param name="character">The glyph's character code</param>
        /// <param name="fontMetrics">Font metrics, used to obtain design units scale</param>
        /// <param name="fontSize">Requested font size. The bigger, the more precise the SDF image is going to be</param>
        /// <returns></returns>
        private Glyph ImportGlyph(FontFace fontFace, char character, FontMetrics fontMetrics, float fontSize)
        {
            var indices = fontFace.GetGlyphIndices(new int[] { character });

            var metrics = fontFace.GetDesignGlyphMetrics(indices, false);
            var metric = metrics[0];

            var width = (float)(metric.AdvanceWidth - metric.LeftSideBearing - metric.RightSideBearing) / fontMetrics.DesignUnitsPerEm * fontSize;
            var height = (float)(metric.AdvanceHeight - metric.TopSideBearing - metric.BottomSideBearing) / fontMetrics.DesignUnitsPerEm * fontSize;

            var xOffset = (float)metric.LeftSideBearing / fontMetrics.DesignUnitsPerEm * fontSize;
            var yOffset = (float)(metric.TopSideBearing - metric.VerticalOriginY) / fontMetrics.DesignUnitsPerEm * fontSize;

            var advanceWidth = (float)metric.AdvanceWidth / fontMetrics.DesignUnitsPerEm * fontSize;
            //var advanceHeight = (float)metric.AdvanceHeight / fontMetrics.DesignUnitsPerEm * fontSize;

            var pixelWidth = (int)Math.Ceiling(width + 4);
            var pixelHeight = (int)Math.Ceiling(height + 4);


            var matrixM31 = -(float)Math.Floor(xOffset) + 1;
            var matrixM32 = -(float)Math.Floor(yOffset) + 1;

            Bitmap bitmap;
            if (char.IsWhiteSpace(character))
            {
                bitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
            }
            else
            {
                bitmap = LoadSDFBitmap(character, pixelWidth, pixelHeight, 1, 1);
            }

            var glyph = new Glyph(character, bitmap)
            {
                XOffset = -matrixM31,
                XAdvance = advanceWidth,
                YOffset = -matrixM32,
            };

            return glyph;
        }
예제 #10
0
        private Glyph ImportGlyph(Factory factory, FontFace fontFace, char character, FontMetrics fontMetrics, float fontSize, bool activateAntiAliasDetection)
        {
            var indices = fontFace.GetGlyphIndices(new int[] {character});

            var metrics = fontFace.GetDesignGlyphMetrics(indices, false);
            var metric = metrics[0];

            var width = (float)(metric.AdvanceWidth - metric.LeftSideBearing - metric.RightSideBearing) / fontMetrics.DesignUnitsPerEm * fontSize;
            var height = (float)(metric.AdvanceHeight - metric.TopSideBearing - metric.BottomSideBearing) / fontMetrics.DesignUnitsPerEm * fontSize;

            var xOffset = (float)metric.LeftSideBearing / fontMetrics.DesignUnitsPerEm * fontSize;
            var yOffset = (float)(metric.TopSideBearing - metric.VerticalOriginY) / fontMetrics.DesignUnitsPerEm * fontSize;

            var advanceWidth = (float)(metric.AdvanceWidth) / fontMetrics.DesignUnitsPerEm * fontSize;
            var advanceHeight = (float)(metric.AdvanceHeight) / fontMetrics.DesignUnitsPerEm * fontSize;

            var pixelWidth = (int)Math.Ceiling(width + 2);
            var pixelHeight = (int)Math.Ceiling(height + 2);

            Bitmap bitmap;
            if(char.IsWhiteSpace(character))
            {
                bitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
            }
            else
            {
                var glyphRun = new GlyphRun()
                               {
                                   FontFace = fontFace,
                                   Advances = new[] { (float)Math.Round(advanceWidth) },
                                   FontSize = fontSize,
                                   BidiLevel = 0,
                                   Indices = indices,
                                   IsSideways = false,
                                   Offsets = new[] {new GlyphOffset()}
                               };

                var matrix = SharpDX.Matrix.Identity;
                matrix.M41 = -(float)Math.Floor(xOffset - 1);
                matrix.M42 = -(float)Math.Floor(yOffset - 1);

                RenderingMode renderingMode;
                if (activateAntiAliasDetection)
                {
                    var rtParams = new RenderingParams(factory);
                    renderingMode = fontFace.GetRecommendedRenderingMode(fontSize, 1.0f, MeasuringMode.Natural, rtParams);
                    rtParams.Dispose();
                }
                else
                {
                    renderingMode = RenderingMode.Aliased;
                }

                using(var runAnalysis = new GlyphRunAnalysis(factory,
                    glyphRun,
                    1.0f,
                    matrix,
                    renderingMode,
                    MeasuringMode.Natural,
                    0.0f,
                    0.0f))
                {
                    var bounds = new SharpDX.Rectangle(0, 0, pixelWidth, pixelHeight);
                    bitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);

                    if(renderingMode == RenderingMode.Aliased)
                    {
                        var texture = new byte[bounds.Width * bounds.Height];
                        runAnalysis.CreateAlphaTexture(TextureType.Aliased1x1, bounds, texture, texture.Length);
                        bitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
                        for (int y = 0; y < bounds.Height; y++)
                        {
                            for (int x = 0; x < bounds.Width; x++)
                            {
                                int pixelX = y * bounds.Width + x;
                                var grey = texture[pixelX];
                                var color = Color.FromArgb(grey, grey, grey);

                                bitmap.SetPixel(x, y, color);
                            }
                        }
                    }
                    else
                    {
                        var texture = new byte[bounds.Width * bounds.Height * 3];
                        runAnalysis.CreateAlphaTexture(TextureType.Cleartype3x1, bounds, texture, texture.Length);
                        for (int y = 0; y < bounds.Height; y++)
                        {
                            for (int x = 0; x < bounds.Width; x++)
                            {
                                int pixelX = (y * bounds.Width + x) * 3;
                                var red = texture[pixelX];
                                var green = texture[pixelX + 1];
                                var blue = texture[pixelX + 2];
                                var color = Color.FromArgb(red, green, blue);

                                bitmap.SetPixel(x, y, color);
                            }
                        }
                    }

                    //var positionUnderline = (float)fontMetrics.UnderlinePosition / fontMetrics.DesignUnitsPerEm * fontSize;
                    //var positionUnderlineSize = (float)fontMetrics.UnderlineThickness / fontMetrics.DesignUnitsPerEm * fontSize;
                }
            }

            var glyph = new Glyph(character, bitmap)
                        {
                            XOffset = (float)Math.Floor(xOffset-1),
                            XAdvance = (float)Math.Round(advanceWidth),
                            YOffset = (float)Math.Floor(yOffset-1),
                        };
            return glyph;
        }
예제 #11
0
        public void Import(FontDescription options)
        {
            //ImportBitmapFonts(options);
            //return;
            var factory = new DirectWrite.Factory();
            DirectWrite.Font font = null;

            using (var fontCollection = factory.GetSystemFontCollection(false))
            {
                int index;
                if(!fontCollection.FindFamilyName(options.FontName, out index))
                {
                    // Lets try to import System.Drawing for old system bitmap fonts (like MS Sans Serif)
                    throw new FontException(string.Format("Can't find font '{0}'.", options.FontName));
                }

                using(var fontFamily = fontCollection.GetFontFamily(index))
                {
                    var weight = FontWeight.Regular;
                    var style = DirectWrite.FontStyle.Normal;
                    switch(options.Style)
                    {
                        case FontStyle.Bold:
                            weight = FontWeight.Bold;
                            break;
                        case FontStyle.Italic:
                            weight = FontWeight.Regular;
                            style = DirectWrite.FontStyle.Italic;
                            break;
                        case FontStyle.Regular:
                            weight = FontWeight.Regular;
                            break;
                    }

                    font = fontFamily.GetFirstMatchingFont(weight, DirectWrite.FontStretch.Normal, style);
                }
            }

            var fontFace = new FontFace(font);
            var fontMetrics = fontFace.Metrics;

            // Create a bunch of GDI+ objects.
            var fontSize = PointsToPixels(options.Size);
            
            // Which characters do we want to include?
            var characters = CharacterRegion.Flatten(options.CharacterRegions);

            var glyphList = new List<Glyph>();

            // Store the font height.
            LineSpacing = (float)Math.Round((float)(fontMetrics.LineGap + fontMetrics.Ascent + fontMetrics.Descent) / fontMetrics.DesignUnitsPerEm * fontSize);

            var baseLine = (float)Math.Round((float)(fontMetrics.LineGap + fontMetrics.Ascent) / fontMetrics.DesignUnitsPerEm * fontSize);

            // If font size <= 13, use aliased fonts instead
            bool activateAntiAliasDetection = options.Size > 13;

            // Rasterize each character in turn.
            foreach (char character in characters)
            {
                var glyph = ImportGlyph(factory, fontFace, character, fontMetrics, fontSize, activateAntiAliasDetection);
                glyph.YOffset += baseLine;

                glyphList.Add(glyph);
            }

            Glyphs = glyphList;

        }
예제 #12
0
        public void SetTextFormat(TextFormat textFormat)
        {
            // Initializes properties using a text format, like font family, font size,
            // and reading direction. For simplicity, this custom layout supports
            // minimal formatting. No mixed formatting or alignment modes are supported.
            readingDirection_ = textFormat.ReadingDirection;
            fontEmSize_ = textFormat.FontSize;
            localName_ = textFormat.LocaleName;

            // Map font and style to fontFace.
            FontCollection fontCollection = textFormat.FontCollection;// Need the font collection to map from font name to actual font.
            if (fontCollection == null)
                fontCollection = dwriteFactory_.GetSystemFontCollection(false);// No font collection was set in the format, so use the system default.

            // Find matching family name in collection.
            String fontFamilyName = textFormat.FontFamilyName;

            int fontIndex;
            // If the given font does not exist, take what we can get
            // (displaying something instead nothing), choosing the foremost
            // font in the collection.
            if (!fontCollection.FindFamilyName(fontFamilyName, out fontIndex))
                fontIndex = 0;

            FontFamily fontFamily = fontCollection.GetFontFamily(fontIndex);
            Font font = fontFamily.GetFirstMatchingFont(textFormat.FontWeight, textFormat.FontStretch, textFormat.FontStyle);
            fontFace_ = new FontFace(font);

            font.Dispose();
            fontFamily.Dispose();
            fontCollection.Dispose();
        }
        public override string GetFontPath(AssetCompilerResult result = null)
        {
            using (var factory = new Factory())
            {
                Font font;

                using (var fontCollection = factory.GetSystemFontCollection(false))
                {
                    int index;
                    if (!fontCollection.FindFamilyName(FontName, out index))
                    {
                        result?.Error("Cannot find system font '{0}'. Make sure it is installed on this machine.", FontName);
                        return null;
                    }

                    using (var fontFamily = fontCollection.GetFontFamily(index))
                    {
                        var weight = Style.IsBold() ? FontWeight.Bold : FontWeight.Regular;
                        var style = Style.IsItalic() ? SharpDX.DirectWrite.FontStyle.Italic : SharpDX.DirectWrite.FontStyle.Normal;
                        font = fontFamily.GetFirstMatchingFont(weight, FontStretch.Normal, style);
                        if (font == null)
                        {
                            result?.Error("Cannot find style '{0}' for font family {1}. Make sure it is installed on this machine.", Style, FontName);
                            return null;
                        }
                    }
                }

                var fontFace = new FontFace(font);

                // get the font path on the hard drive
                var file = fontFace.GetFiles().First();
                var referenceKey = file.GetReferenceKey();
                var originalLoader = (FontFileLoaderNative)file.Loader;
                var loader = originalLoader.QueryInterface<LocalFontFileLoader>();
                return loader.GetFilePath(referenceKey);
            }
        }