예제 #1
0
 public Box(Run run, string str, BoxFontInfo fontInfo, ushort glyphIndex, double width)
     : this(run, str)
 {
     this.FontInfo   = fontInfo;
     this.GlyphIndex = glyphIndex;
     this.Width      = width;
 }
예제 #2
0
 public Box(Run run, string str, BoxFontInfo fontInfo, RGFloat width, RGFloat height)
     : this(run, str)
 {
     this.FontInfo = fontInfo;
     this.Width    = width;
     this.Height   = height;
 }
예제 #3
0
        private void CommitWord(ref Line line,         /*BoxGroup cachedBoxes, List<Box> wordBoxes, ref RGFloat cachedBoxesSize,*/
                                RelayoutSession rs, ref BoxFontInfo fontInfo)
        {
            bool newline = false;

            if (this.rt.TextWrap != TextWrapMode.NoWrap)
            {
                var angle = this.rt.RotationAngle;

                if (angle == 0)
                {
                    newline = rs.currentLoc.X + rs.cacheBoxesWidth > rs.bounds.Width;
                }
                else
                {
                    var w = rs.cacheBoxesWidth;
                    var h = rs.cacheBoxesMaxHeight;

                    var s = rs.s;
                    var c = rs.c;

                    var leftTop     = rs.currentLoc;
                    var rightTop    = new Point(leftTop.X + w * c, leftTop.Y + w * s);
                    var leftBottom  = new Point(leftTop.X - h * s, leftTop.Y + h * c);
                    var rightBottom = new Point(rightTop.X - h * s, rightTop.Y + h * c);

                    if (angle > 0)
                    {
                        var maxY = Math.Max(leftTop.Y, Math.Max(rightTop.Y, Math.Max(leftBottom.Y, rightBottom.Y)));
                        var maxX = Math.Max(leftTop.X, Math.Max(rightTop.X, Math.Max(leftBottom.X, rightBottom.X)));

                        newline = (maxX >= rs.bounds.Width || maxY > rs.bounds.Height);
                    }
                    else                     // angle < 0
                    {
                        var minY = Math.Min(leftTop.Y, Math.Min(rightTop.Y, Math.Min(leftBottom.Y, rightBottom.Y)));
                        var maxX = Math.Max(leftTop.X, Math.Max(rightTop.X, Math.Max(leftBottom.X, rightBottom.X)));

                        newline = (maxX > rs.bounds.Width || minY < -rs.bounds.Height);
                    }
                }
            }

            if (newline)
            {
                CommitLine(rs, line);
                line = new Line(rs.currentLoc.Y);
            }

            if (line.Ascent < rs.maxBaseline)
            {
                line.Ascent = rs.maxBaseline;
            }
            if (line.Height < rs.maxHeight)
            {
                line.Height = rs.maxHeight;
            }

            foreach (var cb in rs.cacheBoxes)
            {
                if (rt.RotationAngle == 0)
                {
                    cb.leftTop.X     = rs.currentLoc.X;
                    cb.rightTop.X    = cb.leftTop.X + cb.Width;
                    rs.currentLoc.X += cb.Width;
                }
                else
                {
                    cb.leftTop       = rs.currentLoc;
                    rs.currentLoc.X += (float)(cb.Width * rs.c);
                    rs.currentLoc.Y += (float)(cb.Width * rs.s);
                }

                line.boxes.Add(cb);
            }

            if (newline)
            {
                rs.maxBaseline = fontInfo.Ascent;
                rs.maxHeight   = fontInfo.LineHeight;
            }

            rs.CacheBoxesReset();
        }
예제 #4
0
        internal void UpdateText(RelayoutSession rs)
        {
            this.lines.Clear();

            this.lastLine = null;

            if (this.Runs != null && this.Runs.Count > 0 && rs.bounds.Width > 0)
            {
                rs.ParagraphReset();

                var line = new Line(rs.currentLoc.Y);
                //line.Top = rs.currentLoc.Y;

                Run         prevRun = null, nextRun = null;
                BoxFontInfo curFontInfo = null;

                for (int ri = 0; ri < this.Runs.Count; ri++)
                {
                    var r = this.Runs[ri];

                    if (curFontInfo != r.FontInfo)
                    {
                        curFontInfo = r.FontInfo;

                        if (rs.maxBaseline < curFontInfo.Ascent)
                        {
                            rs.maxBaseline = curFontInfo.Ascent;
                        }
                        if (rs.maxHeight < curFontInfo.LineHeight)
                        {
                            rs.maxHeight = curFontInfo.LineHeight;
                        }
                    }

                    //prevRun = ri > 0 ? p.Runs[ri - 1] : null;
                    nextRun = ri < this.Runs.Count - 1 ? this.Runs[ri + 1] : null;

                    if (!string.IsNullOrEmpty(r.Text))
                    {
                        for (int i = 0; i < r.Text.Length; i++)
                        {
                            char c = r.Text[i];                            //.ToString();

#if WINFORM || ANDROID
                            var b = new Box(r, c.ToString(), curFontInfo, r.TextSizes[i], r.FontInfo.LineHeight);
#elif WPF
                            var b = new Box(r, c.ToString(), curFontInfo, r.GlyphIndexes[i], r.TextSizes[i]);
#endif // WPF

                            rs.AddCachedBox(b);

                            if (CJKHelper.IsBreakable(this, prevRun, nextRun, r, i))
                            {
                                this.CommitWord(ref line, rs, ref curFontInfo);
                            }
                        }
                    }

                    prevRun = r;
                }

                if (rs.cacheBoxesWidth > 0)
                {
                    this.CommitWord(ref line, rs, ref curFontInfo);
                }

                if (line.boxes.Count > 0)
                {
                    this.CommitLine(rs, line);
                }
            }
        }