Ejemplo n.º 1
0
        // 处理一个矩形区域
        int DoRect(
            Graphics g,
            XmlNode nodeContainer,
            RectParam rect_def,
            bool bRemainPage,
            Hashtable macro_table,
            RectGroup rect_group,
            ref List<Page> pages,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            Padding padding = new Padding(0, 0, 0, 0);
            string strPadding = DomUtil.GetAttr(nodeContainer,
                "padding");
            if (String.IsNullOrEmpty(strPadding) == false)
            {
                nRet = GetPadding(strPadding,
                out padding,
                out strError);
                if (nRet == -1)
                {
                    strError = "元素<" + nodeContainer.Name + ">中padding属性值 '" + strPadding + "' 格式错误: " + strError;
                    return -1;
                }
            }

            rect_def.Padding = padding;


            List<PrintLine> lines = new List<PrintLine>();

            // 将一个容器元素下级的全部内容切割为Line数组
            nRet = Process(g,
                rect_def,
                nodeContainer,
                macro_table,
                rect_group,
        ref lines,
        out strError);
            if (nRet == -1)
                return -1;

            SetLastLine(lines);

            // 组装到Page中
            int iPage = 0;
            Page current_page = null;
            if (pages.Count > iPage)
                current_page = pages[iPage];
            else
            {
                current_page = new Page();
                pages.Add(current_page);
            }
            float current_height = 0;
            for (int i = 0; i < lines.Count; i++)
            {
                PrintLine line = lines[i];

                if (current_height + line.Height > rect_def.Height - rect_def.Padding.Vertical
                    && current_page.Lines.Count > 0    // 至少有一个行
                    && bRemainPage == false)
                {
                    // 新增一页
                    current_height = 0;
                    iPage++;
                    if (pages.Count > iPage)
                        current_page = pages[iPage];
                    else
                    {
                        current_page = new Page();
                        pages.Add(current_page);
                    }

                }

                // 
                line.X += rect_def.X + rect_def.Padding.Left;
                line.Y += rect_def.Y + rect_def.Padding.Top + current_height;
                current_page.Lines.Add(line);

                current_height += line.Height;
            }

            return iPage;
        }
Ejemplo n.º 2
0
        // parameters:
        //      state  ParagraphFirst 是否为首次处理一个<p>
        int Process(
            Graphics g,
            RectParam rect_def,
            XmlNode node,
            Hashtable macro_table,
            RectGroup rect_group,
            ref List<PrintLine> lines,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            if (node.NodeType == XmlNodeType.Element
                && node.Name == "br")
            {
                SetLastLine(lines);

                Color color;
                Font font = GetNodeFont(node, out color);

                ParagraphFormat format = GetNodeParagraphFormat(node);

                try
                {
                    nRet = BuildLines(g,
            rect_def,
            "\r\n",
            font,
            color,
            format,
            ref lines,
            out strError);
                    if (nRet == -1)
                        return -1;
                }
                finally
                {
                    font.Dispose();
                }

                return 0;
            }

            int nStartLines = lines.Count;
            int nLinesLimit = -1;
            ParagraphGroup p_group = null;

            // <p>的开头,触发一下换行
            if (node.NodeType == XmlNodeType.Element
                && node.Name == "p")
            {
                SetLastLine(lines);

                Color color;
                Font font = GetNodeFont(node, out color);

                ParagraphFormat format = GetNodeParagraphFormat(node);
                nLinesLimit = (int)format.MaxLines;

                p_group = new ParagraphGroup();
                p_group.Format = format;
                rect_group.Paragraphs.Add(p_group);

                try
                {

                    nRet = BuildLines(g,
            rect_def,
            null,
            font,
            color,
            format,
            ref lines,
            out strError);
                    if (nRet == -1)
                        return -1;


                }
                finally
                {
                    font.Dispose();
                }
            }

            for (int i = 0; i < node.ChildNodes.Count; i++)
            {
                XmlNode child = node.ChildNodes[i];

                if (child.NodeType == XmlNodeType.Text)
                {
                    string strText = child.Value;
                    strText = strText.Replace("\n", "\r");
                    strText = strText.Replace("\r", "");

                    if (macro_table != null)
                    {
                        strText = StringUtil.MacroString(macro_table,
        strText);
                    }

                    Color color;
                    Font font = GetNodeFont(node, out color);

                    ParagraphFormat format = GetNodeParagraphFormat(node);

                    try
                    {
                        nRet = BuildLines(g,
                rect_def,
                strText,
                font,
                color,
                format,
                ref lines,
                out strError);
                        if (nRet == -1)
                            return -1;
                    }
                    finally
                    {
                        font.Dispose();
                    }
                }

                if (child.NodeType == XmlNodeType.Element)
                {
                    int x_delta = 0;
                    int y_delta = 0;
                    RectParam current_rect_def = rect_def;
                    if (child.Name == "p")
                    {
                        // 2012/4/23
                        // 让<p>的padding属性起作用
                        ParagraphFormat format = GetNodeParagraphFormat(child);
                        current_rect_def = new RectParam(rect_def);
                        current_rect_def.Padding = AddPadding(current_rect_def.Padding, format.Padding);
                        x_delta = format.Padding.Left;
                        y_delta = format.Padding.Top;
                    }

                    int nStartLine = 0;
                    if (lines != null)
                        nStartLine = lines.Count;

                    nRet = Process(
                        g,
                        current_rect_def,
                        child,
                        macro_table,
                        rect_group,
                        ref lines,
                        out strError);
                    if (nRet == -1)
                        return -1;

                    // 对新增的行进行平移
                    if (x_delta != 0 || y_delta != 0)
                    {
                        for (int j = nStartLine; j < lines.Count; j++)
                        {
                            PrintLine line = lines[j];

                            // 
                            line.X += x_delta;
                            line.Y += y_delta;
                        }
                    }
                }
            }

            // 删除多余的行
            if (nLinesLimit != -1)
            {
                // TODO 如果发生切断,是不是最后要加... ?
                while (lines.Count > nStartLines + nLinesLimit)
                {
                    lines.RemoveAt(lines.Count - 1);
                }
            }

            if (p_group != null)
            {
                for (int i = nStartLines; i < lines.Count; i++)
                {
                    p_group.Lines.Add(lines[i]);
                }
            }

            return 0;
        }
Ejemplo n.º 3
0
        // parameters:
        //      height  分页以前的单页允许高度
        //      bIsHeaderFooter 是否保持不增加page
        int DoColumns(
            Graphics g,
            XmlNode nodeDocument,
            float x,
            float y,
            float width,
            float height,
            bool bIsHeaderFooter,
            Hashtable macro_table,
            string strHeaderCondition,
            ref List<Page> pages,
            out string strError)
        {
            strError = "";

            List<RectParam> rects = new List<RectParam>();

            // 列出根下面的<Column>元素
            XmlNodeList nodes = nodeDocument.SelectNodes("column");
            for (int i = 0; i < nodes.Count; i++)
            {
                XmlNode node = nodes[i];



                // 获得矩形参数
                RectParam rect = new RectParam();
                rect.WidthString = DomUtil.GetAttr(node, "width");
                rects.Add(rect);

            }

            // 分配宽度。固定宽度剩下以后的,就是auto的平分
            float rest = width;    // 剩下的宽度
            // 1) 处理数字宽度
            int nAutoCount = 0;
            for (int i = 0; i < rects.Count; i++)
            {
                RectParam rect = rects[i];
                string strWidth = rect.WidthString;
                if (StringUtil.IsPureNumber(strWidth) == true)
                {
                    rect.Width = (float)Convert.ToDouble(strWidth);
                    rest -= rect.Width;
                }
                else
                {
                    if (string.Compare(strWidth, "auto", true) != 0)
                    {
                        strError = "<column>元素的width属性值 '"+strWidth+"' 格式错误";
                        return -1;
                    }
                    rect.Width = -1;
                    nAutoCount++;
                }
            }

            // 2) 处理auto宽度
            if (nAutoCount > 0)
            {
                float nAverWidth = rest / nAutoCount;
                if (nAverWidth < 0)
                    nAverWidth = 0;
                for (int i = 0; i < rects.Count; i++)
                {
                    RectParam rect = rects[i];
                    if (rect.Width == -1)
                        rect.Width = nAverWidth;
                }
            }

            // 3)填充 X Y Height
            float start_x = x;
            for (int i = 0; i < rects.Count; i++)
            {
                RectParam rect = rects[i];
                rect.X = start_x;
                start_x += rect.Width;

                rect.Y = y;
                rect.Height = height;   // 一页内最大高度
            }

            List<RectGroup> rect_groups = new List<RectGroup>();

            for (int i = 0; i < nodes.Count; i++)
            {
                XmlNode node = nodes[i];

                if (bIsHeaderFooter == true)
                {
                    string strStyle = DomUtil.GetAttr(node, "style");
                    if (StringUtil.IsInList("hidewhenonepage", strStyle) == true
    && StringUtil.IsInList("onlyonepage", strHeaderCondition) == true)
                        continue;
                    if (StringUtil.IsInList("hidewhenfirstpage", strStyle) == true
&& StringUtil.IsInList("firstpage", strHeaderCondition) == true)
                        continue;
                    if (StringUtil.IsInList("hidewhentailpage", strStyle) == true
&& StringUtil.IsInList("tailpage", strHeaderCondition) == true)
                        continue;
                }

                // 获得矩形参数
                RectParam rect = rects[i];

                RectGroup rect_group = new RectGroup();
                rect_groups.Add(rect_group);

                int nRet = DoRect(
                    g,
                    node,
                    rect,
                    bIsHeaderFooter,
                    macro_table,
                    rect_group,
                    ref pages,
                    out strError);
                if (nRet == -1)
                    return -1;
            }


            if (bIsHeaderFooter == false)
            {
                // 处理valign=bottom的<p>
                for (int i = 0; i < nodes.Count; i++)
                {
                    XmlNode node = nodes[i];

                    // 获得矩形参数
                    RectParam rect = rects[i];

                    RectGroup rect_group = rect_groups[i];
                    for (int j = rect_group.Paragraphs.Count - 1; j >= 0; j--)
                    {
                        ParagraphGroup p_group = rect_group.Paragraphs[j];
                        if (p_group.Format.VertAlign == "bottom")
                        {
                            ResetLines(pages,
    rect,
    p_group.Lines);

                        }
                        else
                            break;  // 只要中间不连续,就中断
                    }
                }
            }

            return 0;
        }