Пример #1
0
        /// <inheritdoc/>
        public override void AppendTo(ShapedStringBuilder builder, UltravioletFontFace fontFace, Int32 start, Int32 length, Int32 sourceIndexOffset = 0)
        {
            Contract.Require(builder, nameof(builder));
            Contract.Require(fontFace, nameof(fontFace));
            Contract.EnsureRange(start >= 0 && start < rawstr.Length, nameof(start));
            Contract.EnsureRange(length >= 0 && start + length <= rawstr.Length, nameof(length));
            Contract.EnsureNotDisposed(this, Disposed);

            unsafe
            {
                Shape(fontFace, out var glyphInfo, out var glyphPosition, out var glyphCount);

                var end = start + length;
                for (var i = 0; i < glyphCount; i++)
                {
                    var cluster = (Int32)glyphInfo->cluster;
                    if (cluster >= start)
                    {
                        if (cluster >= end)
                        {
                            break;
                        }

                        CreateShapedChar(glyphInfo, glyphPosition, sourceIndexOffset + cluster, out var sc);
                        builder.Append(sc);
                    }
                    glyphInfo++;
                    glyphPosition++;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Performs shaping on the native buffer using the specified font..
        /// </summary>
        private unsafe void Shape(UltravioletFontFace fontFace, out hb_glyph_info_t *infos, out hb_glyph_position_t *positions, out UInt32 count)
        {
            ValidateUnicodeProperties();

            var ftFontFace = fontFace as FreeTypeFontFace;

            if (ftFontFace == null)
            {
                throw new NotSupportedException(FreeTypeStrings.TextShaperRequiresFreeTypeFont);
            }

            PopulateNativeBuffer();

            if (lastUsedFont != ftFontFace && lastUsedFontNative != IntPtr.Zero)
            {
                hb_font_destroy(lastUsedFontNative);
                lastUsedFont       = null;
                lastUsedFontNative = IntPtr.Zero;
            }

            var fontNative    = (lastUsedFontNative == IntPtr.Zero) ? hb_ft_font_create(ftFontFace.NativePointer, IntPtr.Zero) : lastUsedFontNative;
            var fontLoadFlags = ftFontFace.IsStroked ? FT_LOAD_NO_BITMAP : FT_LOAD_COLOR;

            hb_ft_font_set_load_flags(fontNative, fontLoadFlags);
            lastUsedFont       = ftFontFace;
            lastUsedFontNative = fontNative;

            hb_shape(fontNative, native, IntPtr.Zero, 0);

            var glyphCount = 0u;

            infos     = (hb_glyph_info_t *)hb_buffer_get_glyph_infos(native, (IntPtr)(&glyphCount));
            positions = (hb_glyph_position_t *)hb_buffer_get_glyph_positions(native, IntPtr.Zero);
            count     = glyphCount;
        }
Пример #3
0
        /// <summary>
        /// Gets the absolute position of the text when rendered.
        /// </summary>
        /// <param name="font">The font with which the command is being rendered.</param>
        /// <param name="x">The x-coordinate of the top-left corner of the line of text that is being rendered.</param>
        /// <param name="y">The y-coordinate of the top-left corner of the line of text that is being rendered.</param>
        /// <param name="lineHeight">The height of the line of text that is being rendered.</param>
        /// <returns>A <see cref="Vector2"/> that describes the absolute position of the text.</returns>
        public Vector2 GetAbsolutePositionVector(UltravioletFontFace font, Single x, Single y, Int32 lineHeight)
        {
            var lineHeightSansDescender = lineHeight + font.Descender;
            var textHeightSansDescender = textHeight + font.Descender;

            return(new Vector2(x + textX, (y - font.Descender) + textY + ((lineHeightSansDescender - textHeightSansDescender) / 2)));
        }
Пример #4
0
        /// <summary>
        /// Gets the absolute bounds of the text when rendered.
        /// </summary>
        /// <param name="font">The font with which the command is being rendered.</param>
        /// <param name="x">The x-coordinate of the top-left corner of the line of text that is being rendered.</param>
        /// <param name="y">The y-coordinate of the top-left corner of the line of text that is being rendered.</param>
        /// <param name="lineHeight">The height of the line of text that is being rendered.</param>
        /// <returns>A <see cref="Rectangle"/> that describes the absolute bounds of the text.</returns>
        public Rectangle GetAbsoluteBounds(UltravioletFontFace font, Int32 x, Int32 y, Int32 lineHeight)
        {
            var lineHeightSansDescender = lineHeight + font.Descender;
            var textHeightSansDescender = textHeight + font.Descender;

            return(new Rectangle(x + textX, (y - font.Descender) + textY + ((lineHeightSansDescender - textHeightSansDescender) / 2), textWidth, textHeight));
        }
Пример #5
0
        /// <summary>
        /// Gets the absolute position of the text when rendered.
        /// </summary>
        /// <param name="font">The font with which the command is being rendered.</param>
        /// <param name="x">The x-coordinate of the top-left corner of the line of text that is being rendered.</param>
        /// <param name="y">The y-coordinate of the top-left corner of the line of text that is being rendered.</param>
        /// <param name="lineHeight">The height of the line of text that is being rendered.</param>
        /// <returns>A <see cref="Point2"/> that describes the absolute position of the text.</returns>
        public Point2 GetAbsolutePosition(UltravioletFontFace font, Int32 x, Int32 y, Int32 lineHeight)
        {
            var lineHeightSansDescender = lineHeight + font.Descender;
            var textHeightSansDescender = textHeight + font.Descender;

            return(new Point2(x + textX, (y - font.Descender) + textY + ((lineHeightSansDescender - textHeightSansDescender) / 2)));
        }
Пример #6
0
        /// <summary>
        /// Appends the contents of the specified <see cref="TextShaper"/> to the end of the
        /// current <see cref="ShapedStringBuilder"/> instance.
        /// </summary>
        /// <param name="shaper">The <see cref="TextShaper"/> instance from which to append values.</param>
        /// <param name="fontFace">The font face with which to shape the string.</param>
        /// <returns>A reference to this instance after the append operation has completed.</returns>
        public ShapedStringBuilder Append(TextShaper shaper, UltravioletFontFace fontFace)
        {
            Contract.Require(shaper, nameof(shaper));

            shaper.AppendTo(this, fontFace);

            return(this);
        }
Пример #7
0
        /// <summary>
        /// Gets the absolute bounds of the text when rendered.
        /// </summary>
        /// <param name="font">The font with which the command is being rendered.</param>
        /// <param name="x">The x-coordinate of the top-left corner of the line of text that is being rendered.</param>
        /// <param name="y">The y-coordinate of the top-left corner of the line of text that is being rendered.</param>
        /// <param name="lineWidth">The width of the line of text that is being rendered.</param>
        /// <param name="lineHeight">The height of the line of text that is being rendered.</param>
        /// <param name="direction">The direction in which the text is oriented.</param>
        /// <returns>A <see cref="Rectangle"/> that describes the absolute bounds of the text.</returns>
        public Rectangle GetAbsoluteBounds(UltravioletFontFace font, Int32 x, Int32 y, Int32 lineWidth, Int32 lineHeight, TextDirection direction)
        {
            var lineHeightSansDescender = lineHeight + font.Descender;
            var textHeightSansDescender = TextHeight + font.Descender;
            var absX = (direction == TextDirection.RightToLeft) ? (x + lineWidth) - (TextX + TextWidth) : x + TextX;
            var absY = (y - font.Descender) + TextY + ((lineHeightSansDescender - textHeightSansDescender) / 2);

            return(new Rectangle(absX, absY, TextWidth, TextHeight));
        }
Пример #8
0
        /// <summary>
        /// Gets the absolute position of the text when rendered.
        /// </summary>
        /// <param name="font">The font with which the command is being rendered.</param>
        /// <param name="x">The x-coordinate of the top-left corner of the line of text that is being rendered.</param>
        /// <param name="y">The y-coordinate of the top-left corner of the line of text that is being rendered.</param>
        /// <param name="lineWidth">The width of the line of text that is being rendered.</param>
        /// <param name="lineHeight">The height of the line of text that is being rendered.</param>
        /// <param name="direction">The direction in which the text is oriented.</param>
        /// <returns>A <see cref="Vector2"/> that describes the absolute position of the text.</returns>
        public Vector2 GetAbsolutePositionVector(UltravioletFontFace font, Single x, Single y, Int32 lineWidth, Int32 lineHeight, TextDirection direction)
        {
            var lineHeightSansDescender = lineHeight + font.Descender;
            var textHeightSansDescender = TextHeight + font.Descender;
            var absX = (direction == TextDirection.RightToLeft) ? (x + lineWidth) - (TextX + TextWidth) : x + TextX;
            var absY = (y - font.Descender) + TextY + ((lineHeightSansDescender - textHeightSansDescender) / 2);

            return(new Vector2(absX, absY));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="TextLayoutToken"/> structure.
 /// </summary>
 /// <param name="text">The token's text.</param>
 /// <param name="bounds">The token's bounds relative to its layout region.</param>
 /// <param name="fontFace">The token's font face.</param>
 /// <param name="icon">The token's icon.</param>
 /// <param name="glyphShader">The token's glyph shader.</param>
 /// <param name="color">The token's color.</param>
 internal TextLayoutToken(StringSegment text, Rectangle bounds, UltravioletFontFace fontFace, TextIconInfo?icon, GlyphShader glyphShader, Color?color)
 {
     this.text        = text;
     this.bounds      = bounds;
     this.fontFace    = fontFace;
     this.icon        = icon;
     this.glyphShader = glyphShader;
     this.color       = color;
 }
Пример #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ShapedString"/> class.
        /// </summary>
        /// <param name="fontFace">The font face with which the string was created.</param>
        /// <param name="language">The name of the language which this string contains.</param>
        /// <param name="script">A <see cref="TextScript"/> value specifying which script which this string contains.</param>
        /// <param name="direction">A <see cref="TextDirection"/> value specifying the direction in which this string should be written.</param>
        /// <param name="value">An array of <see cref="ShapedChar"/> values.</param>
        /// <param name="startIndex">The starting position within <paramref name="value"/>.</param>
        /// <param name="count">The number of characters within <paramref name="value"/> to use.</param>
        public ShapedString(UltravioletFontFace fontFace, String language, TextScript script, TextDirection direction, ShapedChar[] value, Int32 startIndex, Int32 count)
        {
            Contract.Require(fontFace, nameof(fontFace));
            Contract.Require(language, nameof(language));
            Contract.Require(value, nameof(value));

            this.FontFace  = fontFace;
            this.Language  = language;
            this.Script    = script;
            this.Direction = direction;
            this.buffer    = CreateShapedString(value, startIndex, count);
        }
Пример #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ShapedString"/> class.
        /// </summary>
        /// <param name="fontFace">The font face with which the string was created.</param>
        /// <param name="language">The name of the language which this string contains.</param>
        /// <param name="script">A <see cref="TextScript"/> value specifying which script which this string contains.</param>
        /// <param name="direction">A <see cref="TextDirection"/> value specifying the direction in which this string should be written.</param>
        /// <param name="value">An array of <see cref="ShapedChar"/> values.</param>
        public ShapedString(UltravioletFontFace fontFace, String language, TextScript script, TextDirection direction, ShapedChar[] value)
        {
            Contract.Require(fontFace, nameof(fontFace));
            Contract.Require(language, nameof(language));
            Contract.Require(value, nameof(value));

            this.FontFace  = fontFace;
            this.Language  = language;
            this.Script    = script;
            this.Direction = direction;
            this.buffer    = CreateShapedString(value, 0, value?.Length ?? 0);
        }
Пример #12
0
        /// <inheritdoc/>
        public override ShapedString CreateShapedString(UltravioletFontFace fontFace, Int32 start, Int32 length, Int32 sourceIndexOffset = 0)
        {
            Contract.Require(fontFace, nameof(fontFace));
            Contract.EnsureRange(start >= 0 && start < rawstr.Length, nameof(start));
            Contract.EnsureRange(length >= 0 && start + length <= rawstr.Length, nameof(length));
            Contract.EnsureNotDisposed(this, Disposed);

            unsafe
            {
                Shape(fontFace, out var glyphInfo, out var glyphPosition, out var glyphCount);

                var end        = start + length;
                var chars      = new ShapedChar[glyphCount];
                var charsCount = 0;
                for (var i = 0; i < glyphCount; i++)
                {
                    var cluster = (Int32)glyphInfo->cluster;
                    if (cluster >= start)
                    {
                        if (cluster >= end)
                        {
                            break;
                        }

                        switch (rawstr[cluster])
                        {
                        case '\n':
                            chars[i] = new ShapedChar('\n', sourceIndexOffset + cluster, Int16.MaxValue, Int16.MaxValue, Int16.MaxValue);
                            break;

                        case '\t':
                            chars[i] = new ShapedChar('\t', sourceIndexOffset + cluster, Int16.MaxValue, Int16.MaxValue, Int16.MaxValue);
                            break;

                        default:
                            CreateShapedChar(glyphInfo, glyphPosition, sourceIndexOffset + cluster, out chars[i]);
                            break;
                        }
                        charsCount++;
                    }
                    glyphInfo++;
                    glyphPosition++;
                }

                return(new ShapedString(fontFace, GetLanguage(), GetScript(), GetDirection(), chars, 0, charsCount));
            }
        }
Пример #13
0
 /// <inheritdoc/>
 public override void AppendTo(ShapedStringBuilder builder, UltravioletFontFace fontFace, Int32 sourceIndexOffset = 0) =>
 AppendTo(builder, fontFace, 0, rawstr.Length, sourceIndexOffset);
Пример #14
0
 /// <summary>
 /// Converts the value of the current <see cref="ShapedStringBuilder"/> to a new <see cref="ShapedString"/> instance.
 /// </summary>
 /// <param name="fontFace">The font face with which the string was created.</param>
 /// <param name="language">The name of the language which this string contains.</param>
 /// <param name="script">A <see cref="TextScript"/> value specifying which script which this string contains.</param>
 /// <param name="direction">A <see cref="TextDirection"/> value specifying the direction in which this string should be written.</param>
 /// <returns>The <see cref="ShapedString"/> instance which was created.</returns>
 public ShapedString ToShapedString(UltravioletFontFace fontFace, String language, TextScript script, TextDirection direction) =>
 new ShapedString(fontFace, language, script, direction, buffer, 0, length);
Пример #15
0
 /// <summary>
 /// Appends the contents of a subset of this shaping buffer to the specified <see cref="ShapedStringBuilder"/> instance.
 /// </summary>
 /// <param name="builder">The <see cref="ShapedStringBuilder"/> instance to which to append this shaper's contents.</param>
 /// <param name="fontFace">The font face with which to shape the string.</param>
 /// <param name="start">The offset of the character in the original string which corresponds to the beginning of the shaped substring.</param>
 /// <param name="length">The number of characters in the raw substring from which to create the shaped substring.</param>
 /// <param name="sourceIndexOffset">The offset which is applied to the source indices assigned to shaped characters in the resulting string.</param>
 public abstract void AppendTo(ShapedStringBuilder builder, UltravioletFontFace fontFace, Int32 start, Int32 length, Int32 sourceIndexOffset = 0);
Пример #16
0
 /// <summary>
 /// Creates a new <see cref="ShapedString"/> instance from a subset of the current contents of the shaping buffer.
 /// </summary>
 /// <param name="fontFace">The font face with which to shape the string.</param>
 /// <param name="start">The offset of the character in the original string which corresponds to the beginning of the shaped substring.</param>
 /// <param name="length">The number of characters in the raw substring from which to create the shaped substring.</param>
 /// <param name="sourceIndexOffset">The offset which is applied to the source indices assigned to shaped characters in the resulting string.</param>
 /// <returns>A new shaped string instance.</returns>
 public abstract ShapedString CreateShapedString(UltravioletFontFace fontFace, Int32 start, Int32 length, Int32 sourceIndexOffset = 0);
Пример #17
0
 /// <inheritdoc/>
 public override ShapedString CreateShapedString(UltravioletFontFace fontFace, Int32 sourceIndexOffset = 0) =>
 CreateShapedString(fontFace, 0, rawstr.Length, sourceIndexOffset);