示例#1
0
        private void GetLspanFor(int pos, out RichTextBoxLayoutSpan lspan, out int lspanIndex, out int charIndexInLspan)
        {
            var nextLspanIndex = Enumerable.Range(0, LayoutSpans.Count).Where(x => pos < LayoutSpans[x].TextAbsPosition).FirstOrNull() ?? LayoutSpans.Count;

            lspanIndex       = nextLspanIndex - 1;
            lspan            = LayoutSpans[lspanIndex];
            charIndexInLspan = pos - lspan.TextAbsPosition;
        }
示例#2
0
 private bool TryGetClosestSpanAt(Vector2 point, out RichTextBoxLayoutSpan lspan)
 {
     if (LayoutSpans.Count == 0)
     {
         lspan = default(RichTextBoxLayoutSpan);
         return(false);
     }
     lspan = LayoutSpans.Minimal(x => x.DistanceFrom(point));
     return(true);
 }
示例#3
0
        private void FlushStrip(BuildingContext context, int paragraphIndex, float tabOffset, SubList <Subspan> subspans, bool isFirstStrip, bool isLastStrip)
        {
            // todo: consider direction
            var paragraph = context.Text.Paragraphs[paragraphIndex];
            //if (!isLastStrip)
            //    subspans = TrimEnd(subspans);
            var commonSize = MeasureSubspans(context, subspans);
            var stripSize  = new Size2(context.RemainingShape.Width, commonSize.Height);

            if (paragraph.Style.Alignment != RtParagraphAlignment.Justify || isLastStrip)
            {
                // todo: tabs
                var mergedSubspans = MergeSubspans(subspans);
                var newRectangles  = new RichTextBoxLayoutSpan[mergedSubspans.Count];
                var strip          = AaRectangle2.FromCornerAndDimensions(
                    context.StripStartPoint.X, context.StripStartPoint.Y,
                    commonSize.Width, commonSize.Height);
                var rectOffsetX = context.StripStartPoint.X + tabOffset;
                var charIndex   = 0;

                for (var i = 0; i < mergedSubspans.Count; i++)
                {
                    var subspan     = mergedSubspans[i];
                    var subspanSize = MeasureSubspan(subspan);

                    var charWidths = subspan.Text.Select(x => measurer.GetCharSize(x, subspan.Style).Width).ToArray();
                    var subspanWidthWithoutKerning = charWidths.Sum();
                    var kerningAdjustment          = subspanSize.Width / subspanWidthWithoutKerning;
                    var adjustedCharWidths         = charWidths.Select(x => x * kerningAdjustment).ToArray();
                    var charOffsets = Enumerable.Range(0, subspan.Text.Length).Select(x => adjustedCharWidths.Take(x).Sum()).ToArray();

                    newRectangles[i] = new RichTextBoxLayoutSpan
                    {
                        TextRelPosition = subspan.TextRelPosition,
                        TextAbsPosition = context.Text.GetGlobalIndex(subspan.TextRelPosition),
                        Bounds          = new AaRectangle2(
                            new Vector2(rectOffsetX, context.StripStartPoint.Y),
                            new Vector2(rectOffsetX + subspanSize.Width, context.StripStartPoint.Y + commonSize.Height)),
                        Strip            = strip,
                        CharOffsets      = charOffsets,
                        Text             = subspan.Text,
                        Style            = subspan.Style,
                        Embedding        = subspan.Embedding,
                        EmbeddingHandler = subspan.EmbeddingHandler,
                        EmbeddingImage   = subspan.EmbeddingImage
                    };

                    rectOffsetX += subspanSize.Width;
                    charIndex   += subspan.Text.Length;
                }

                var adjustment = 0f;
                switch (paragraph.Style.Alignment)
                {
                case RtParagraphAlignment.Left:
                    break;

                case RtParagraphAlignment.Center:
                    var leftCenterX = rectOffsetX / 2;
                    var stripCenter = stripSize.Width / 2;
                    adjustment = stripCenter - leftCenterX;
                    break;

                case RtParagraphAlignment.Right:
                    adjustment = stripSize.Width - rectOffsetX;
                    break;

                case RtParagraphAlignment.Justify:
                default:
                    throw new ArgumentOutOfRangeException();
                }
                for (var i = 0; i < newRectangles.Length; i++)
                {
                    newRectangles[i].Bounds.Center.X += adjustment;
                }
                context.LayoutSpans.AddRange(newRectangles);
                context.RemainingShape = new AaRectangle2(context.RemainingShape.MinMin + Vector2.UnitY * stripSize.Height,
                                                          context.RemainingShape.MaxMax);

                if (isFirstStrip)
                {
                    // todo: adjust for other directions
                    var bulletStr = paragraph.Style.ListStyle.GetIconFor(paragraph.Style.TabCount, /*todo*/ 0);
                    FlushBullet(context, new Vector2(tabOffset, strip.MaxY), bulletStr, subspans.First().Style);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
示例#4
0
 private static int GetPositionInLspan(Vector2 point, RichTextBoxLayoutSpan lspan)
 {
     return(lspan.TextAbsPosition + lspan.ClosestIndexFor(point.X));
 }
示例#5
0
 public bool TryGetSpanAt(Vector2 point, out RichTextBoxLayoutSpan lspan)
 {
     return(TryGetClosestSpanAt(point, out lspan) && lspan.Bounds.ContainsPoint(point));
 }