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)); }
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; }
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); }
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); } }
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); }
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(); }
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 }); } } }
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; }
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; }
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; }
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); } }