Esempio n. 1
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;
        }
Esempio n. 2
0
        // 获得一个XML元素位置的段落格式
        // 从下级元素向上级元素寻找
        ParagraphFormat GetNodeParagraphFormat(XmlNode node)
        {
            Debug.Assert(node.NodeType == XmlNodeType.Element, "node.NodeType == XmlNodeType.Element 不满足");
            string strIndent = "";
            string strLineBreak = "";
            string strAlign = "";
            string strMaxLines = "";
            string strVertAlign = "";

            // <p>本身的padding属性
            Padding padding = new Padding(0, 0, 0, 0);
            string strPadding = DomUtil.GetAttr(node,
    "padding");
            if (String.IsNullOrEmpty(strPadding) == false)
            {
                string strError = "";
                int nRet = GetPadding(strPadding,
                out padding,
                out strError);
                if (nRet == -1)
                {
                    strError = "元素<" + node.Name + ">中padding属性值 '" + strPadding + "' 格式错误: " + strError;
                    throw new Exception(strError);
                }
            }


            while (node != null)
            {
                if (node.Name == "p")
                {
                    if (String.IsNullOrEmpty(strIndent) == true)
                        strIndent = DomUtil.GetAttr(node, "indent");
                    if (String.IsNullOrEmpty(strLineBreak) == true)
                        strLineBreak = DomUtil.GetAttr(node, "lineBreak");
                    if (String.IsNullOrEmpty(strAlign) == true)
                        strAlign = DomUtil.GetAttr(node, "align");
                    if (String.IsNullOrEmpty(strMaxLines) == true)
                        strMaxLines = DomUtil.GetAttr(node, "maxLines");
                    if (String.IsNullOrEmpty(strVertAlign) == true)
                        strVertAlign = DomUtil.GetAttr(node, "valign");
                }

                node = node.ParentNode;
            }

            if (String.IsNullOrEmpty(strIndent) == true)
                strIndent = this.m_pagesetting.Indent.ToString();

            ParagraphFormat format = new ParagraphFormat();
            if (string.IsNullOrEmpty(strIndent) == false)
            {
                if (float.TryParse(strIndent, out format.Indent) == false)
                {
                    string strError = "indent属性值 '" + strIndent + "' 格式不正确";
                    throw new Exception(strError);
                }
            }
            else
                format.Indent = this.m_pagesetting.Indent;

            if (String.IsNullOrEmpty(strLineBreak) == false)
                format.LineBreak = strLineBreak;
            else
                format.LineBreak = this.m_pagesetting.LineBreak;

            if (String.IsNullOrEmpty(strAlign) == false)
                format.Align = strAlign;
            else
                format.Align = this.m_pagesetting.Align;

            if (String.IsNullOrEmpty(strVertAlign) == false)
                format.VertAlign = strVertAlign;
            else
                format.VertAlign = this.m_pagesetting.VertAlign;

            if (String.IsNullOrEmpty(strMaxLines) == true)
                format.MaxLines = -1;
            else
            {
                try
                {
                    format.MaxLines = Convert.ToInt64(strMaxLines);
                }
                catch (Exception /*ex*/)
                {
                    string strError = "maxLines属性值 '" + strMaxLines + "' 格式不正确";
                    throw new Exception(strError);
                }
            }

            format.Padding = padding;

            return format;
        }