Ejemplo n.º 1
0
        // return:
        //      -1   无需特殊处理
        //      其他  需要切断的位置
        static int DetectLineBreak(string strCurrentChar,
            PrintLine line)
        {
            // 如果是西文分隔符号
            if (SepChars.IndexOf(strCurrentChar) != -1)
                return -1;

            // 如果是中文字符
            if (StringUtil.IsHanzi(strCurrentChar[0]) == true)
                return -1;

            for (int i = line.Boxes.Count - 1; i >= 0; i--)
            {
                Box box = line.Boxes[i];
                if (SepChars.IndexOf(box.Text) != -1)
                {
                    if (i == line.Boxes.Count - 1)
                        return -1;
                    return i + 1;
                }
                if (StringUtil.IsHanzi(box.Text[0]) == true)
                {
                    if (i == line.Boxes.Count - 1)
                        return -1;
                    return i + 1;
                }
            }

            return -1;  // 如果整个line都是无法切割,就干脆放弃按词折行
        }
Ejemplo n.º 2
0
        // 获得一个行的最右端位置
        static float GetLineWidth(PrintLine line)
        {
            float x = 0;
            for (int i = 0; i < line.Boxes.Count; i++)
            {
                Box box = line.Boxes[i];
                x += box.LeftBlank + box.Width;
            }

            return x;
        }
Ejemplo n.º 3
0
        // 将一个字符串切割为Line数组
        // parameters:
        //      strTextParam    ==null 表示触发<p>前面的初始化换行
        //                      == "\r\n" 执行<br/>动作
        int BuildLines(Graphics g,
            RectParam rect_def,
            string strTextParam,
            Font font,
            Color color,
            ParagraphFormat p_format,
            ref List<PrintLine> lines,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            float fLineHeight = 0;
            string strFontString = GetFontString(font);
            string strFontColor = GetColorString(color);

            // 表示建立一个空的<p>元素显示位置
            if (strTextParam == null)
            {
                SizeF size = g.MeasureString("1", font);
                fLineHeight = size.Height;

                float emheight = font.FontFamily.GetEmHeight(FontStyle.Regular);
                float ascent = font.FontFamily.GetCellAscent(FontStyle.Regular);

                PrintLine current_line = null;

                current_line = new PrintLine();
                current_line.HorzAlign = GetHorzAlign(p_format.Align);
                current_line.Height = fLineHeight;
                current_line.Width = rect_def.Width - rect_def.Padding.Horizontal;
                current_line.FontDef = strFontString;
                current_line.ColorDef = strFontColor;
                current_line.BaseRatio = ascent / emheight;
                lines.Add(current_line);
                current_line.Indent = p_format.Indent;

                return 0;
            }

            // 回车换行
            if (strTextParam == "\r\n")
            {
                SizeF size = g.MeasureString("1", font);
                fLineHeight = size.Height;

                float emheight = font.FontFamily.GetEmHeight(FontStyle.Regular);
                float ascent = font.FontFamily.GetCellAscent(FontStyle.Regular);

                PrintLine current_line = null;

                // 另起一行
                current_line = new PrintLine();
                current_line.HorzAlign = GetHorzAlign(p_format.Align);
                current_line.Height = fLineHeight;
                current_line.Width = rect_def.Width - rect_def.Padding.Horizontal;
                current_line.FontDef = strFontString;
                current_line.ColorDef = strFontColor;
                current_line.BaseRatio = ascent / emheight;
                lines.Add(current_line);
                current_line.Indent = p_format.Indent;

                return 0;
            }


            for (int j=0; ;j++ )
            {
                if (String.IsNullOrEmpty(strTextParam) == true)
                    break;

                float emheight = font.FontFamily.GetEmHeight(FontStyle.Regular);
                float ascent = font.FontFamily.GetCellAscent(FontStyle.Regular);

                int nLen = Math.Min(30, strTextParam.Length);
                string strText = strTextParam.Substring(0, nLen);
                strTextParam = strTextParam.Remove(0, nLen);

                CharacterRange[] ranges = new CharacterRange[strText.Length];
                for (int i = 0; i < strText.Length; i++)
                {
                    ranges[i] = new CharacterRange(i, 1);
                }

                StringFormat format = new StringFormat();
                format.FormatFlags = StringFormatFlags.NoClip ;
                format.SetMeasurableCharacterRanges(ranges);


                Region[] regions = new Region[strText.Length];

                {
                    SizeF size = g.MeasureString(strText, font);
                    fLineHeight = size.Height;
                    RectangleF layout = new RectangleF(0, 0, size.Width, size.Height);
                    regions = g.MeasureCharacterRanges(
                        strText,
                        font,
                        layout,
                        format);
                }

                // 切割为若干行
                {
                    float x = 0;
                    PrintLine current_line = null;
                    if (lines.Count == 0)
                    {
                        current_line = new PrintLine();
                        current_line.HorzAlign = GetHorzAlign(p_format.Align);
                        current_line.Height = fLineHeight;
                        current_line.Width = rect_def.Width - rect_def.Padding.Horizontal;
                        current_line.FontDef = strFontString;
                        current_line.ColorDef = strFontColor;
                        current_line.BaseRatio = ascent / emheight;
                        lines.Add(current_line);
                        x = p_format.Indent;
                        current_line.Indent = p_format.Indent;

                    }
                    else
                    {
                        current_line = lines[lines.Count - 1];
                        x = GetLineWidth(current_line) + current_line.Indent;
                    }

                    for (int i = 0; i < regions.Length; i++)
                    {
                        string strCurrentChar = strText.Substring(i, 1);

                        Region region = regions[i];
                        RectangleF rect = region.GetBounds(g);
                        if (x + rect.Width > rect_def.Width - rect_def.Padding.Horizontal)
                        {
                            if (p_format.LineBreak == "word")
                            {
                                // return:
                                //      -1   无需特殊处理
                                //      其他  需要切断的位置
                                nRet = DetectLineBreak(strCurrentChar,
                                    current_line);
                            }
                            else
                                nRet = -1;

                            if (nRet != -1)
                            {
                                PrintLine prev_line = current_line;

                                // 另起一行
                                current_line = new PrintLine();
                                current_line.HorzAlign = GetHorzAlign(p_format.Align);
                                current_line.Width = rect_def.Width - rect_def.Padding.Horizontal;
                                current_line.BaseRatio = prev_line.BaseRatio;
                                lines.Add(current_line);
                                x = 0;

                                int nStart = nRet;

                                // 准备字体、颜色字符串
                                string strTempFontString = prev_line.FontDef;
                                string strTempColorString = prev_line.ColorDef;
                                for (int k = 0; k <= nStart; k++)
                                {
                                    Box box = prev_line.Boxes[k];
                                    if (string.IsNullOrEmpty(box.FontDef) == false)
                                        strTempFontString = box.FontDef;
                                    if (string.IsNullOrEmpty(box.ColorDef) == false)
                                        strTempColorString = box.ColorDef;
                                }

                                current_line.FontDef = strTempFontString;
                                current_line.ColorDef = strTempColorString;

                                // 切断,同时获得行高度
                                float fTempLineHeight = 0;
                                int nCount = prev_line.Boxes.Count;
                                for (int k = nStart; k < nCount; k++)
                                {
                                    Box box = prev_line.Boxes[nStart];
                                    current_line.Boxes.Add(box);
                                    prev_line.Boxes.RemoveAt(nStart);
                                    if (fTempLineHeight < box.Height)
                                        fTempLineHeight = box.Height;
                                }

                                current_line.Height = fTempLineHeight;
                            }
                            else
                            {
                                // 另起一行
                                current_line = new PrintLine();
                                current_line.HorzAlign = GetHorzAlign(p_format.Align);
                                current_line.Height = fLineHeight;
                                current_line.Width = rect_def.Width - rect_def.Padding.Horizontal;
                                current_line.FontDef = strFontString;
                                current_line.ColorDef = strFontColor;
                                current_line.BaseRatio = ascent / emheight;
                                lines.Add(current_line);
                                x = 0;

                            }
                        }
                        else
                        {
                        }


                        if (current_line.Boxes.Count == 0
                            && lines.Count > 1
                            && strCurrentChar == " ")
                        {
                            // 忽略第二行以后最左端的空格
                        }
                        else
                        {
                            Box box = new Box();
                            box.Text = strCurrentChar;
                            box.Width = rect.Width;
                            box.Height = rect.Height;
                            box.Base = fLineHeight * ascent / emheight;
                            if (i == 0 && j == 0)
                            {
                                box.FontDef = strFontString;
                                box.ColorDef = strFontColor;
                            }
                            if (current_line.Height < fLineHeight)
                            {
                                current_line.Height = fLineHeight;
                            }
                            current_line.Boxes.Add(box);

                            x += rect.Width;
                        }

                    }
                }
            }

            return 0;
        }