Beispiel #1
1
        /// <summary>
        /// 文字描画関数に渡されるフォント構造体を初期化する
        /// </summary>
        /// <param name="fontFace">フォント名の識別子</param>
        /// <param name="hscale">幅の比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の幅で表示される. 0.5fにした場合, 文字は元々の半分の幅で表示される.</param>
        /// <param name="vscale">高さの比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の高さで表示される. 0.5fにした場合, 文字は元々の半分の高さで表示される.</param>
        /// <param name="shear">垂直線からの文字の相対的な角度.ゼロの場合は非イタリックフォントで,例えば,1.0fは≈45°を意味する.</param>
        /// <param name="thickness">文字の太さ.</param>
        /// <param name="lineType">線の種類.</param>
#else
        /// <summary>
        /// Initializes font structure
        /// </summary>
        /// <param name="fontFace">Font name identifier. Only a subset of Hershey fonts are supported now.</param>
        /// <param name="hscale">Horizontal scale. If equal to 1.0f, the characters have the original width depending on the font type. If equal to 0.5f, the characters are of half the original width. </param>
        /// <param name="vscale">Vertical scale. If equal to 1.0f, the characters have the original height depending on the font type. If equal to 0.5f, the characters are of half the original height. </param>
        /// <param name="shear">Approximate tangent of the character slope relative to the vertical line. Zero value means a non-italic font, 1.0f means ≈45° slope, etc. thickness Thickness of lines composing letters outlines. The function cvLine is used for drawing letters. </param>
        /// <param name="thickness">Thickness of the text strokes. </param>
        /// <param name="lineType">Type of the strokes, see cvLine description. </param>
#endif
        public CvFont(FontFace fontFace, double hscale, double vscale, double shear, int thickness, LineType lineType)
        {
            ptr = AllocMemory(SizeOf);
            CvInvoke.cvInitFont(ptr, fontFace, hscale, vscale, shear, thickness, lineType);
        }
Beispiel #2
0
 public void Dispose()
 {
     FontFace?.Dispose();
     FontFace = null;
 }
Beispiel #3
0
 /// <summary>
 /// returns bounding box of the text string
 /// </summary>
 /// <param name="text"></param>
 /// <param name="fontFace"></param>
 /// <param name="fontScale"></param>
 /// <param name="thickness"></param>
 /// <param name="baseLine"></param>
 /// <returns></returns>
 public static Size GetTextSize(string text, FontFace fontFace,
     double fontScale, int thickness, out int baseLine)
 {
     if (String.IsNullOrEmpty(text))
         throw new ArgumentNullException(text);
     return NativeMethods.core_getTextSize(text, (int)fontFace, fontScale, thickness, out baseLine);
 }
Beispiel #4
0
 internal void SetFont(string filename)
 {
     FontFace?.Dispose();
     FontFace = new Face(lib, filename);
     SetSize(this.Size);
 }
        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 = new RawColor3(1.0f, 1.0f, 1.0f);
             *
             * 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
                    });
                }
            }
        }
Beispiel #6
0
 public static extern void cvInitFont(IntPtr font, FontFace font_face, double hscale, double vscale, double shear, int thickness,
     [MarshalAs(UnmanagedType.U4)] LineType line_type);
        unsafe GlyphRect GetGlyph(uint fontHash, FontFace fontFace, short glyphIndex, float fontSize)
        {
            var       glyphHash = GlyphHash(fontFace, fontHash, glyphIndex);
            GlyphRect grect;

            if (!glyphs.TryGetValue(glyphHash, out grect))
            {
                var metrics      = fontFace.Metrics;
                var glyphMetrics = fontFace.GetDesignGlyphMetrics(new short[] { glyphIndex }, false)[0];
                var run          = new GlyphRun();
                run.FontFace = fontFace;
                run.FontSize = fontSize;
                run.Indices  = new short[] { glyphIndex };
                run.Advances = new float[] { 0 };
                run.Offsets  = new GlyphOffset[] { new GlyphOffset() };
                var gdata    = new ComputedSize(fontSize, metrics, glyphMetrics);
                var fillRect = new GDI.RECT()
                {
                    left   = 0,
                    top    = 0,
                    right  = 2 + gdata.maxWidth + 5,
                    bottom = 2 + gdata.maxHeight + 5
                };
                GDI.FillRect(hdc, ref fillRect, hBrush);
                RawRectangle rect;
                renderTarget.DrawGlyphRun(2.0f - gdata.offsetX, 2.0f - gdata.offsetY, D2D1.MeasuringMode.Natural, run, renderParams, new RawColorBGRA(255, 255, 255, 255), out rect);
                var left   = rect.Left < 0 ? 0 : rect.Left;
                var right  = rect.Right > MAX_GLYPH_SIZE ? MAX_GLYPH_SIZE : rect.Right;
                var top    = rect.Top < 0 ? 0 : rect.Top;
                var bottom = rect.Bottom > MAX_GLYPH_SIZE ? MAX_GLYPH_SIZE : rect.Bottom;
                var r      = new Rectangle(0, 0, right - left, bottom - top);
                //Construct grayscale image from GDI
                byte[] data    = new byte[r.Width * r.Height * 4];
                byte * srcData = (byte *)bmBits;
                for (int y = 0; y < r.Height; y++)
                {
                    for (int x = 0; x < r.Width; x++)
                    {
                        var destP = (y * r.Width * 4) + (x * 4);
                        var pixel = srcData[(top + y) * bytesPerPixel * MAX_GLYPH_SIZE + (left + x) * bytesPerPixel];
                        data[destP]     = data[destP + 1] = data[destP + 2] = 255;
                        data[destP + 3] = (byte)(Math.Pow(pixel / 255.0, 1.0 / 1.45) * 255.0);
                    }
                }
                //
                if (currentX + r.Width > MAX_GLYPH_SIZE)
                {
                    currentX      = 0;
                    currentY     += maxLineHeight;
                    maxLineHeight = 0;
                }
                if (currentY + r.Height > MAX_GLYPH_SIZE)
                {
                    pages.Add(new Texture2D(TEXT_PAGE_SIZE, TEXT_PAGE_SIZE, false, SurfaceFormat.Color));
                    currentX = currentY = maxLineHeight = 0;
                }
                r.X           = currentX;
                r.Y           = currentY;
                maxLineHeight = Math.Max(maxLineHeight, r.Height);
                currentX     += r.Width;
                var page = pages[pages.Count - 1];
                page.SetData(0, r, data, 0, data.Length);
                grect.Texture   = page;
                grect.OffsetX   = (int)(gdata.offsetX + left - 2);
                grect.OffsetY   = (int)(gdata.offsetY + top - 2);
                grect.Rectangle = r;
                glyphs.Add(glyphHash, grect);
            }
            return(grect);
        }
Beispiel #8
0
        public IFontFamily[] Initialize()
        {
            var familyList = new List <DXFontFamily>();
            var families   = new Dictionary <string, DXFontFamily>();

            var fontCollection = DXGraphicsService.FactoryDirectWrite.GetSystemFontCollection(false);
            int familyCount    = fontCollection.FontFamilyCount;

            for (int i = 0; i < familyCount; i++)
            {
                var fontFamily  = fontCollection.GetFontFamily(i);
                var familyNames = fontFamily.FamilyNames;

                if (!familyNames.FindLocaleName("en-us", out var index))
                {
                    index = 0;
                }
                var familyName = familyNames.GetString(index);

                for (int j = 0; j < fontFamily.FontCount; j++)
                {
                    string postScriptName = familyName;

                    var font = fontFamily.GetFont(j);

                    var found = font.GetInformationalStrings(InformationalStringId.PostscriptName,
                                                             out var localizedPostScriptName);
                    if (found)
                    {
                        postScriptName = localizedPostScriptName.GetString(0);
                    }

                    if (!families.TryGetValue(familyName, out var family))
                    {
                        family = new DXFontFamily(familyName);
                        families[familyName] = family;
                        familyList.Add(family);
                    }

                    var id = postScriptName;
                    if (!font.FaceNames.FindLocaleName("en-us", out index))
                    {
                        index = 0;
                    }

                    var name = font.FaceNames.GetString(index);

                    var fullName = familyName;
                    if (!("Regular".Equals(name) || "Plain".Equals(name) || "Normal".Equals(name)))
                    {
                        fullName = string.Format("{0} {1}", familyName, name);
                    }

                    var fontFace = new FontFace(font);
                    var style    = new DXFontStyle(family, id, name, fullName, font.Style, font.Weight, fontFace);
                    family.AddStyle(style);
                }
            }

            familyList.Sort();

            foreach (var family in familyList)
            {
                family.RemoveDuplicates();
            }

            return(familyList.OfType <IFontFamily>().ToArray());
        }
Beispiel #9
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));
        }
Beispiel #10
0
        internal static unsafe void Main(string[] args)
        {
            try
            {
                int pixelsCount = 1 << 18;
                uint[] pixelsArray = new uint[65536];

                using (DisposableHandle handle = DisposableHandle.Alloc(pixelsArray))
                {
                    NTInvoke.SetUnmanagedMemory(handle, 255, pixelsCount);
                }

                byte[] outputData = null;

                MCvScalar redColor = MCvScalarExtensions.FromColor(Colors.Red);
                MCvScalar greenColor = MCvScalarExtensions.FromColor(Colors.Green);

                using (PresentationImage prImage = new PresentationImage(256, 256))
                {
                    prImage.WritePixels(pixelsArray);

                    FontFace[] faces = new FontFace[]
                    {
                        FontFace.HersheyComplex,
                        FontFace.HersheyComplexSmall,
                        FontFace.HersheyDuplex,
                        FontFace.HersheyPlain,
                        FontFace.HersheyScriptComplex,
                        FontFace.HersheyScriptSimplex,
                        FontFace.HersheySimplex,
                        FontFace.HersheyTriplex
                    };

                    Parallel.For(0, 8, (int index) =>
                    {
                        Point drawPoint = new Point(10, 30 + 30 * index);
                        FontFace drawFace = faces[index];

                        string outputText = Enum.GetName(typeof(FontFace), drawFace);

                        CvInvoke.DrawText(prImage, outputText, drawPoint, drawFace, 1.0D, redColor, 1);
                    });

                    outputData = CvInvoke.Imencode(prImage, ImageEncoding.Jpeg, new int[] { 95 });
                }

                if (outputData != null && outputData.Length > 0)
                {
                    using (MemoryStream dataStream = new MemoryStream(outputData))
                    {
                        JpegBitmapDecoder decoder = new JpegBitmapDecoder(dataStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnLoad);
                        BitmapFrame frame = decoder.Frames[0];

                        Window imageWindow = new Window()
                        {
                            Height = 300.0D,
                            Width = 500.0D,
                            Title = "Image window",
                            ResizeMode = ResizeMode.CanResize,
                            WindowStartupLocation = WindowStartupLocation.CenterScreen
                        };
                        imageWindow.Content = new Image()
                        {
                            Source = frame
                        };
                        new Application().Run(imageWindow);
                    }
                }
            }
            catch (Exception exc)
            {
                Debug.WriteLine("\tCatched exception: {0}\r\n{1}", exc.Message, exc);
            }
            finally
            {
                Debug.WriteLine("\tData released succesfully.");
            }
        }
Beispiel #11
0
        protected override bool Init(object controller, object binding, DefinitionFile definition)
        {
            if (!base.Init(controller, binding, definition))
            {
                return(false);
            }

            DefinitionFileWithStyle file = new DefinitionFileWithStyle(definition, typeof(UiRichView));

            string defaultFont        = file["Font"] as string;
            int    defaultFontSize    = DefinitionResolver.Get <int>(Controller, Binding, file["FontSize"], 0);
            int    defaultFontSpacing = DefinitionResolver.Get <int>(Controller, Binding, file["FontSpacing"], int.MaxValue);

            for (int idx = 0; idx < (int)FontType.Count; ++idx)
            {
                FontType type    = (FontType)idx;
                string   font    = string.Format("{0}.Font", type);
                string   spacing = string.Format("{0}.FontSpacing", type);
                string   resize  = string.Format("{0}.FontResize", type);

                string fontName    = file[font] as string;
                int    fontSpacing = DefinitionResolver.Get <int>(Controller, Binding, file[spacing], defaultFontSpacing == int.MaxValue ? 0 : defaultFontSpacing);
                int    fontResize  = DefinitionResolver.Get <int>(Controller, Binding, file[resize], 0);

                if (fontName == null)
                {
                    fontName = defaultFont;
                }

                FontFace fontObj = FontManager.Instance.FindFont(fontName);

                if (defaultFont == null)
                {
                    defaultFont = fontName;
                }

                if (defaultFontSpacing == int.MaxValue)
                {
                    defaultFontSpacing = fontSpacing;
                }

                _fonts[idx] = new FontInfo()
                {
                    Font        = fontObj,
                    FontSpacing = (float)fontSpacing / 1000.0f,
                    FontResize  = fontResize
                };
            }

            for (int idx = 0; idx < (int)SizeType.Count; ++idx)
            {
                SizeType type = (SizeType)idx;
                string   size = string.Format("{0}.FontSize", type);

                int fontSize = DefinitionResolver.Get <int>(Controller, Binding, file[size], defaultFontSize);

                if (defaultFontSize == 0)
                {
                    defaultFontSize = fontSize;
                }

                _sizes[idx] = fontSize;
            }

            _bulletText = DefinitionResolver.GetString(Controller, Binding, file["BulletText"]) ?? "* ";
            //_bulletText = _bulletText.Replace(" ", ((char)0xa0).ToString());

            _horizontalRulerHeight = DefinitionResolver.Get <Length>(Controller, Binding, file["HorizontalRulerHeight"], new Length(0, 0, 1));
            _indentSize            = DefinitionResolver.Get <Length>(Controller, Binding, file["Indent"], Length.Zero);
            _paragraphSpacing      = DefinitionResolver.Get <Length>(Controller, Binding, file["ParagraphSpacing"], Length.Zero);

            _lineHeight = (float)DefinitionResolver.Get <int>(Controller, Binding, file["LineHeight"], 100) / 100.0f;
            _justify    = DefinitionResolver.Get <bool>(Controller, Binding, file["Justify"], false);

            Type processorType = file["Processor"] as Type;

            if (processorType != null)
            {
                _richProcessor = Activator.CreateInstance(processorType) as IRichProcessor;
            }

            Text = DefinitionResolver.GetString(Controller, Binding, file["Text"]);

            _colorNormal          = DefinitionResolver.GetColorWrapper(Controller, Binding, file["TextColor"]) ?? UiLabel.DefaultTextColor;
            _colorClickable       = DefinitionResolver.GetColorWrapper(Controller, Binding, file["LinkColor"]) ?? UiLabel.DefaultTextColor;
            _colorClickableActive = DefinitionResolver.GetColorWrapper(Controller, Binding, file["ActiveLinkColor"]) ?? _colorClickable;
            _colorRuler           = DefinitionResolver.GetColorWrapper(Controller, Binding, file["HorizontalRulerColor"]) ?? UiLabel.DefaultTextColor;

            HorizontalContentAlignment horzAlign = DefinitionResolver.Get <HorizontalContentAlignment>(Controller, Binding, file["HorizontalContentAlignment"], HorizontalContentAlignment.Left);
            VerticalContentAlignment   vertAlign = DefinitionResolver.Get <VerticalContentAlignment>(Controller, Binding, file["VerticalContentAlignment"], VerticalContentAlignment.Top);

            _textAlign = UiHelper.TextAlignFromContentAlignment(horzAlign, vertAlign);

            _clickMargin = DefinitionResolver.Get <Length>(Controller, Binding, file["ClickMargin"], Length.Zero);

            RegisterDelegate("UrlClick", file["UrlClick"]);

            EnabledGestures = (GestureType.Down | GestureType.Up | GestureType.Move | GestureType.Tap);

            return(true);
        }
Beispiel #12
0
        internal static pTexture CreateText(string text, float size, Vector2 restrictBounds, Color color, ShadowType shadow, bool bold, bool italic, bool underline, TextAlignment alignment, bool forceAa, out Vector2 measured, out RectangleF[] characterRegions, Color background, Color border, int borderWidth, bool measureOnly, bool getCharacterRegions, FontFace fontFace, Vector4 cornerBounds, Vector2 padding, pTexture lastTexture = null, int startIndex = 0, int length = -1)
        {
            characterRegions = null;
            if (text == null)
            {
                measured = Vector2.Zero;
                return(null);
            }

            if (ConfigManager.dDisableTextRendering)
            {
                measured = new Vector2(text.Length * size, size);
                return(null);
            }

#if DEBUG
            if (!text.Contains(@"NativeText"))
            {
                int  limit_per_second = osu.GameModes.Play.Player.Playing ? 5 : 58;
                bool newSecond        = GameBase.Time / 1000 != currentSecond;

                drawCount++;
                if (drawCount == limit_per_second)
                {
                    Debug.Print(@"NativeText: High number of text refreshes per second.");
                }

                if (newSecond)
                {
                    currentSecond = GameBase.Time / 1000;
                    drawCount     = 0;
                }
            }
#endif

            //This lock ensures we are only using the shared GDI+ object (FromHwnd) in one place at a time.
            lock (createTextLock)
            {
                try
                {
                    using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero))
                        using (StringFormat sf = new StringFormat())
                        {
                            if (dpiRatio == 0)
                            {
                                dpiRatio = 96 / graphics.DpiX;
                            }

                            size *= dpiRatio;

                            GameBase.PerformanceMonitor.ReportCount(CounterType.NativeText);

                            graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

                            SizeF measuredSize;

                            string face = GetFontFace(fontFace);

                            if (face.StartsWith(@"Aller"))
                            {
                                //if we are using the default osu! font, allow specific language overrides based on simple detection.
                                string fontFaceOverride = getLanguageSpeicificFont(text);
                                if (fontFaceOverride != null)
                                {
                                    face = fontFaceOverride;
                                }
                            }

                            if (startIndex != 0 || length > 0)
                            {
                                text = text.Substring(startIndex, length);
                            }
                            else if (length == -1)
                            {
                                length = text.Length;
                            }


                            if (size < 20 && face.EndsWith(@" Light"))
                            {
                                face = face.Replace(@" Light", string.Empty);
                            }

                            FontStyle fs = FontStyle.Regular;
                            if (bold)
                            {
                                if (face.EndsWith(@" Light"))
                                {
                                    face = face.Replace(@" Light", string.Empty);
                                }
                                fs |= FontStyle.Bold;
                            }

                            if (italic)
                            {
                                fs |= FontStyle.Italic;
                            }

                            if (underline)
                            {
                                fs |= FontStyle.Underline;
                            }

                            switch (alignment)
                            {
                            case TextAlignment.Left:
                            case TextAlignment.LeftFixed:
                                sf.Alignment = StringAlignment.Near;
                                break;

                            case TextAlignment.Centre:
                                sf.Alignment = StringAlignment.Center;
                                break;

                            case TextAlignment.Right:
                                sf.Alignment = StringAlignment.Far;
                                break;
                            }

                            if (!OsuMain.IsWine && face.StartsWith(@"Aller"))
                            {
                                for (char c = '0'; c <= '9'; c++)
                                {
                                    text = text.Replace(c, (char)(c + (0xf83c - '0')));
                                }
                            }

                            Font f = GetFont(face, size * ScaleModifier, fs);
                            if (ScaleModifier != 1)
                            {
                                restrictBounds *= ScaleModifier;
                            }

                            try
                            {
                                if (text.Length == 0)
                                {
                                    text = " ";
                                }
                                measuredSize = restrictBounds != Vector2.Zero
                                                ? graphics.MeasureString(text, f, new SizeF(restrictBounds.X, restrictBounds.Y), sf)
                                                : graphics.MeasureString(text, f);
                            }
                            catch (InvalidOperationException)
                            {
                                measured = Vector2.Zero;
                                return(null);
                            }

                            int width  = (int)(measuredSize.Width + 1);
                            int height = (int)(measuredSize.Height + 1);

                            if (restrictBounds.Y != 0)
                            {
                                height = (int)restrictBounds.Y;
                            }

                            if (restrictBounds.X != 0 && (alignment != TextAlignment.Left || background.A > 0))
                            {
                                width = (int)restrictBounds.X;
                            }

                            if (padding != Vector2.Zero && restrictBounds == Vector2.Zero)
                            {
                                width  += (int)(padding.X * 2);
                                height += (int)(padding.Y * 2);
                            }

                            measured = new Vector2(width, height);
                            float offset = Math.Max(0.5f, Math.Min(1f, (size * ScaleModifier) / 14));

                            if (getCharacterRegions)
                            {
                                characterRegions = new RectangleF[text.Length];

                                // SetMeasurableCharacterRanges only accepts a maximum of 32 intervals to be queried, so we as the library user are
                                // forced to split the string into 32 character long chunks and perform MeasureCharacterRanges on each.
                                int numIntervals = (text.Length / 32) + 1;
                                for (int i = 0; i < numIntervals; ++i)
                                {
                                    int offsetIndex = i * 32;
                                    int end         = Math.Min(text.Length - offsetIndex, 32);

                                    CharacterRange[] characterRanges = new CharacterRange[end];
                                    for (int j = 0; j < end; ++j)
                                    {
                                        characterRanges[j] = new CharacterRange(j + offsetIndex, 1);
                                    }

                                    sf.SetMeasurableCharacterRanges(characterRanges);
                                    Region[] regions = graphics.MeasureCharacterRanges(
                                        text,
                                        f,
                                        new RectangleF(
                                            padding.X,
                                            padding.Y,
                                            restrictBounds.X == 0 ? Single.PositiveInfinity : restrictBounds.X,
                                            restrictBounds.Y == 0 ? Single.PositiveInfinity : restrictBounds.Y),
                                        sf);

                                    for (int j = 0; j < end; ++j)
                                    {
                                        Region region = regions[j] as Region;
                                        characterRegions[j + offsetIndex] = region.GetBounds(graphics);
                                    }
                                }
                            }

                            if (measureOnly)
                            {
                                int startSpace = 0;
                                int endSpace   = 0;

                                int i = 0;
                                while (i < text.Length && text[i++] == ' ')
                                {
                                    startSpace++;
                                }
                                int j = text.Length - 1;
                                while (j >= i && text[j--] == ' ')
                                {
                                    endSpace++;
                                }
                                if (startSpace == text.Length)
                                {
                                    endSpace += startSpace;
                                }

                                measured = new Vector2(width + (endSpace * 5.145f * size / 12), height);
                                return(null);
                            }

                            using (Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb))
                                using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b))
                                {
                                    //Quality settings
                                    g.TextRenderingHint = graphics.TextRenderingHint;
                                    g.SmoothingMode     = SmoothingMode.HighQuality;
                                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                                    if (background.A > 0)
                                    {
                                        if (cornerBounds != Vector4.Zero)
                                        {
                                            fillRoundedRectangle(g, new Rectangle(0, 0, width, height), new SolidBrush(OsuMathHelper.CConvert(background)), cornerBounds);

                                            if (borderWidth > 0)
                                            {
                                                drawRoundedRectangle(g,
                                                                     new Rectangle(0, 0, width - (int)Math.Ceiling(borderWidth / 2f), height - (int)Math.Ceiling(borderWidth / 2f)),
                                                                     new Pen(OsuMathHelper.CConvert(border), borderWidth),
                                                                     cornerBounds);
                                            }
                                        }
                                        else
                                        {
                                            g.Clear(OsuMathHelper.CConvert(background));
                                            if (borderWidth > 0)
                                            {
                                                g.DrawRectangle(new Pen(OsuMathHelper.CConvert(border), borderWidth),
                                                                new Rectangle(borderWidth / 2, borderWidth / 2, width - borderWidth, height - borderWidth));
                                            }
                                        }
                                    }
                                    else
                                    {
                                        g.Clear(System.Drawing.Color.FromArgb(1, color.R, color.G, color.B));
                                    }


                                    using (Brush brush = new SolidBrush(OsuMathHelper.CConvert(color)))
                                    {
                                        if (restrictBounds != Vector2.Zero)
                                        {
                                            restrictBounds.X -= padding.X * 2;
                                            restrictBounds.Y -= padding.Y * 2;

                                            switch (shadow)
                                            {
                                            case ShadowType.Normal:
                                                g.DrawString(text, f, shadowBrush, new RectangleF(padding.X - offset, offset + padding.Y, restrictBounds.X, restrictBounds.Y), sf);
                                                g.DrawString(text, f, shadowBrush, new RectangleF(padding.X + offset, offset + padding.Y, restrictBounds.X, restrictBounds.Y), sf);
                                                break;

                                            case ShadowType.Border:
                                                Brush borderBrush = greyBrush;
                                                if (background.A == 0 && borderWidth == 1 && border.A > 0)
                                                {
                                                    borderBrush = new SolidBrush(OsuMathHelper.CConvert(border));
                                                }

                                                g.DrawString(text, f, borderBrush, new RectangleF(padding.X + offset, padding.Y + offset, restrictBounds.X, restrictBounds.Y), sf);
                                                g.DrawString(text, f, borderBrush, new RectangleF(padding.X + offset, padding.Y - offset, restrictBounds.X, restrictBounds.Y), sf);
                                                g.DrawString(text, f, borderBrush, new RectangleF(padding.X - offset, padding.Y + offset, restrictBounds.X, restrictBounds.Y), sf);
                                                g.DrawString(text, f, borderBrush, new RectangleF(padding.X - offset, padding.Y - offset, restrictBounds.X, restrictBounds.Y), sf);
                                                break;
                                            }

                                            g.DrawString(text, f, brush, new RectangleF(padding.X, padding.Y, restrictBounds.X, restrictBounds.Y), sf);
                                        }
                                        else
                                        {
                                            switch (shadow)
                                            {
                                            case ShadowType.Normal:
                                                g.DrawString(text, f, shadowBrush, padding.X - offset, padding.Y + offset);
                                                g.DrawString(text, f, shadowBrush, padding.X + offset, padding.Y + offset);
                                                break;

                                            case ShadowType.Border:
                                                Brush borderBrush = greyBrush;
                                                if (background.A == 0 && borderWidth == 1 && border.A > 0)
                                                {
                                                    borderBrush = new SolidBrush(OsuMathHelper.CConvert(border));
                                                }

                                                g.DrawString(text, f, borderBrush, padding.X + offset, padding.Y + offset);
                                                g.DrawString(text, f, borderBrush, padding.X - offset, padding.Y + offset);
                                                g.DrawString(text, f, borderBrush, padding.X + offset, padding.Y - offset);
                                                g.DrawString(text, f, borderBrush, padding.X - offset, padding.Y - offset);
                                                break;
                                            }

                                            g.DrawString(text, f, brush, padding.X, padding.Y);
                                        }
                                    }

                                    //if (lastTexture == null || lastTexture.isDisposed)
                                    {
                                        lastTexture            = pTexture.FromBitmap(b);
                                        lastTexture.Disposable = true;
                                    }

                                    /*else
                                     * {
                                     *  lastTexture.Width = b.Width;
                                     *  lastTexture.Height = b.Height;
                                     *  lastTexture.SetData(b);
                                     * }*/

                                    return(lastTexture);
                                }
                        }
                }
                catch (Exception e)
                {
                    measured = Vector2.Zero;
                    return(null);
                }
            }
        }
        private bool LoadFont(Value value)
        {
            Value  path = value["url"];
            string pathValue;

            if (path != null)
            {
                // Get the text value:
                pathValue = path.Text;
            }
            else
            {
                // Read the raw value:
                pathValue = value.Text;
            }

            DataPackage package = new DataPackage(pathValue, Document.basepath);

            package.onload = delegate(UIEvent e){
                // Load the face - it will by default add to it's "native" family:
                FontFace loaded = FontLoader.Load(package.responseBytes);

                if (loaded == null || loaded.Family == null)
                {
                    Dom.Log.Add("@font-face error: invalid font file at " + package.location.absolute);
                    return;
                }

                // Got any weight, stretch or style overrides?
                Css.Value styleValue   = style["font-style"];
                Css.Value weightValue  = style["font-weight"];
                Css.Value stretchValue = style["font-stretch"];

                if (styleValue != null || weightValue != null || stretchValue != null)
                {
                    // Yep!

                    // New style value:
                    int styleV = (styleValue == null) ? loaded.Style : styleValue.GetInteger(null, Css.Properties.FontStyle.GlobalProperty);

                    // New weight value:
                    int weight = (weightValue == null) ? loaded.Weight : weightValue.GetInteger(null, Css.Properties.FontWeight.GlobalProperty);

                    // New stretch value:
                    int stretch = (stretchValue == null) ? loaded.Stretch : stretchValue.GetInteger(null, Css.Properties.FontStretch.GlobalProperty);

                    // Update the flags:
                    loaded.SetFlags(styleV, weight, stretch);
                }

                Value family = style["font-family"];

                // Grab the family name:
                string familyName;

                if (family == null || family.Text == null)
                {
                    familyName = loaded.Family.Name;
                }
                else
                {
                    familyName = family.Text.Trim();
                }

                // Add as an active font:
                Dictionary <string, DynamicFont> fonts = Document.ActiveFonts;

                DynamicFont dFont;
                if (!fonts.TryGetValue(familyName, out dFont))
                {
                    // Create the font object:
                    dFont        = new DynamicFont(familyName);
                    dFont.Family = loaded.Family;

                    fonts[familyName] = dFont;
                }
                else
                {
                    // Hook up the "real" family:
                    dFont.Family = loaded.Family;

                    // Tell all instances using this dFont that the font is ready:
                    Document.FontLoaded(dFont);
                }
            };

            // Send now:
            package.send();

            return(true);
        }
 public int GetGlyphIndex(Character c)
 {
     int[] results = FontFace.GetGlyphIndices(new uint[] { c.UnicodeIndex });
     return(results[0]);
 }
Beispiel #15
0
        /// <summary>
        /// 文字描画関数に渡されるフォント構造体を初期化する
        /// </summary>
        /// <param name="font_face">フォント名の識別子</param>
        /// <param name="hscale">幅の比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の幅で表示される. 0.5fにした場合, 文字は元々の半分の幅で表示される.</param>
        /// <param name="vscale">高さの比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の高さで表示される. 0.5fにした場合, 文字は元々の半分の高さで表示される.</param>
        /// <param name="shear">垂直線からの文字の相対的な角度.ゼロの場合は非イタリックフォントで,例えば,1.0fは≈45°を意味する.</param>
        /// <param name="thickness">文字の太さ.</param>
        /// <param name="line_type">線の種類.</param>
#else
        /// <summary>
        /// Initializes font structure
        /// </summary>
        /// <param name="font_face">Font name identifier. Only a subset of Hershey fonts are supported now.</param>
        /// <param name="hscale">Horizontal scale. If equal to 1.0f, the characters have the original width depending on the font type. If equal to 0.5f, the characters are of half the original width. </param>
        /// <param name="vscale">Vertical scale. If equal to 1.0f, the characters have the original height depending on the font type. If equal to 0.5f, the characters are of half the original height. </param>
        /// <param name="shear">Approximate tangent of the character slope relative to the vertical line. Zero value means a non-italic font, 1.0f means ≈45° slope, etc. thickness Thickness of lines composing letters outlines. The function cvLine is used for drawing letters. </param>
        /// <param name="thickness">Thickness of the text strokes. </param>
        /// <param name="line_type">Type of the strokes, see cvLine description. </param>
#endif
        public CvFont(FontFace font_face, double hscale, double vscale, double shear, int thickness, LineType line_type)
        {
            this._ptr = base.AllocMemory(SizeOf);
            CvInvoke.cvInitFont(this._ptr, font_face, hscale, vscale, shear, thickness, line_type);
        }
Beispiel #16
0
        private static void BlitCharacter(int pixelSize, int maxWidth, FullDictionary <char, CharacterInfo> dict, ref int currentX, ref int currentY, Graphics g, FontFace typeface, char c)
        {
            if (c == ' ')
            {
                int width = pixelSize / 3;
                if (currentX + xInterval + width >= maxWidth)
                {
                    currentX  = 0;
                    currentY += yInterval + pixelSize;
                    if (currentY + yInterval + pixelSize >= maxWidth)
                    {
                        throw new Exception("Texture Size not big enough for reuqired characters.");
                    }
                }
                Bitmap glyphBitmap = new Bitmap(width + xInterval, pixelSize + yInterval);
                //float yoffset = pixelSize * 3 / 4 - glyph.HorizontalMetrics.Bearing.Y;
                g.DrawImage(glyphBitmap, currentX + xInterval, currentY + yInterval);
                CharacterInfo info = new CharacterInfo(currentX, currentY, width + xInterval, pixelSize + yInterval);
                dict.Add(c, info);
                glyphBitmap.Dispose();
                currentX += width;
            }
            else
            {
                Surface surface; Glyph glyph;
                if (RenderGlyph(typeface, c, pixelSize, out surface, out glyph))
                {
                    if (currentX + xInterval + surface.Width >= maxWidth)
                    {
                        currentX  = 0;
                        currentY += yInterval + pixelSize;
                        if (currentY + yInterval + pixelSize >= maxWidth)
                        {
                            throw new Exception("Texture Size not big enough for reuqired characters.");
                        }
                    }
                    Bitmap    glyphBitmap = GetGlyphBitmap(surface);
                    const int a           = 5;
                    const int b           = 8;
                    //float yoffset = pixelSize * a / b - glyph.HorizontalMetrics.Bearing.Y;
#if DEBUG
                    g.DrawRectangle(redPen, currentX + xInterval, currentY + yInterval + pixelSize * a / b - glyph.HorizontalMetrics.Bearing.Y, glyphBitmap.Width, glyphBitmap.Height);
                    g.DrawRectangle(greenPen, currentX, currentY, glyphBitmap.Width + xInterval, yInterval + pixelSize - 1);
#endif
                    g.DrawImage(glyphBitmap, currentX + xInterval, currentY + yInterval + pixelSize * a / b - glyph.HorizontalMetrics.Bearing.Y, glyphBitmap.Width, glyphBitmap.Height);
                    CharacterInfo info = new CharacterInfo(currentX, currentY, glyphBitmap.Width + xInterval, yInterval + pixelSize - 1);
                    dict.Add(c, info);
                    glyphBitmap.Dispose();
                    currentX += xInterval + surface.Width;
                }

                surface.Dispose();
            }
        }
Beispiel #17
0
        /// <summary>
        /// 文字描画関数に渡されるフォント構造体を初期化する
        /// </summary>
        /// <param name="font_face">フォント名の識別子</param>
        /// <param name="hscale">幅の比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の幅で表示される. 0.5fにした場合, 文字は元々の半分の幅で表示される.</param>
        /// <param name="vscale">高さの比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の高さで表示される. 0.5fにした場合, 文字は元々の半分の高さで表示される.</param>
        /// <param name="shear">垂直線からの文字の相対的な角度.ゼロの場合は非イタリックフォントで,例えば,1.0fは≈45°を意味する.</param>
#else
        /// <summary>
        /// Initializes font structure
        /// </summary>
        /// <param name="font_face">Font name identifier. Only a subset of Hershey fonts are supported now.</param>
        /// <param name="hscale">Horizontal scale. If equal to 1.0f, the characters have the original width depending on the font type. If equal to 0.5f, the characters are of half the original width. </param>
        /// <param name="vscale">Vertical scale. If equal to 1.0f, the characters have the original height depending on the font type. If equal to 0.5f, the characters are of half the original height. </param>
        /// <param name="shear">Approximate tangent of the character slope relative to the vertical line. Zero value means a non-italic font, 1.0f means ≈45° slope, etc. thickness Thickness of lines composing letters outlines. The function cvLine is used for drawing letters. </param>
#endif
        public CvFont(FontFace font_face, double hscale, double vscale, Double shear)
            : this(font_face, hscale, vscale, shear, 1, LineType.Link8)
        {
        }
Beispiel #18
0
 public D2DFontPathData([NotNull] string text, RenderContext context, D2DFont d2dFont, FontFace fontFace, float maxWidth, float maxHeight)
 {
     Initialize(context, text, d2dFont, fontFace);
     Size = context.MeasureText(text, d2dFont, maxWidth, maxHeight);
 }
Beispiel #19
0
 /// <summary>
 /// Internal Constructor to create a Game Font Data object.
 /// </summary>
 internal GameFont(FontFace ff, int size, Dictionary <char, TextCharacter> fontAtlas)
 {
     Size       = size;
     _fontFace  = ff;
     _fontAtlas = fontAtlas;
 }
Beispiel #20
0
 public D2DFontPathData([NotNull] string text, RenderContext context, D2DFont d2dFont, FontFace fontFace)
 {
     Initialize(context, text, d2dFont, fontFace);
     Size = context.MeasureText(text, d2dFont);
 }
        /// <inheritdoc/>
        public void Import(SpriteFontAsset options, List <char> characters)
        {
            fontSource = options.FontSource.GetFontPath();
            if (string.IsNullOrEmpty(fontSource))
            {
                return;
            }

            // Get the msdfgen.exe location
            var installationDir = DirectoryHelper.GetPackageDirectory("Xenko");
            var binDir          = UPath.Combine(installationDir, new UDirectory("Bin"));

            binDir = UPath.Combine(binDir, new UDirectory("Windows"));
            var msdfgen = UPath.Combine(binDir, new UFile("msdfgen.exe"));

            if (!File.Exists(msdfgen))
            {
                throw new AssetException("Failed to compile a font asset, msdfgen was not found.");
            }

            msdfgenExe = msdfgen.FullPath;
            tempDir    = $"{Environment.GetEnvironmentVariable("TEMP")}\\";

            var factory = new Factory();

            FontFace fontFace = options.FontSource.GetFontFace();

            var fontMetrics = fontFace.Metrics;

            // Create a bunch of GDI+ objects.
            var fontSize = options.FontType.Size;

            var glyphList = new List <Glyph>();

            // Remap the LineMap coming from the font with a user defined remapping
            // Note:
            // We are remapping the lineMap to allow to shrink the LineGap and to reposition it at the top and/or bottom of the
            // font instead of using only the top
            // According to http://stackoverflow.com/questions/13939264/how-to-determine-baseline-position-using-directwrite#comment27947684_14061348
            // (The response is from a MSFT employee), the BaseLine should be = LineGap + Ascent but this is not what
            // we are experiencing when comparing with MSWord (LineGap + Ascent seems to offset too much.)
            //
            // So we are first applying a factor to the line gap:
            //     NewLineGap = LineGap * LineGapFactor
            var lineGap = fontMetrics.LineGap * options.LineGapFactor;

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

            // And then the baseline is also changed in order to allow the linegap to be distributed between the top and the
            // bottom of the font:
            //     BaseLine = NewLineGap * LineGapBaseLineFactor
            BaseLine = (float)(lineGap * options.LineGapBaseLineFactor + fontMetrics.Ascent) / fontMetrics.DesignUnitsPerEm * fontSize;

            // Generate SDF bitmaps for each character in turn.
            foreach (var character in characters)
            {
                glyphList.Add(ImportGlyph(fontFace, character, fontMetrics, fontSize));
            }

            Glyphs = glyphList;

            factory.Dispose();
        }
Beispiel #22
0
 /// <summary>
 /// Adds a font face into the font search list.
 /// </summary>
 /// <param name="fontFace">The font face to be added.</param>
 /// <param name="fontFamily">The font family name associated with the font face.</param>
 /// <param name="fontStyle">The font style associated with the font face. Mustn't be <c>Inherited</c>.</param>
 /// <param name="weight">The font weight associated with the font face. Must be in range <c>[100, 1000]</c>.</param>
 public void AddFontFace(FontFace fontFace, string fontFamily, FontStyle fontStyle, int weight)
 {
     this.fontConfig.AddFontFace(fontFace, fontFamily, fontStyle, weight);
     FontConfigUpdated?.Invoke(this, EventArgs.Empty);
 }
Beispiel #23
0
        /// <summary>
        /// loads a font from a filestream and creates the gl textures for the chars
        /// </summary>
        /// <param name="fileStream">Filestream of the font file</param>
        /// <param name="pixelSize">The Pixel Size</param>
        /// <param name="fontName">The name of the font</param>
        /// <returns>A the game font from an font file</returns>
        internal static GameFont LoadFontInternal(Stream fileStream, int pixelSize, out string fontName)
        {
            FontFace ff = new FontFace(fileStream);

            fontName = ff.FullName;

            Dictionary <char, TextCharacter> fontAtlas = new Dictionary <char, TextCharacter>();

            for (int i = 0; i < ushort.MaxValue; i++)
            {
                Glyph g = ff.GetGlyph(new CodePoint(i), pixelSize);
                if (g == null)
                {
                    continue;
                }

                byte[]   buf    = new byte[g.RenderWidth * g.RenderHeight];
                GCHandle handle = GCHandle.Alloc(buf, GCHandleType.Pinned);
                Surface  s      = new Surface
                {
                    Bits   = handle.AddrOfPinnedObject(),
                    Width  = g.RenderWidth,
                    Height = g.RenderHeight,
                    Pitch  = g.RenderWidth
                };

                g.RenderTo(s);
                Texture glTex;
                if (g.RenderWidth != 0 && g.RenderHeight != 0)
                {
                    Bitmap     bmp  = new Bitmap(g.RenderWidth, g.RenderHeight);
                    BitmapData data = bmp.LockBits(new Rectangle(0, 0, g.RenderWidth, g.RenderHeight),
                                                   ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                    byte[] iimgBuf = new byte[buf.Length * 4];
                    for (int j = 0; j < buf.Length; j++)
                    {
                        iimgBuf[j * 4 + 3] = 255;
                        iimgBuf[j * 4 + 1] = buf[j];
                        iimgBuf[j * 4 + 2] = buf[j];
                        iimgBuf[j * 4]     = buf[j];
                    }

                    Marshal.Copy(iimgBuf, 0, data.Scan0, iimgBuf.Length);

                    bmp.UnlockBits(data);

                    //bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); //Rotating hack

                    data = bmp.LockBits(new Rectangle(0, 0, g.RenderWidth, g.RenderHeight),
                                        ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                    Texture tex = TextureLoader.ParameterToTexture(bmp.Width, bmp.Height, fontName + "+" + (char)i);
                    glTex = tex;
                    GL.BindTexture(TextureTarget.Texture2D, tex.TextureId);

                    GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.R8, g.RenderWidth, g.RenderHeight,
                                  0, PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
                    GL.TextureParameter(tex.TextureId, TextureParameterName.TextureWrapS,
                                        (int)TextureWrapMode.ClampToEdge);
                    GL.TextureParameter(tex.TextureId, TextureParameterName.TextureWrapT,
                                        (int)TextureWrapMode.ClampToEdge);
                    GL.TextureParameter(tex.TextureId, TextureParameterName.TextureMinFilter,
                                        (int)TextureMinFilter.Linear);
                    GL.TextureParameter(tex.TextureId, TextureParameterName.TextureMagFilter,
                                        (int)TextureMagFilter.Linear);

                    bmp.UnlockBits(data);
                }
                else
                {
                    glTex = null;
                }

                TextCharacter c = new TextCharacter
                {
                    GlTexture = glTex,
                    Width     = s.Width,
                    Height    = s.Height,
                    Advance   = g.HorizontalMetrics.Advance,
                    BearingX  = g.HorizontalMetrics.Bearing.X,
                    BearingY  = g.HorizontalMetrics.Bearing.Y
                };
                fontAtlas.Add((char)i, c);
            }

            GameFont font = new GameFont(ff, pixelSize, fontAtlas);

            return(font);
        }
Beispiel #24
0
 public unsafe void Append(TextAnalyzer analyzer, FontFace font, CharBuffer charBuffer, float fontSize, int atlasWidth, RectangleF drawRect)
 {
     Append(analyzer, font, charBuffer, fontSize, atlasWidth, drawRect, RgbaByte.White);
 }
Beispiel #25
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);
        }
Beispiel #26
0
 /// <summary>
 /// Setzt die Schriftart der Instanz
 /// </summary>
 /// <param name="fontFace">zu nutzende Schriftart</param>
 public void SetFont(FontFace fontFace)
 {
     Font = fontFace;
 }
Beispiel #27
0
 /// <summary>
 /// renders text string in the image
 /// </summary>
 /// <param name="img"></param>
 /// <param name="text"></param>
 /// <param name="org"></param>
 /// <param name="fontFace"></param>
 /// <param name="fontScale"></param>
 /// <param name="color"></param>
 /// <param name="thickness"></param>
 /// <param name="lineType"></param>
 /// <param name="bottomLeftOrigin"></param>
 public static void PutText(Mat img, string text, Point org,
     FontFace fontFace, double fontScale, Scalar color,
     int thickness = 1, LineType lineType = LineType.Link8, bool bottomLeftOrigin = false) 
 {
     if (img == null)
         throw new ArgumentNullException("img");
     if (String.IsNullOrEmpty(text))
         throw new ArgumentNullException(text); 
     img.ThrowIfDisposed();
     NativeMethods.core_putText(img.CvPtr, text, org, (int)fontFace, fontScale, color, 
         thickness, (int)lineType, bottomLeftOrigin ? 1 : 0);
 }
Beispiel #28
0
 private static extern void cvePutText(IntPtr imagePtr,
     IntPtr text,
     ref Point position,
     FontFace fontFace,
     double fontScale,
     ref MCvScalar color,
     int thickness,
     LineType lineType,
     [MarshalAs(UnmanagedType.U1)] bool bottomLeftOrigin);
        private static FontStyle GetStyle(FontFace face)
        {
            switch (face)
            {
                case FontFace.Bold:
                    return FontStyle.Bold;

                case FontFace.Italic:
                    return FontStyle.Italic;

                case FontFace.BoldItalic:
                    return FontStyle.Bold | FontStyle.Italic;

                default:
                    return FontStyle.Regular;
            }
        }
Beispiel #30
0
 public static void DrawText(IInputOutputArray image,
     string text,
     Point position,
     FontFace fontFace,
     double fontScale,
     MCvScalar color,
     int thickness = 1,
     LineType lineType = LineType.EightConnected,
     bool bottomLeftOrigin = false)
 {
     using (CvString cvString = new CvString(text))
     {
         using (InputOutputArray array = image.GetInputOutputArray())
         {
             cvePutText(array, cvString, ref position, fontFace, fontScale, ref color, thickness, lineType, bottomLeftOrigin);
         }
     }
 }
 private static SvgFontWeight MapFontWeight(FontFace face)
 {
     switch (face)
     {
         case FontFace.Bold:
             return SvgFontWeight.bold;
         default:
             return SvgFontWeight.normal;
     }
 }
Beispiel #32
0
        internal unsafe static void Main(string[] args)
        {
            try
            {
                int    pixelsCount = 1 << 18;
                uint[] pixelsArray = new uint[65536];

                using (DisposableHandle handle = DisposableHandle.Alloc(pixelsArray))
                {
                    NTInvoke.SetUnmanagedMemory(handle, 255, pixelsCount);
                }

                byte[] outputData = null;

                MCvScalar redColor   = MCvScalarExtensions.FromColor(Colors.Red);
                MCvScalar greenColor = MCvScalarExtensions.FromColor(Colors.Green);

                using (PresentationImage prImage = new PresentationImage(256, 256))
                {
                    prImage.WritePixels(pixelsArray);

                    FontFace[] faces = new FontFace[]
                    {
                        FontFace.HersheyComplex,
                        FontFace.HersheyComplexSmall,
                        FontFace.HersheyDuplex,
                        FontFace.HersheyPlain,
                        FontFace.HersheyScriptComplex,
                        FontFace.HersheyScriptSimplex,
                        FontFace.HersheySimplex,
                        FontFace.HersheyTriplex
                    };

                    Parallel.For(0, 8, (int index) =>
                    {
                        Point drawPoint   = new Point(10, 30 + 30 * index);
                        FontFace drawFace = faces[index];

                        string outputText = Enum.GetName(typeof(FontFace), drawFace);

                        CvInvoke.DrawText(prImage, outputText, drawPoint, drawFace, 1.0D, redColor, 1);
                    });

                    outputData = CvInvoke.Imencode(prImage, ImageEncoding.Jpeg, new int[] { 95 });
                }

                if (outputData != null && outputData.Length > 0)
                {
                    using (MemoryStream dataStream = new MemoryStream(outputData))
                    {
                        JpegBitmapDecoder decoder = new JpegBitmapDecoder(dataStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnLoad);
                        BitmapFrame       frame   = decoder.Frames[0];

                        Window imageWindow = new Window()
                        {
                            Height                = 300.0D,
                            Width                 = 500.0D,
                            Title                 = "Image window",
                            ResizeMode            = ResizeMode.CanResize,
                            WindowStartupLocation = WindowStartupLocation.CenterScreen
                        };
                        imageWindow.Content = new Image()
                        {
                            Source = frame
                        };
                        new Application().Run(imageWindow);
                    }
                }
            }
            catch (Exception exc)
            {
                Debug.WriteLine("\tCatched exception: {0}\r\n{1}", exc.Message, exc);
            }
            finally
            {
                Debug.WriteLine("\tData released succesfully.");
            }
        }
Beispiel #33
0
        /// <summary>
        /// 文字描画関数に渡されるフォント構造体を初期化する
        /// </summary>
        /// <param name="font_face">フォント名の識別子</param>
        /// <param name="hscale">幅の比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の幅で表示される. 0.5fにした場合, 文字は元々の半分の幅で表示される.</param>
        /// <param name="vscale">高さの比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の高さで表示される. 0.5fにした場合, 文字は元々の半分の高さで表示される.</param>
#else
        /// <summary>
        /// Initializes font structure
        /// </summary>
        /// <param name="font_face">Font name identifier. Only a subset of Hershey fonts are supported now.</param>
        /// <param name="hscale">Horizontal scale. If equal to 1.0f, the characters have the original width depending on the font type. If equal to 0.5f, the characters are of half the original width. </param>
        /// <param name="vscale">Vertical scale. If equal to 1.0f, the characters have the original height depending on the font type. If equal to 0.5f, the characters are of half the original height. </param>
#endif
        public CvFont(FontFace font_face, double hscale, double vscale)
            : this(font_face, hscale, vscale, 0, 1, LineType.Link8)
        {
        }
Beispiel #34
0
        public void Import(FontDescription options)
        {
            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)(fontMetrics.LineGap + fontMetrics.Ascent + fontMetrics.Descent) / fontMetrics.DesignUnitsPerEm * fontSize;

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

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

                glyphList.Add(glyph);
            }

            Glyphs = glyphList;

            factory.Dispose();
        }
Beispiel #35
0
        /// <summary>
        /// 文字描画関数に渡されるフォント構造体を初期化する
        /// </summary>
        /// <param name="font_face">フォント名の識別子</param>
        /// <param name="hscale">幅の比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の幅で表示される. 0.5fにした場合, 文字は元々の半分の幅で表示される.</param>
        /// <param name="vscale">高さの比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の高さで表示される. 0.5fにした場合, 文字は元々の半分の高さで表示される.</param>
        /// <param name="shear">垂直線からの文字の相対的な角度.ゼロの場合は非イタリックフォントで,例えば,1.0fは≈45°を意味する.</param>
        /// <param name="thickness">文字の太さ.</param>
#else
        /// <summary>
        /// Initializes font structure
        /// </summary>
        /// <param name="font_face">Font name identifier. Only a subset of Hershey fonts are supported now.</param>
        /// <param name="hscale">Horizontal scale. If equal to 1.0f, the characters have the original width depending on the font type. If equal to 0.5f, the characters are of half the original width. </param>
        /// <param name="vscale">Vertical scale. If equal to 1.0f, the characters have the original height depending on the font type. If equal to 0.5f, the characters are of half the original height. </param>
        /// <param name="shear">Approximate tangent of the character slope relative to the vertical line. Zero value means a non-italic font, 1.0f means ≈45° slope, etc. thickness Thickness of lines composing letters outlines. The function cvLine is used for drawing letters. </param>
        /// <param name="thickness">Thickness of the text strokes. </param>
#endif
        public CvFont(FontFace font_face, double hscale, double vscale, double shear, int thickness)
            : this(font_face, hscale, vscale, shear, thickness, LineType.Link8)
        {
        }
Beispiel #36
0
        private void TextByGlyph(RectangleF rect, string text, TextInfo info, SolidColorBrush brush)
        {
            FontFace fontFace;

            if (!m_faceMap.TryGetValue(info.Font, out fontFace))
            {
                using (var f = new SharpDX.DirectWrite.Factory())
                    using (var collection = f.GetSystemFontCollection(false))
                    {
                        int familyIndex;
                        if (!collection.FindFamilyName(info.Font.FamilylName, out familyIndex))
                        {
                            return;
                        }

                        using (var family = collection.GetFontFamily(familyIndex))
                            using (var font = family.GetFont(0))
                            {
                                fontFace = new FontFace(font);
                                m_faceMap.Add(info.Font, fontFace);
                            }
                    }
            }

            var codePoints = EnumCodePoints(text).ToArray();
            var indices    = fontFace.GetGlyphIndices(codePoints);

            // Get glyph
            var metrices = fontFace.GetDesignGlyphMetrics(indices, false);

            // draw
            var glyphRun = new GlyphRun
            {
                FontFace = fontFace,
                Indices  = indices,
                FontSize = info.Font.Size,
            };

            bool done = false;

            using (var f = new SharpDX.DirectWrite.Factory())
                using (var ff = f.QueryInterface <SharpDX.DirectWrite.Factory4>())
                {
                    var desc = new GlyphRunDescription
                    {
                    };
                    ColorGlyphRunEnumerator it;
                    var result = ff.TryTranslateColorGlyphRun(0, 0, glyphRun,
                                                              null, MeasuringMode.Natural, null, 0, out it);
                    if (result.Code == DWRITE_E_NOCOLORLOR)
                    {
                        m_device.D2DDeviceContext.DrawGlyphRun(rect.TopLeft + new Vector2(0, info.Font.Size), glyphRun, brush, MeasuringMode.Natural);
                    }
                    else
                    {
                        while (true)
                        {
                            var colorBrush = GetOrCreateBrush(new Color4(
                                                                  it.CurrentRun.RunColor.R,
                                                                  it.CurrentRun.RunColor.G,
                                                                  it.CurrentRun.RunColor.B,
                                                                  it.CurrentRun.RunColor.A));
                            m_device.D2DDeviceContext.DrawGlyphRun(rect.TopLeft + new Vector2(0, info.Font.Size),
                                                                   it.CurrentRun.GlyphRun, colorBrush, MeasuringMode.Natural);
                            done = true;

                            SharpDX.Mathematics.Interop.RawBool hasNext;
                            it.MoveNext(out hasNext);
                            if (!hasNext)
                            {
                                break;;
                            }
                        }
                    }
                }
        }
Beispiel #37
0
 /// <summary>
 /// renders text string in the image
 /// </summary>
 /// <param name="text"></param>
 /// <param name="org"></param>
 /// <param name="fontFace"></param>
 /// <param name="fontScale"></param>
 /// <param name="color"></param>
 /// <param name="thickness"></param>
 /// <param name="lineType"></param>
 /// <param name="bottomLeftOrigin"></param>
 public void PutText(string text, Point org,
     FontFace fontFace, double fontScale, Scalar color,
     int thickness = 1,
     LineType lineType = LineType.Link8,
     bool bottomLeftOrigin = false)
 {
     Cv2.PutText(this, text, org, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin);
 }
Beispiel #38
0
        public ChatLine(Vector2 position, float drawDepth, float fontSize, float lineWidth, Message msg, FontFace fontFace)
        {
            this.fontSize = fontSize;

            nameSprite    = new pText(string.Empty, fontSize, position, new Vector2(lineWidth, 0), drawDepth, true, Color.White);
            messageSprite = new pText(string.Empty, fontSize, position, new Vector2(lineWidth, 0), drawDepth, true, Color.White);

            nameSprite.FontFace    = fontFace;
            messageSprite.FontFace = fontFace;

            bool isMe = msg.Name.Length > 8 && msg.Name[7] == '*' && msg.Content.Length == 0;

            initialColour = msg.Colour;

            messageSprite.Text       = msg.Content;
            nameSprite.Text          = msg.Name;
            nameSprite.InitialColour = initialColour;

            nameSprite.HandleInput = !isMe && msg.User != null;

            nameSprite.Tag = msg.User;

            nameSprite.OnHover     += delegate(object sender, EventArgs args) { ((pSprite)sender).FadeColour(userFlashColour, 100); };
            nameSprite.OnHoverLost += delegate(object sender, EventArgs args) { ((pSprite)sender).FadeColour(initialColour, 700); };
            nameSprite.OnClick     += ChatEngine.user_OnClick;
            nameSprite.ClickRequiresConfirmation = true;

            float offsetX = Math.Max(50, nameSprite.MeasureText().X);

            messageSprite.Position.X        += offsetX;
            messageSprite.InitialPosition.X += offsetX;
            messageSprite.TextBounds.X      -= offsetX;

            pText checkSprite = isMe ? nameSprite : messageSprite;

            if (msg.Colour.A != 0)
            {
                Sprites.Add(nameSprite);
            }

            Sprites.Add(messageSprite);

            try
            {
                if (checkSprite.Text.Length > 0 && msg.FormatterResults != null && msg.FormatterResults.Links.Count > 0)
                {
                    System.Drawing.RectangleF[] characterRegions = checkSprite.MeasureCharacters();
                    List <int> lineBreaks = checkSprite.ComputeLineBreaks(characterRegions);

                    foreach (Link l in msg.FormatterResults.Links)
                    {
                        if (l.Url.IndexOf('\uD83D') == 0 && l.Url.Length == 2)
                        {
                            //emoji
                            float   thisOffsetX = (int)(offsetX + checkSprite.MeasureText(0, l.Index).X - (l.Index == 0 ? 4 : 1));
                            string  temp        = ((int)l.Url[1]).ToString();
                            pSprite p           = new pSprite(TextureManager.Load("emoji-" + temp), Fields.TopLeft, Origins.TopLeft, Clocks.Game, nameSprite.Position + new Vector2(thisOffsetX, 0), 0.975f, true, Color.White);

                            Sprites.Add(p);
                        }
                        else
                        {
                            // First smaller or equal element. I.E. linebreak immediately before the link starts.
                            int start = lineBreaks.BinarySearch(l.Index);
                            if (start < 0)
                            {
                                start = ~start - 1;
                            }

                            List <pSprite> linkSprites = new List <pSprite>();

                            int pos = l.Index;
                            while (pos < l.Index + l.Length)
                            {
                                int nextLineBreak = start >= lineBreaks.Count - 1 ? checkSprite.Text.Length : (lineBreaks[start + 1]);
                                pos = Math.Min(nextLineBreak, l.Index + l.Length);

                                int beginIndex = Math.Max(lineBreaks[start], l.Index);

                                // Go backwards until we find the first character that actually has bounds. Reasoning is, that whitespaces at the end of the line can have 0,0,0,0 as rect.
                                int end = pos - 1;
                                while (end > beginIndex && characterRegions[end].Width == 0 && characterRegions[end].Height == 0 && characterRegions[end].X == 0 && characterRegions[end].Y == 0)
                                {
                                    --end;
                                }

                                offsetX = characterRegions[beginIndex].X - 1;
                                System.Drawing.RectangleF endRect = characterRegions[end];
                                float sizeX = endRect.X + endRect.Width - offsetX + 1;

                                linkSprites.Add(AddLinkSprite(l, linkSprites, new Vector2(offsetX, fontSize * start + 1f), new Vector2(sizeX, fontSize)));

                                ++start;
                            }
                        }
                    }
                }
            }
            catch { }
        }