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(); }
private void CommitLine(RelayoutSession rs, Line line) { var angle = this.rt.RotationAngle; #region Last Line Spacing // if there is last line, plus the line spacing height if (lastLine != null) { RGFloat lineSpacing = lastLine.Height * (this.LineHeight - 1); if (angle == 0) { rs.startLoc.Y += lineSpacing; //line.leftTop.Y += lineSpacing; } else { foreach (var box in line.boxes) { var a = (lineSpacing) * rs.s; var b = (lineSpacing) * rs.c / Math.Tan(rs.d); box.leftTop.X -= (float)(a + b); } } } #endregion // Last Line Spacing this.lines.Add(line); #region Horizontal Relayout Boxes var lineWidth = line.Width; RGFloat horAlignOffset = 0; var halign = this.HorizontalAlign; if (halign == ReoGridHorAlign.General) { halign = this.rt.DefaultHorizontalAlignment; } switch (halign) { default: case ReoGridHorAlign.Left: horAlignOffset = 0; break; case ReoGridHorAlign.Center: horAlignOffset = (rs.bounds.Width - lineWidth) / 2 - 3; break; case ReoGridHorAlign.Right: horAlignOffset = (rs.bounds.Width - lineWidth) - 4; break; } foreach (var b in line.boxes) { var r = b.Run; if (this.rt.RotationAngle == 0) { if ((r.FontStyles & FontStyles.Superscrit) == FontStyles.Superscrit) { b.leftTop.Y = line.Top - b.FontInfo.LineHeight / 2; } else if ((r.FontStyles & FontStyles.Subscript) == FontStyles.Subscript) { b.leftTop.Y = line.Top + line.Height - b.FontInfo.LineHeight / 2; } else { b.leftTop.Y = line.Top - b.FontInfo.LineHeight + line.Ascent; } } else { // TODO //b.leftTop.X = line.leftTop.Y - b.FontInfo.LineHeight + line.Ascent; } b.leftTop.X += horAlignOffset; } #endregion // Horizontal Relayout Boxes var lineHeight = line.Height; if (angle == 0) { rs.startLoc.Y += lineHeight; if (rs.measuredSize.Width < line.Width) { rs.measuredSize.Width = line.Width; } rs.measuredSize.Height = rs.startLoc.Y; } else { var a = (lineHeight) * rs.s; var b = (lineHeight) * rs.c / Math.Tan(rs.d); rs.startLoc.X -= (float)(a + b); rs.measuredSize.Width = 200; rs.measuredSize.Height = 200; } rs.currentLoc = rs.startLoc; lastLine = line; }
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); } } }