Example #1
0
        // https://www.freetype.org/freetype2/docs/glyphs/glyphs-3.html
        // https://github.com/Robmaister/SharpFont/blob/master/Source/SharpFont/GlyphSlot.cs

        public TTFGlyph(char c, uint index, byte[] bufferData, GlyphMetrics metrics, int bitmapLeft, GraphicsDevice graphics)
        {
            C          = c;
            Index      = index;
            Width      = (int)metrics.Width;
            Height     = (int)metrics.Height;
            AdvanceX   = (int)metrics.HorizontalAdvance;
            BearingX   = (int)metrics.HorizontalBearingX;
            BearingY   = (int)metrics.HorizontalBearingY;
            BitmapLeft = bitmapLeft;

            // turn buffer data into texture
            Texture = new Texture2D(graphics, Width, Height);
            Color[] colors = new Color[Width * Height];
            for (int j = 0; j < Height; j++)
            {
                for (int i = 0; i < Width; i++)
                {
                    var src = (j * Width) + i;
                    colors[src] = Color.FromNonPremultiplied(255, 255, 255, bufferData[src]);
                }
            }
            Texture.SetData(colors);
            Clip = new Rectangle(0, 0, Texture.Width, Texture.Height);
        }
Example #2
0
        public void GlyphMetricsVerticalMatchesReference()
        {
            // Compared to EveryFonts TTFDump metrics
            // https://everythingfonts.com/ttfdump
            var        collection = new FontCollection();
            FontFamily family     = collection.Add(TestFonts.NotoSansSCThinFile);
            Font       font       = family.CreateFont(12);

            var          codePoint     = new CodePoint('A');
            GlyphMetrics glyphMetrics  = font.FontMetrics.GetGlyphMetrics(codePoint, ColorFontSupport.None).First();
            GlyphMetrics glyphMetrics1 = font.GetGlyphs(codePoint, ColorFontSupport.None).First().GlyphMetrics;

            Assert.Equal(glyphMetrics, glyphMetrics1);

            // Position 0.
            Assert.Equal(codePoint, glyphMetrics.CodePoint);
            Assert.Equal(font.FontMetrics.UnitsPerEm, glyphMetrics.UnitsPerEm);
            Assert.Equal(glyphMetrics.UnitsPerEm * 72F, glyphMetrics.ScaleFactor);
            Assert.Equal(364, glyphMetrics.AdvanceWidth);
            Assert.Equal(1000, glyphMetrics.AdvanceHeight);
            Assert.Equal(265, glyphMetrics.Width);
            Assert.Equal(666, glyphMetrics.Height);
            Assert.Equal(33, glyphMetrics.LeftSideBearing);
            Assert.Equal(134, glyphMetrics.TopSideBearing);
            Assert.Equal(GlyphType.Fallback, glyphMetrics.GlyphType);
        }
Example #3
0
        /// <summary>
        /// Obtains ideal (resolution-independent) glyph metrics in font design units.
        /// </summary>
        /// <remarks>
        /// Design glyph metrics are used for glyph positioning.
        /// </remarks>
        /// <param name="glyphIndices">An array of glyph indices for which to compute  metrics. The array must contain at least as many elements as specified by glyphCount. </param>
        /// <param name="isSideways">Indicates whether the font is being used in a sideways run. This can affect the glyph metrics if the font has oblique simulation because sideways oblique simulation differs from non-sideways oblique simulation </param>
        /// <returns>an array of <see cref="GlyphMetrics"/> structures. </returns>
        /// <unmanaged>HRESULT IDWriteFontFace::GetDesignGlyphMetrics([In, Buffer] const short* glyphIndices,[None] int glyphCount,[Out, Buffer] DWRITE_GLYPH_METRICS* glyphMetrics,[None] BOOL isSideways)</unmanaged>
        public GlyphMetrics[] GetDesignGlyphMetrics(short[] glyphIndices, bool isSideways)
        {
            var glyphMetrics = new GlyphMetrics[glyphIndices.Length];

            GetDesignGlyphMetrics(glyphIndices, glyphIndices.Length, glyphMetrics, isSideways);
            return(glyphMetrics);
        }
Example #4
0
        public void GlyphMetricsMatchesReference_WithWoff1format()
        {
            // Compared to EveryFonts TTFDump metrics
            // https://everythingfonts.com/ttfdump
            var        collection = new FontCollection();
            FontFamily family     = collection.Add(TestFonts.OpenSansFileWoff1);
            Font       font       = family.CreateFont(12);

            var          codePoint     = new CodePoint('A');
            GlyphMetrics glyphMetrics  = font.FontMetrics.GetGlyphMetrics(codePoint, ColorFontSupport.None).First();
            GlyphMetrics glyphMetrics1 = font.GetGlyphs(codePoint, ColorFontSupport.None).First().GlyphMetrics;

            Assert.Equal(glyphMetrics, glyphMetrics1);

            Assert.Equal(codePoint, glyphMetrics.CodePoint);
            Assert.Equal(font.FontMetrics.UnitsPerEm, glyphMetrics.UnitsPerEm);
            Assert.Equal(glyphMetrics.UnitsPerEm * 72F, glyphMetrics.ScaleFactor);
            Assert.Equal(1295, glyphMetrics.AdvanceWidth);
            Assert.Equal(2789, glyphMetrics.AdvanceHeight);
            Assert.Equal(1293, glyphMetrics.Width);
            Assert.Equal(1468, glyphMetrics.Height);
            Assert.Equal(0, glyphMetrics.LeftSideBearing);
            Assert.Equal(721, glyphMetrics.TopSideBearing);
            Assert.Equal(GlyphType.Standard, glyphMetrics.GlyphType);
        }
Example #5
0
        internal override void BuildNodes(XmlElement parent, XmlDocument doc)
        {
            XmlNode root = doc.CreateElement("BitmapFont");

            XmlHelper.AppendAttribute(root, doc, "name", Name);
            XmlHelper.AppendAttribute(root, doc, "image", mImage);

            XmlNode metrics = doc.CreateElement("Metrics");

            foreach (char glyph in mMetrics.Keys)
            {
                XmlNode      current      = doc.CreateElement("Glyph");
                GlyphMetrics glyphMetrics = mMetrics[glyph];

                XmlHelper.AppendAttribute(current, doc, "char", glyph);
                XmlHelper.AppendAttribute(current, doc, "source", glyphMetrics.SourceRect.ToString());

                if (glyphMetrics.LeftOverhang != 0)
                {
                    XmlHelper.AppendAttribute(current, doc, "leftOverhang", glyphMetrics.LeftOverhang);
                }
                if (glyphMetrics.RightOverhang != 0)
                {
                    XmlHelper.AppendAttribute(current, doc, "rightOverhang", glyphMetrics.RightOverhang);
                }

                metrics.AppendChild(current);
            }

            root.AppendChild(metrics);
            parent.AppendChild(root);
        }
Example #6
0
        /// <summary>
        /// Obtains glyph metrics in font design units with the return values compatible with what GDI would produce.
        /// </summary>
        /// <param name="fontSize">The logical size of the font in DIP units. </param>
        /// <param name="pixelsPerDip">The number of physical pixels per DIP. </param>
        /// <param name="transform">An optional transform applied to the glyphs and their positions. This transform is applied after the scaling specified by the font size and pixelsPerDip. </param>
        /// <param name="useGdiNatural">When set to FALSE, the metrics are the same as the metrics of GDI aliased text.  When set to TRUE, the metrics are the same as the metrics of text measured by GDI using a font created with CLEARTYPE_NATURAL_QUALITY. </param>
        /// <param name="glyphIndices">An array of glyph indices for which to compute the metrics. </param>
        /// <param name="isSideways">A BOOL value that indicates whether the font is being used in a sideways run.  This can affect the glyph metrics if the font has oblique simulation because sideways oblique simulation differs from non-sideways oblique simulation. </param>
        /// <returns>An array of <see cref="T:SharpDX.DirectWrite.GlyphMetrics" /> structures filled by this function. The metrics are in font design units. </returns>
        /// <unmanaged>HRESULT IDWriteFontFace::GetGdiCompatibleGlyphMetrics([None] float emSize,[None] float pixelsPerDip,[In, Optional] const DWRITE_MATRIX* transform,[None] BOOL useGdiNatural,[In, Buffer] const short* glyphIndices,[None] int glyphCount,[Out, Buffer] DWRITE_GLYPH_METRICS* glyphMetrics,[None] BOOL isSideways)</unmanaged>
        public GlyphMetrics[] GetGdiCompatibleGlyphMetrics(float fontSize, float pixelsPerDip, RawMatrix3x2?transform, bool useGdiNatural, short[] glyphIndices, bool isSideways)
        {
            var glyphMetrics = new GlyphMetrics[glyphIndices.Length];

            GetGdiCompatibleGlyphMetrics(fontSize, pixelsPerDip, transform, useGdiNatural, glyphIndices, glyphIndices.Length, glyphMetrics, isSideways);
            return(glyphMetrics);
        }
 public GlyphMarshallingStruct(uint index, GlyphMetrics metrics, GlyphRect glyphRect, float scale, int atlasIndex)
 {
     this.index      = index;
     this.metrics    = metrics;
     this.glyphRect  = glyphRect;
     this.scale      = scale;
     this.atlasIndex = atlasIndex;
 }
Example #8
0
 /// <summary>
 /// Constructor for new sprite glyph.
 /// </summary>
 /// <param name="index">Index of the sprite glyph.</param>
 /// <param name="metrics">Metrics which define the position of the glyph in the context of text layout.</param>
 /// <param name="glyphRect">GlyphRect which defines the coordinates of the glyph in the atlas texture.</param>
 /// <param name="scale">Scale of the glyph.</param>
 /// <param name="atlasIndex">Index of the atlas texture that contains the glyph.</param>
 public TMP_SpriteGlyph(uint index, GlyphMetrics metrics, GlyphRect glyphRect, float scale, int atlasIndex)
 {
     this.index      = index;
     this.metrics    = metrics;
     this.glyphRect  = glyphRect;
     this.scale      = scale;
     this.atlasIndex = atlasIndex;
 }
 public GlyphMarshallingStruct(Glyph glyph)
 {
     this.index      = glyph.index;
     this.metrics    = glyph.metrics;
     this.glyphRect  = glyph.glyphRect;
     this.scale      = glyph.scale;
     this.atlasIndex = glyph.atlasIndex;
 }
 /// <summary>
 /// Constructor for new glyph
 /// </summary>
 /// <param name="index">The index of the glyph in the font file.</param>
 /// <param name="metrics">The metrics of the glyph.</param>
 /// <param name="glyphRect">A rectangle defining the position of the glyph in the atlas texture.</param>
 /// <param name="scale">The relative scale of the glyph.</param>
 /// <param name="atlasIndex">The index of the atlas texture that contains the glyph.</param>
 /// <param name="classDefinitionType">Class definition type for the glyph.</param>
 public GlyphMarshallingStruct(uint index, GlyphMetrics metrics, GlyphRect glyphRect, float scale, int atlasIndex, GlyphClassDefinitionType classDefinitionType)
 {
     this.index               = index;
     this.metrics             = metrics;
     this.glyphRect           = glyphRect;
     this.scale               = scale;
     this.atlasIndex          = atlasIndex;
     this.classDefinitionType = classDefinitionType;
 }
Example #11
0
        /// <summary>
        /// Returns a GlyphMetrics[].
        /// </summary>
        /// <param name="length">
        /// Minimum number of elements in the array.
        /// </param>
        internal static GlyphMetrics[] GetGlyphMetrics(int length)
        {
            GlyphMetrics[] glyphMetrics = (GlyphMetrics[])GetBuffer(length, GlyphMetricsIndex);

            if (glyphMetrics == null)
            {
                glyphMetrics = new GlyphMetrics[length];
            }

            return glyphMetrics;
        }
        private GlyphMetrics GetGlyphMetrics(FontKey fontKey, string glyphLabel)
        {
            Dictionary <string, GlyphMetrics> fontCache = null;

            if (!cache.TryGetValue(fontKey, out fontCache))
            {
                fontCache      = new Dictionary <string, GlyphMetrics>();
                cache[fontKey] = fontCache;
            }

            GlyphMetrics value = null;

            if (!fontCache.TryGetValue(glyphLabel, out value))
            {
                var typeFace      = new Typeface(fontKey.FontFamily, fontKey.FontStyle, fontKey.FontWeight, fontKey.FontStretch);
                var formattedChar = new FormattedText
                                    (
                    glyphLabel, System.Globalization.CultureInfo.CurrentCulture,
                    FlowDirection.LeftToRight, typeFace, fontKey.FontSize, Brushes.Black
                                    );

                formattedChar.TextAlignment = TextAlignment.Left;

                var geometry = formattedChar.BuildGeometry(new System.Windows.Point(0.0f, 0.0f));
                var rect     = geometry.Bounds;

                // For glyph without geometry (space)
                if (rect.IsEmpty)
                {
                    rect = new Rect(0.0, 0.0, formattedChar.WidthIncludingTrailingWhitespace, formattedChar.Height);
                }

                var rectX = (float)rect.X;
                var rectY = (float)rect.Y;
                var rectW = (float)rect.Width;
                var rectH = (float)rect.Height;

                var leftBearing  = -(float)(rect.X);
                var rightBearing = 0.0f;

                var glyphX            = px2mm(rectX, dpiX);
                var glyphY            = px2mm(rectY, dpiY);
                var glyphW            = px2mm(rectW, dpiX);
                var glyphH            = px2mm(rectH, dpiY);
                var glyphRect         = new Rectangle(glyphX, glyphY, glyphW, glyphH);
                var glyphLeftBearing  = px2mm(leftBearing, dpiX);
                var glyphRightBearing = px2mm(rightBearing, dpiX);

                value = new GlyphMetrics(glyphRect, glyphLeftBearing, glyphRightBearing);
                fontCache[glyphLabel] = value;
            }

            return(new GlyphMetrics(new Rectangle(value.BoundingBox.X, value.BoundingBox.Y, value.BoundingBox.Width, value.BoundingBox.Height), value.LeftSideBearing, value.RightSideBearing));
        }
        /// <summary>
        /// Returns a GlyphMetrics[].
        /// </summary>
        /// <param name="length">
        /// Minimum number of elements in the array.
        /// </param>
        internal static GlyphMetrics[] GetGlyphMetrics(int length)
        {
            GlyphMetrics[] glyphMetrics = (GlyphMetrics[])GetBuffer(length, GlyphMetricsIndex);

            if (glyphMetrics == null)
            {
                glyphMetrics = new GlyphMetrics[length];
            }

            return(glyphMetrics);
        }
Example #14
0
 public GlyphInfo(char c, uint index, int bitmapLeft, GlyphMetrics metrics, FTBitmap bitmap)
 {
     BitmapLeft = bitmapLeft;
     Index      = index;
     Character  = c;
     Width      = (int)metrics.Width;
     Height     = (int)metrics.Height;
     Advance    = (int)metrics.HorizontalAdvance;
     BearingX   = (int)metrics.HorizontalBearingX;
     BearingY   = (int)metrics.HorizontalBearingY;
     Bitmap     = new GlyphBitmap(bitmap);
 }
Example #15
0
 public GlyphInfo(char c, uint index, int bitmapLeft, GlyphMetrics metrics, byte[] bufferData)
 {
     BitmapLeft = bitmapLeft;
     Index      = index;
     Character  = c;
     Width      = (int)metrics.Width;
     Height     = (int)metrics.Height;
     Advance    = (int)metrics.HorizontalAdvance;
     BearingX   = (int)metrics.HorizontalBearingX;
     BearingY   = (int)metrics.HorizontalBearingY;
     BufferData = bufferData;
 }
        public void LoadFont_WithWoff2Format()
        {
            Font font = new FontCollection().Add(TestFonts.OpensSansWoff2Data()).CreateFont(12);

            GlyphMetrics glyph = font.FontMetrics.GetGlyphMetrics(new CodePoint('A'), ColorFontSupport.None).First();
            var          r     = new GlyphRenderer();

            glyph.RenderTo(r, font.Size, System.Numerics.Vector2.Zero, new TextOptions(font));

            Assert.Equal(37, r.ControlPoints.Count);
            Assert.Single(r.GlyphKeys);
            Assert.Single(r.GlyphRects);
        }
        private GlyphMetrics GetGlyphMetrics(FontKey fontKey, string glyphLabel, CanvasDevice canvasDevice)
        {
            Dictionary <string, GlyphMetrics> fontCache = null;

            if (!cache.TryGetValue(fontKey, out fontCache))
            {
                fontCache      = new Dictionary <string, GlyphMetrics>();
                cache[fontKey] = fontCache;
            }

            GlyphMetrics value = null;

            if (!fontCache.TryGetValue(glyphLabel, out value))
            {
                var textFormat = new CanvasTextFormat()
                {
                    FontSize   = fontKey.FontSize,
                    FontFamily = fontKey.FontFamily,
                    FontStyle  = fontKey.FontStyle,
                    FontWeight = fontKey.FontWeight
                };

                using (var canvasCharLayout = new CanvasTextLayout(canvasDevice, glyphLabel, textFormat, 10000, 10000))
                {
                    canvasCharLayout.SetFontFamily(0, 1, fontKey.FontFamily);
                    canvasCharLayout.SetFontSize(0, 1, fontKey.FontSize);
                    canvasCharLayout.SetFontWeight(0, 1, fontKey.FontWeight);
                    canvasCharLayout.SetFontStyle(0, 1, fontKey.FontStyle);

                    var charRect         = canvasCharLayout.DrawBounds;
                    var charX            = (float)charRect.X;
                    var charY            = (float)charRect.Y - canvasCharLayout.LineMetrics[0].Baseline;
                    var charLeftBearing  = (float)(-charRect.Left);
                    var charAdvance      = canvasCharLayout.GetCaretPosition(0, true);
                    var charRightBearing = (float)(charAdvance.X - charRect.Right);

                    var glyphX            = px2mm(charX, dpiX);
                    var glyphY            = px2mm(charY, dpiY);
                    var glyphW            = px2mm((float)charRect.Width, dpiX);
                    var glyphH            = px2mm((float)charRect.Height, dpiY);
                    var glyphRect         = new Rectangle(glyphX, glyphY, glyphW, glyphH);
                    var glyphLeftBearing  = px2mm(charLeftBearing, dpiX);
                    var glyphRightBearing = px2mm(charRightBearing, dpiX);

                    value = new GlyphMetrics(glyphRect, glyphLeftBearing, glyphRightBearing);
                    fontCache[glyphLabel] = value;
                }
            }

            return(new GlyphMetrics(new Rectangle(value.BoundingBox.X, value.BoundingBox.Y, value.BoundingBox.Width, value.BoundingBox.Height), value.LeftSideBearing, value.RightSideBearing));
        }
        public void LoadFontWoff()
        {
            Font font = new FontCollection().Add(TestFonts.SimpleFontFileWoffData()).CreateFont(12);

            Assert.Equal("SixLaborsSampleAB regular", font.FontMetrics.Description.FontNameInvariantCulture);
            Assert.Equal("Regular", font.FontMetrics.Description.FontSubFamilyNameInvariantCulture);

            GlyphMetrics glyph = font.FontMetrics.GetGlyphMetrics(new CodePoint('a'), ColorFontSupport.None).First();
            var          r     = new GlyphRenderer();

            glyph.RenderTo(r, 12, System.Numerics.Vector2.Zero, new TextOptions(font));

            // the test font only has characters .notdef, 'a' & 'b' defined
            Assert.Equal(6, r.ControlPoints.Distinct().Count());
        }
Example #19
0
            public ComputedSize(float fontSize, FontMetrics fontMetrics, GlyphMetrics glyphMetrics)
            {
                var fscale = fontSize / fontMetrics.DesignUnitsPerEm;
                var l      = glyphMetrics.LeftSideBearing * fscale;
                var t      = glyphMetrics.TopSideBearing * fscale;
                var r      = glyphMetrics.RightSideBearing * fscale;
                var b      = glyphMetrics.BottomSideBearing * fscale;
                var v      = glyphMetrics.VerticalOriginY * fscale;
                var aw     = glyphMetrics.AdvanceWidth * fscale;
                var ah     = glyphMetrics.AdvanceHeight * fscale;

                offsetX   = (int)Math.Floor(l);
                offsetY   = (int)Math.Floor(t) - (int)Math.Floor(v);
                maxWidth  = (int)(aw - r - l + 2.0f);
                maxHeight = (int)(ah - b - t + 2.0f);
            }
        private void getKernWidthHeight(Face face, FontInfo info, out int width, out int maxHeight, out int firstAdjust)
        {
            width       = 0;
            maxHeight   = 0;
            firstAdjust = 0;

            for (int i = 0; i < characters.Length; i++)
            {
                char character1 = characters[i];
                uint index1     = face.GetCharIndex(character1);

                face.LoadGlyph(index1, LoadFlags.Default, LoadTarget.Normal);
                GlyphMetrics metrics = face.Glyph.Metrics;

                int yoffset = metrics.VerticalAdvance.ToInt32() - metrics.HorizontalBearingY.ToInt32();
                int nheight = yoffset + metrics.Height.ToInt32();
                int height  = metrics.Height.ToInt32();
                if (height > maxHeight)
                {
                    maxHeight   = height;                   //nheight;
                    firstAdjust = yoffset;
                }

                for (int j = 0; j < characters.Length; j++)
                {
                    char character2 = characters[j];
                    uint index2     = face.GetCharIndex(character2);

                    FTVector26Dot6 kern  = face.GetKerning(index1, index2, KerningMode.Default);
                    int            kernX = kern.X.ToInt32();
                    int            kernY = kern.Y.ToInt32();
                    if (kernX != 0 || kernY != 0)
                    {
                        info.addKerning(new KerningInfo(character1, character2, kernX, kernY));
                    }
                }

                if (i + 1 == characters.Length)
                {
                    width += metrics.Width.ToInt32() + metrics.HorizontalBearingX.ToInt32() + padX;
                }
                else
                {
                    width += metrics.HorizontalAdvance.ToInt32() + padX;
                }
            }
        }
Example #21
0
 public Character(CharacterRow row, CharacterContext context, uint id)
     : base(context.ServiceProvider)
 {
     this.context   = context ?? throw new ArgumentNullException(nameof(context));
     this.Row       = row;
     this.ID        = id;
     this.IsEnabled = this.context.Glyphs.ContainsKey(id);
     if (this.context.Glyphs.ContainsKey(id))
     {
         this.glyph        = this.context.Glyphs[id];
         this.glyphMetrics = this.context.Glyphs[id].Metrics;
     }
     else
     {
         this.glyphMetrics.VerticalAdvance = this.context.Height;
     }
     this.context.Register(this);
 }
Example #22
0
        private void PaintFontImage(Graphics g)
        {
            g.FillRectangle(Brushes.DarkRed, new Rectangle(0, 0, image.Width, image.Height));

            if (lstItems.SelectedIndex != -1)
            {
                GlyphMetrics metric = SelectedMetric;
                Rectangle    r      = metric.SourceRect.ToDrawing();


                Rectangle glyph = r;
                glyph.X     += metric.LeftOverhang;
                glyph.Width -= metric.LeftOverhang;
                glyph.Width -= metric.RightOverhang;

                g.DrawRectangle(Pens.Red, r);
                g.DrawRectangle(Pens.Blue, glyph);
            }
            g.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height));
        }
Example #23
0
        private void ReadMetrics030(XmlNode parent)
        {
            XmlNode root = null;

            // find metrics node
            foreach (XmlNode n in parent.ChildNodes)
            {
                if (n.Name == "Metrics")
                {
                    root = n;
                    break;
                }
            }

            if (root == null)
            {
                throw new AgateResourceException(string.Format(
                                                     "Could not find Metrics node in bitmap font resource {0}.", Name));
            }

            foreach (XmlNode node in root.ChildNodes)
            {
                if (node.Name != "Glyph")
                {
                    throw new AgateResourceException(string.Format(
                                                         "Expected to find glyph node, but found {0} instead.", node.Name));
                }

                GlyphMetrics glyph = new GlyphMetrics();

                char key = (char)int.Parse(node.Attributes["char"].Value);
                glyph.SourceRect = Rectangle.Parse(node.Attributes["source"].Value);

                glyph.LeftOverhang  = XmlHelper.ReadAttributeInt(node, "leftOverhang", 0);
                glyph.RightOverhang = XmlHelper.ReadAttributeInt(node, "rightOverhang", 0);

                mMetrics.Add(key, glyph);
            }
        }
Example #24
0
        private void pctImage_Paint(object sender, PaintEventArgs e)
        {
            if (image == null)
            {
                return;
            }

            e.Graphics.FillRectangle(Brushes.DarkRed, new Rectangle(0, 0, image.Width, image.Height));
            e.Graphics.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height));

            if (lstItems.SelectedIndex != -1)
            {
                char         glyph  = (char)lstItems.SelectedItem;
                GlyphMetrics metric = font[glyph];
                Color        clr    = Color.FromArgb(128, Color.Blue);

                using (Pen p = new Pen(clr))
                {
                    e.Graphics.DrawRectangle(p, Interop.Convert(metric.SourceRect));
                }
            }
        }
        private int renderCharacter(Face face, char character, int posX, int posY, int atlas, FontInfo info, Graphics graphics)
        {
            uint index = face.GetCharIndex(character);

            face.LoadGlyph(index, LoadFlags.Default, LoadTarget.Normal);
            face.Glyph.RenderGlyph(RenderMode.Normal);

            GlyphMetrics metrics    = face.Glyph.Metrics;
            int          width      = metrics.Width.ToInt32() + metrics.HorizontalBearingX.ToInt32();
            int          xAdvance   = metrics.HorizontalAdvance.ToInt32();
            int          yoffset    = metrics.VerticalAdvance.ToInt32() - metrics.HorizontalBearingY.ToInt32();
            int          charHeight = metrics.Height.ToInt32();

            if (face.Glyph.Bitmap.Width > 0)
            {
                FTBitmap ftbmp = face.Glyph.Bitmap;
                Bitmap   copy  = ftbmp.ToGdipBitmap(Color.White);
                graphics.DrawImageUnscaled(copy, posX + metrics.HorizontalBearingX.ToInt32(), posY);
            }

            info.addCharacter(new CharacterInfo(character, posX, posY, width, charHeight, xAdvance, yoffset, atlas));

            return(width);
        }
Example #26
0
 /// <summary>	
 /// Obtains glyph metrics in font design units with the return values compatible with what GDI would produce.	
 /// </summary>	
 /// <param name="fontSize">The logical size of the font in DIP units. </param>
 /// <param name="pixelsPerDip">The number of physical pixels per DIP. </param>
 /// <param name="transform">An optional transform applied to the glyphs and their positions. This transform is applied after the scaling specified by the font size and pixelsPerDip. </param>
 /// <param name="useGdiNatural">When set to FALSE, the metrics are the same as the metrics of GDI aliased text.  When set to TRUE, the metrics are the same as the metrics of text measured by GDI using a font created with CLEARTYPE_NATURAL_QUALITY. </param>
 /// <param name="glyphIndices">An array of glyph indices for which to compute the metrics. </param>
 /// <param name="isSideways">A BOOL value that indicates whether the font is being used in a sideways run.  This can affect the glyph metrics if the font has oblique simulation because sideways oblique simulation differs from non-sideways oblique simulation. </param>
 /// <returns>An array of <see cref="T:SharpDX.DirectWrite.GlyphMetrics" /> structures filled by this function. The metrics are in font design units. </returns>
 /// <unmanaged>HRESULT IDWriteFontFace::GetGdiCompatibleGlyphMetrics([None] float emSize,[None] float pixelsPerDip,[In, Optional] const DWRITE_MATRIX* transform,[None] BOOL useGdiNatural,[In, Buffer] const short* glyphIndices,[None] int glyphCount,[Out, Buffer] DWRITE_GLYPH_METRICS* glyphMetrics,[None] BOOL isSideways)</unmanaged>
 public GlyphMetrics[] GetGdiCompatibleGlyphMetrics(float fontSize, float pixelsPerDip, Matrix? transform, bool useGdiNatural, short[] glyphIndices, bool isSideways)
 {
     var glyphMetrics = new GlyphMetrics[glyphIndices.Length];
     GetGdiCompatibleGlyphMetrics(fontSize, pixelsPerDip, transform, useGdiNatural, glyphIndices, glyphIndices.Length, glyphMetrics, isSideways);
     return glyphMetrics;
 }
Example #27
0
 /// <summary>	
 /// Obtains ideal (resolution-independent) glyph metrics in font design units.  	
 /// </summary>	
 /// <remarks>	
 /// Design glyph metrics are used for glyph positioning. 	
 /// </remarks>	
 /// <param name="glyphIndices">An array of glyph indices for which to compute  metrics. The array must contain at least as many elements as specified by glyphCount. </param>
 /// <param name="isSideways">Indicates whether the font is being used in a sideways run. This can affect the glyph metrics if the font has oblique simulation because sideways oblique simulation differs from non-sideways oblique simulation </param>
 /// <returns>an array of <see cref="GlyphMetrics"/> structures. </returns>
 /// <unmanaged>HRESULT IDWriteFontFace::GetDesignGlyphMetrics([In, Buffer] const short* glyphIndices,[None] int glyphCount,[Out, Buffer] DWRITE_GLYPH_METRICS* glyphMetrics,[None] BOOL isSideways)</unmanaged>
 public GlyphMetrics[] GetDesignGlyphMetrics(short[] glyphIndices, bool isSideways)
 {
     var glyphMetrics = new GlyphMetrics[glyphIndices.Length];
     GetDesignGlyphMetrics(glyphIndices, glyphIndices.Length, glyphMetrics, isSideways);
     return glyphMetrics;
 }
Example #28
0
        private static void MakeBitmap(BitmapFontOptions options, ICharacterRenderer rend,
                                       out Drawing.Bitmap bmp, out FontMetrics glyphs)
        {
            Size bitmapSize = new Size(256, 64);

            bmp = new System.Drawing.Bitmap(bitmapSize.Width, bitmapSize.Height);
            Drawing.Graphics g    = Drawing.Graphics.FromImage(bmp);
            Drawing.Font     font = rend.Font;

            g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit;

            glyphs = new FontMetrics();

            const int bitmapPadding = 2;

            int  x = rend.Padding, y = 2;
            int  height   = 0;
            char lastChar = ' ';

            // first measure the required height of the image.
            foreach (BitmapFontOptions.CharacterRange range in options.CharacterRanges)
            {
                for (char i = range.StartChar; i <= range.EndChar; i++)
                {
                    Size sourceSize = rend.MeasureText(g, i.ToString());
                    if (options.CreateBorder)
                    {
                        sourceSize.Width  += 2;
                        sourceSize.Height += 2;
                    }

                    int thisWidth = sourceSize.Width + bitmapPadding;

                    x += thisWidth;

                    if (height < sourceSize.Height)
                    {
                        height = sourceSize.Height;
                    }

                    if (x > bitmapSize.Width)
                    {
                        x      = 1 + thisWidth;
                        y     += height + bitmapPadding + 1;
                        height = 0;
                    }

                    glyphs[i] = new GlyphMetrics(new Rectangle(0, 0, sourceSize.Width, sourceSize.Height));

                    lastChar = i;
                }
            }

            y += glyphs[lastChar].Height;

            if (y > bitmapSize.Height)
            {
                while (y > bitmapSize.Height)
                {
                    bitmapSize.Height *= 2;
                }

                g.Dispose();
                bmp.Dispose();

                bmp = new System.Drawing.Bitmap(bitmapSize.Width, bitmapSize.Height);
                g   = Drawing.Graphics.FromImage(bmp);
            }

            Drawing.Bitmap   borderBmp = new System.Drawing.Bitmap(bmp.Width, bmp.Height);
            Drawing.Graphics borderG   = Drawing.Graphics.FromImage(borderBmp);

            x      = rend.Padding;
            y      = 2;
            height = 0;
            Drawing.Color borderColor = System.Drawing.Color.FromArgb(
                options.BorderColor.A, options.BorderColor.R, options.BorderColor.G, options.BorderColor.B);

            foreach (BitmapFontOptions.CharacterRange range in options.CharacterRanges)
            {
                for (char i = range.StartChar; i <= range.EndChar; i++)
                {
                    if (x + glyphs[i].Width > bitmapSize.Width)
                    {
                        x      = rend.Padding;
                        y     += height + bitmapPadding + 1;
                        height = 0;
                    }

                    if (options.CreateBorder)
                    {
                        rend.DrawText(borderG, i.ToString(), new Point(x, y + 1), borderColor);
                        rend.DrawText(borderG, i.ToString(), new Point(x + 2, y + 1), borderColor);
                        rend.DrawText(borderG, i.ToString(), new Point(x + 1, y), borderColor);
                        rend.DrawText(borderG, i.ToString(), new Point(x + 1, y + 2), borderColor);

                        rend.DrawText(g, i.ToString(), new Point(x + 1, y + 1), System.Drawing.Color.White);

                        if (font.SizeInPoints >= 14.0)
                        {
                            glyphs[i].LeftOverhang = 1;
                        }

                        glyphs[i].RightOverhang = 1;
                    }
                    else
                    {
                        rend.DrawText(g, i.ToString(), new Point(x, y), System.Drawing.Color.White);
                    }

                    glyphs[i].SourceRect = new Rectangle(
                        new Point(x, y),
                        glyphs[i].Size);

                    x += glyphs[i].Width + bitmapPadding;

                    if (height < glyphs[i].Height)
                    {
                        height = glyphs[i].Height;
                    }
                }
            }

            g.Dispose();

            // do post processing of chars.
            PostProcessFont(options, bmp);

            // place the chars on the border image
            borderG.DrawImage(bmp, new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height));

            bmp.Dispose();
            borderG.Dispose();

            bmp = borderBmp;
        }
Example #29
0
        override public int DrawGlyph(float x, float y,
                                      List <Vector3> vertList, List <Vector2> uvList, List <Vector2> uv2List, List <Color32> colList)
        {
            GlyphMetrics metrics = _char.glyph.metrics;
            GlyphRect    rect    = _char.glyph.glyphRect;

            if (_format.specialStyle == TextFormat.SpecialStyle.Subscript)
            {
                y = y - Mathf.RoundToInt(_ascent * _scale * SupOffset);
            }
            else if (_format.specialStyle == TextFormat.SpecialStyle.Superscript)
            {
                y = y + Mathf.RoundToInt(_ascent * _scale * (1 / SupScale - 1 + SupOffset));
            }

            topLeft.x     = x + (metrics.horizontalBearingX - _padding - _stylePadding) * _scale;
            topLeft.y     = y + (metrics.horizontalBearingY + _padding) * _scale;
            bottomRight.x = topLeft.x + (metrics.width + _padding * 2 + _stylePadding * 2) * _scale;
            bottomRight.y = topLeft.y - (metrics.height + _padding * 2) * _scale;

            topRight.x   = bottomRight.x;
            topRight.y   = topLeft.y;
            bottomLeft.x = topLeft.x;
            bottomLeft.y = bottomRight.y;

            #region Handle Italic & Shearing
            if (((_style & FontStyles.Italic) == FontStyles.Italic))
            {
                // Shift Top vertices forward by half (Shear Value * height of character) and Bottom vertices back by same amount.
                float   shear_value = _fontAsset.italicStyle * 0.01f;
                Vector3 topShear    = new Vector3(shear_value * ((metrics.horizontalBearingY + _padding + _stylePadding) * _scale), 0, 0);
                Vector3 bottomShear = new Vector3(shear_value * (((metrics.horizontalBearingY - metrics.height - _padding - _stylePadding)) * _scale), 0, 0);

                topLeft     += topShear;
                bottomLeft  += bottomShear;
                topRight    += topShear;
                bottomRight += bottomShear;
            }
            #endregion Handle Italics & Shearing

            vertList.Add(bottomLeft);
            vertList.Add(topLeft);
            vertList.Add(topRight);
            vertList.Add(bottomRight);

            float u  = (rect.x - _padding - _stylePadding) / _fontAsset.atlasWidth;
            float v  = (rect.y - _padding - _stylePadding) / _fontAsset.atlasHeight;
            float uw = (rect.width + _padding * 2 + _stylePadding * 2) / _fontAsset.atlasWidth;
            float vw = (rect.height + _padding * 2 + _stylePadding * 2) / _fontAsset.atlasHeight;

            uvBottomLeft  = new Vector2(u, v);
            uvTopLeft     = new Vector2(u, v + vw);
            uvTopRight    = new Vector2(u + uw, v + vw);
            uvBottomRight = new Vector2(u + uw, v);

            float xScale = _scale * 0.01f;
            if (_format.bold)
            {
                xScale *= -1;
            }
            uv2BottomLeft  = new Vector2(0, xScale);
            uv2TopLeft     = new Vector2(511, xScale);
            uv2TopRight    = new Vector2(2093567, xScale);
            uv2BottomRight = new Vector2(2093056, xScale);

            uvList.Add(uvBottomLeft);
            uvList.Add(uvTopLeft);
            uvList.Add(uvTopRight);
            uvList.Add(uvBottomRight);

            uv2List.Add(uv2BottomLeft);
            uv2List.Add(uv2TopLeft);
            uv2List.Add(uv2TopRight);
            uv2List.Add(uv2BottomRight);

            colList.Add(vertexColors[0]);
            colList.Add(vertexColors[1]);
            colList.Add(vertexColors[2]);
            colList.Add(vertexColors[3]);

            return(4);
        }
        /// <summary>
        /// Gets the transformed size of a character image in a font face.
        /// </summary>
        /// <param name="fontFace">The font face.</param>
        /// <param name="glyphIndex">The index of the character glyph. Use <see cref="Face.GetCharIndex"/> to retrieve the glyph index.</param>
        /// <param name="glyphMetrics">Glyph metrics.</param>
        /// <param name="nextChar">The next character in the string. Specify a <see cref="char"/> to enable kerning calculation. When set to <see langword="null"/>, the kerning information is not calculated; instead, <see cref="defaultXSpacing"/> is used.</param>
        /// <param name="defaultXSpacing">Default X spacing value.</param>
        /// <param name="defaultYSpacing">Default Y spacing value.</param>
        /// <returns>Transformed size of the image, in pixels.</returns>
        /// <seealso cref="Face.SetCharSize"/>
        internal static Vector2 GetCharSize([NotNull] this Face fontFace, uint glyphIndex, [NotNull] GlyphMetrics glyphMetrics, [CanBeNull] char?nextChar, int defaultXSpacing, int defaultYSpacing)
        {
            var currentCharacterWidth = glyphMetrics.Width.ToInt32();

            if (nextChar != null && fontFace.HasKerning)
            {
                var kerning = fontFace.GetKerning(glyphIndex, fontFace.GetCharIndex(nextChar.Value), KerningMode.Default);

                currentCharacterWidth += kerning.X.ToInt32();
            }
            else
            {
                // We can't get the kerning value, use defaultXSpacing.
                currentCharacterWidth += defaultXSpacing;
            }

            var currentCharacterHeight = glyphMetrics.Height.ToInt32();

            currentCharacterHeight += defaultYSpacing;

            return(new Vector2(currentCharacterWidth, currentCharacterHeight));
        }
        public GlyphMetrics[] GetGlyphMetrics(MyScript.IInk.Text.Text text, TextSpan[] spans)
        {
            CanvasDevice canvasDevice = CanvasDevice.GetSharedDevice();

            GlyphMetrics[] glyphMetrics = new GlyphMetrics[text.GlyphCount];

            var firstStyle   = spans[0].Style;
            var firstFontKey = FontKeyFromStyle(firstStyle);

            if (text.GlyphCount == 1)
            {
                glyphMetrics[0] = GetGlyphMetrics(firstFontKey, text.Label, canvasDevice);
            }
            else
            {
                var textFormat = new CanvasTextFormat()
                {
                    FontSize   = mm2px(firstStyle.FontSize, dpiY),
                    FontFamily = firstStyle.FontFamily,
                    FontStyle  = firstFontKey.FontStyle,
                    FontWeight = firstFontKey.FontWeight
                };

                using (var canvasTextLayout = new CanvasTextLayout(canvasDevice, text.Label, textFormat, 10000, 10000))
                {
                    for (int i = 0; i < spans.Length; ++i)
                    {
                        var charIndex = spans[i].BeginPosition;
                        var charCount = spans[i].EndPosition - spans[i].BeginPosition;

                        var style   = spans[i].Style;
                        var fontKey = FontKeyFromStyle(style);

                        canvasTextLayout.SetFontFamily(charIndex, charCount, fontKey.FontFamily);
                        canvasTextLayout.SetFontSize(charIndex, charCount, fontKey.FontSize);
                        canvasTextLayout.SetFontWeight(charIndex, charCount, fontKey.FontWeight);
                        canvasTextLayout.SetFontStyle(charIndex, charCount, fontKey.FontStyle);
                    }

                    // Use of TextElementEnumerator to get character indices as in the CanvasTextLayout
                    var tee = StringInfo.GetTextElementEnumerator(text.Label);

                    // Use of ClusterMetrics to identify ligatures in the CanvasTextLayout
                    int cluster          = 0;
                    int clusterStartChar = 0;
                    var clusterCharCount = canvasTextLayout.ClusterMetrics[cluster].CharacterCount;

                    for (int i = 0, g = 0; i < text.GlyphCount; ++i)
                    {
                        var fontKey = new FontKey(canvasTextLayout.GetFontFamily(i)
                                                  , canvasTextLayout.GetFontSize(i)
                                                  , canvasTextLayout.GetFontWeight(i)
                                                  , canvasTextLayout.GetFontStyle(i));
                        var glyphLabel    = text.GetGlyphLabelAt(i);
                        var glyphMetrics_ = GetGlyphMetrics(fontKey, glyphLabel, canvasDevice);

                        // Find cluster associated to element
                        if (tee.MoveNext())
                        {
                            g = tee.ElementIndex;
                        }

                        while ((g < clusterStartChar) || (g >= (clusterStartChar + clusterCharCount)))
                        {
                            ++cluster;
                            clusterStartChar += clusterCharCount;
                            clusterCharCount  = canvasTextLayout.ClusterMetrics[cluster].CharacterCount;
                        }

                        if (g > clusterStartChar)
                        {
                            // Ligature with the previous glyph
                            // The position is not accurate because of glyphs substitution at rendering
                            // but it makes the illusion.
                            var prevGlyphMetrics = glyphMetrics[i - 1];
                            glyphMetrics_.BoundingBox.X = prevGlyphMetrics.BoundingBox.X
                                                          + prevGlyphMetrics.BoundingBox.Width
                                                          + prevGlyphMetrics.RightSideBearing
                                                          + glyphMetrics_.LeftSideBearing;
                        }
                        else
                        {
                            var charPos = canvasTextLayout.GetCaretPosition(g, false);
                            glyphMetrics_.BoundingBox.X += px2mm(charPos.X, dpiX);
                        }

                        glyphMetrics[i] = glyphMetrics_;
                    }
                }
            }

            return(glyphMetrics);
        }
Example #32
0
        private static void WalkDrawingForText_(Drawing drawing, List <GlyphMetrics> glyphMetrics, ref int idx, ref float x, float baseline, float dpiX, float dpiY)
        {
            var glyphs = drawing as GlyphRunDrawing;

            if (idx >= glyphMetrics.Count)
            {
                return;
            }

            if (glyphs != null)
            {
                var glyphRun   = glyphs.GlyphRun;
                var glyphCount = glyphRun.AdvanceWidths.Count;
                var charCount  = glyphRun.ClusterMap != null ? glyphRun.ClusterMap.Count : glyphCount;

                for (int g = 0; g < charCount; ++g)
                {
                    if (idx >= glyphMetrics.Count)
                    {
                        break;
                    }

                    if ((g > 0) && glyphRun.ClusterMap != null && (glyphRun.ClusterMap[g] == glyphRun.ClusterMap[g - 1]))
                    {
                        // Current character shares its glyph with the previous character (ligature)

                    #if false
                        // Recompute box of previous glyph
                        var i = glyphRun.GlyphIndices[glyphRun.ClusterMap[g - 1]];

                        var rectX = (float)(glyphRun.GlyphTypeface.LeftSideBearings[i] * glyphRun.FontRenderingEmSize);
                        var rectY = (float)(glyphRun.GlyphTypeface.BottomSideBearings[i] * glyphRun.FontRenderingEmSize);
                        var rectW = (float)((glyphRun.GlyphTypeface.AdvanceWidths[i] - glyphRun.GlyphTypeface.LeftSideBearings[i] - glyphRun.GlyphTypeface.RightSideBearings[i]) * glyphRun.FontRenderingEmSize);
                        var rectH = (float)((glyphRun.GlyphTypeface.AdvanceHeights[i] - glyphRun.GlyphTypeface.TopSideBearings[i] - glyphRun.GlyphTypeface.BottomSideBearings[i]) * glyphRun.FontRenderingEmSize);

                        var leftBearing  = -(float)(rectX);
                        var rightBearing = 0.0f;

                        var glyphX            = px2mm(rectX, dpiX);
                        var glyphY            = px2mm(rectY, dpiY);
                        var glyphW            = px2mm(rectW, dpiX);
                        var glyphH            = px2mm(rectH, dpiY);
                        var glyphRect         = new Rectangle(glyphX, glyphY, glyphW, glyphH);
                        var glyphLeftBearing  = px2mm(leftBearing, dpiX);
                        var glyphRightBearing = px2mm(rightBearing, dpiX);

                        x -= (float)glyphRun.AdvanceWidths[glyphRun.ClusterMap[g - 1]];
                        glyphMetrics[idx - 1] = new GlyphMetrics(glyphRect, glyphLeftBearing, glyphRightBearing);
                        glyphMetrics[idx - 1].BoundingBox.Y -= px2mm(baseline, dpiY);
                        glyphMetrics[idx - 1].BoundingBox.X += px2mm(x, dpiX);
                        x += (float)glyphRun.AdvanceWidths[glyphRun.ClusterMap[g - 1]];
                    #endif

                        // => Use previous box for current character
                        glyphMetrics[idx] = glyphMetrics[idx - 1];
                    }
                    else
                    {
                        glyphMetrics[idx].BoundingBox.Y -= px2mm(baseline, dpiY);
                        glyphMetrics[idx].BoundingBox.X += px2mm(x, dpiX);
                        x += (float)glyphRun.AdvanceWidths[glyphRun.ClusterMap != null ? glyphRun.ClusterMap[g] : g];
                    }

                    ++idx;
                }
            }
            else
            {
                var group = drawing as DrawingGroup;

                if (group != null)
                {
                    foreach (var child in group.Children)
                    {
                        WalkDrawingForText_(child, glyphMetrics, ref idx, ref x, baseline, dpiX, dpiY);
                    }
                }
            }
        }
Example #33
0
    /// <summary>
    /// 更新图集数据
    /// </summary>
    private void ApplySpriteAssetData()
    {
        if (cacheSpriteGlyphs == null || cacheSpriteGlyphs.Count == 0 || cacheSpriteCharacters == null ||
            cacheSpriteCharacters.Count == 0)
        {
            Debug.LogError("无缓存数据");
        }

        //1.解析新的tpsheet
        string str = File.ReadAllText(arrangeIconAtlasTpsheetFilePath);

        string[] strArr = str.Split('\n');

        //以Name为key的GlyphRect数据
        Dictionary <string, GlyphRect> glyphRectDic = new Dictionary <string, GlyphRect>();

        foreach (var item in strArr)
        {
               
            if (item.StartsWith("#") || item.StartsWith(":") || string.IsNullOrEmpty(item) || item.StartsWith("\r"))
            {
                continue;
            }
            string[]  strArr2 = item.Split(';');
            int       x       = int.Parse(strArr2[1]);
            int       y       = int.Parse(strArr2[2]);
            int       w       = int.Parse(strArr2[3]);
            int       h       = int.Parse(strArr2[4]);
            GlyphRect rect    = new GlyphRect(x, y, w, h);
            glyphRectDic.Add(strArr2[0], rect);
        }

        //1.1获取新的数据,主要使用GlyphMetrics
        Texture texture = AssetDatabase.LoadAssetAtPath <Texture>(AtlasPngPath);
        List <TMP_SpriteCharacter> newSpriteCharacters = new List <TMP_SpriteCharacter>();
        List <TMP_SpriteGlyph>     newSpriteGlyphs     = new List <TMP_SpriteGlyph>();

        PopulateSpriteTables(texture, ref newSpriteCharacters, ref newSpriteGlyphs);

        //2.更新Cache
        //2.1 cacheSpriteGlyphs
        //2.2 cacheSpriteCharacters
        if (cacheSpriteGlyphs != null && cacheSpriteGlyphs.Count > 0)
        {
            //更新Cache的SpriteGlyph的Rect

            for (int i = 0; i < cacheSpriteGlyphs.Count; i++)
            {
                TMP_SpriteGlyph glyph      = cacheSpriteGlyphs[i];
                string          spriteName = cacheSpriteCharacters[(int)glyph.index].name;
                if (glyphRectDic.ContainsKey(spriteName))
                {
                    GlyphRect newRect = glyphRectDic[spriteName];
                    glyph.glyphRect = new GlyphRect(newRect.x, newRect.y, newRect.width, newRect.height);
                }
            }
        }

        foreach (KeyValuePair <string, GlyphRect> glyphRect in glyphRectDic)
        {
            TMP_SpriteCharacter findSpriteCharacter = cacheSpriteCharacters.Find(character => character.name == glyphRect.Key);
            TMP_SpriteCharacter newSpriteCharacter  = newSpriteCharacters.Find(character => character.name == glyphRect.Key);
            if (findSpriteCharacter == null)
            {
                //新增的Sprite

                TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph();
                spriteGlyph.sprite     = null;
                spriteGlyph.atlasIndex = 0;
                spriteGlyph.scale      = 1.0f;
                spriteGlyph.index      = (uint)cacheSpriteGlyphs.Count;

                GlyphMetrics metrics = newSpriteCharacter.glyph.metrics;
                spriteGlyph.metrics = new GlyphMetrics(metrics.width, metrics.height, metrics.horizontalBearingX,
                                                       metrics.horizontalBearingY, metrics.horizontalAdvance);

                spriteGlyph.glyphRect = new GlyphRect(glyphRect.Value.x, glyphRect.Value.y,
                                                      glyphRect.Value.width, glyphRect.Value.height);

                cacheSpriteGlyphs.Add(spriteGlyph);

                TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0, spriteGlyph);
                spriteCharacter.glyphIndex = (uint)cacheSpriteCharacters.Count;
                spriteCharacter.scale      = 1;
                spriteCharacter.name       = glyphRect.Key;

                cacheSpriteCharacters.Add(spriteCharacter);
            }
        }

        //3.cache写入SpriteAsset
        TMP_SpriteAsset spriteAsset            = AssetDatabase.LoadAssetAtPath <TMP_SpriteAsset>(SpriteAssetPath);
        FieldInfo       spriteCharacterTablePi = spriteAsset.GetType().GetField("m_SpriteCharacterTable", BindingFlags.NonPublic | BindingFlags.Instance);

        if (null != spriteCharacterTablePi)
        {
            spriteCharacterTablePi.SetValue(spriteAsset, cacheSpriteCharacters);
        }
        FieldInfo spriteGlyphTablePi = spriteAsset.GetType().GetField("m_SpriteGlyphTable", BindingFlags.NonPublic | BindingFlags.Instance);

        if (null != spriteGlyphTablePi)
        {
            spriteGlyphTablePi.SetValue(spriteAsset, cacheSpriteGlyphs);
        }

        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
Example #34
0
 /// <summary>
 /// Releases a previously allocated GlyphMetrics[], possibly adding it
 /// to the cache.
 /// </summary>
 /// <remarks>
 /// It is not strictly necessary to call this method after receiving an
 /// array.  The penalty is the performance hit of doing a heap allocation
 /// on the next request if this method is not called.
 /// </remarks>
 internal static void ReleaseGlyphMetrics(GlyphMetrics[] glyphMetrics)
 {
     ReleaseBuffer(glyphMetrics, GlyphMetricsIndex);
 }