Esempio n. 1
0
        public int NewDefaultParaStyle()
        {
            HCParaStyle vParaStyle = new HCParaStyle();

            FParaStyles.Add(vParaStyle);
            return(FParaStyles.Count - 1);
        }
Esempio n. 2
0
        public override int GetMatchParaNo(HCStyle AStyle, int ACurParaNo)
        {
            int Result = HCStyle.Null;

            if (AStyle.ParaStyles[ACurParaNo].BackColor == FBackColor)
            {
                Result = ACurParaNo;
                return(Result);
            }

            HCParaStyle vParaStyle = new HCParaStyle();

            try
            {
                vParaStyle.AssignEx(AStyle.ParaStyles[ACurParaNo]);
                vParaStyle.BackColor = FBackColor;
                Result = AStyle.GetParaNo(vParaStyle, true);  // 新段样式
            }
            finally
            {
                vParaStyle.Dispose();
            }

            return(Result);
        }
Esempio n. 3
0
 public void AssignEx(HCParaStyle ASource)
 {
     this.FLineSpaceMode = ASource.LineSpaceMode;
     this.FFristIndent   = ASource.FristIndent;
     this.FLeftIndent    = ASource.LeftIndent;
     this.FBackColor     = ASource.BackColor;
     this.FAlignHorz     = ASource.AlignHorz;
     this.FAlignVert     = ASource.AlignVert;
 }
Esempio n. 4
0
 public bool EqualsEx(HCParaStyle ASource)
 {
     return((this.FLineSpaceMode == ASource.LineSpaceMode) &&
            (this.FFristIndent == ASource.FristIndent) &&
            (this.LeftIndent == ASource.LeftIndent) &&
            (this.FBackColor == ASource.BackColor) &&
            (this.FAlignHorz == ASource.AlignHorz) &&
            (this.FAlignVert == ASource.AlignVert));
 }
Esempio n. 5
0
        protected void LoadItemFromStreamAlone(Stream aStream, ref HCCustomItem aItem)
        {
            string vFileExt     = "";
            ushort vFileVersion = 0;
            byte   vLan         = 0;

            aStream.Position = 0;
            HC._LoadFileFormatAndVersion(aStream, ref vFileExt, ref vFileVersion, ref vLan);  // 文件格式和版本
            if ((vFileExt != HC.HC_EXT) && (vFileExt != "cff."))
            {
                throw new Exception("加载失败,不是" + HC.HC_EXT + "文件!");
            }

            int vStyleNo = HCStyle.Null;

            byte[] vBuffer = BitConverter.GetBytes(vStyleNo);
            aStream.Read(vBuffer, 0, vBuffer.Length);
            vStyleNo = BitConverter.ToInt32(vBuffer, 0);

            if (aItem == null)
            {
                aItem = CreateItemByStyle(vStyleNo);
            }

            aItem.LoadFromStream(aStream, null, vFileVersion);

            if (vStyleNo > HCStyle.Null)
            {
                HCTextStyle vTextStyle = new HCTextStyle();
                try
                {
                    vTextStyle.LoadFromStream(aStream, vFileVersion);
                    vStyleNo      = Style.GetStyleNo(vTextStyle, true);
                    aItem.StyleNo = vStyleNo;
                }
                finally
                {
                    vTextStyle.Dispose();
                }
            }

            int         vParaNo    = -1;
            HCParaStyle vParaStyle = new HCParaStyle();

            try
            {
                vParaStyle.LoadFromStream(aStream, vFileVersion);
                vParaNo = Style.GetParaNo(vParaStyle, true);
            }
            finally
            {
                vParaStyle.Dispose();
            }

            aItem.ParaNo = vParaNo;
        }
Esempio n. 6
0
 public void AssignEx(HCParaStyle aSource)
 {
     FLineSpaceMode = aSource.LineSpaceMode;
     FirstIndent    = aSource.FirstIndent;
     LeftIndent     = aSource.LeftIndent;
     RightIndent    = aSource.RightIndent;
     FBackColor     = aSource.BackColor;
     FAlignHorz     = aSource.AlignHorz;
     FAlignVert     = aSource.AlignVert;
 }
Esempio n. 7
0
 public bool EqualsEx(HCParaStyle aSource)
 {
     return((FLineSpaceMode == aSource.LineSpaceMode) &&
            (FFirstIndent == aSource.FirstIndent) &&
            (FLeftIndent == aSource.LeftIndent) &&
            (FRightIndent == aSource.RightIndent) &&
            (FBackColor == aSource.BackColor) &&
            (FAlignHorz == aSource.AlignHorz) &&
            (FAlignVert == aSource.AlignVert));
 }
Esempio n. 8
0
        private void FormatRange(int aStartDrawItemNo, int aLastItemNo)
        {
            int         vPrioDrawItemNo = -1, vStartItemNo = -1, vStartOffset = -1;
            HCParaStyle vParaStyle = null;
            POINT       vPos       = new POINT();

            FFormatStartDrawItemNo = aStartDrawItemNo;

            // 获取起始DrawItem的上一个序号及格式化开始位置
            if (aStartDrawItemNo > 0)
            {
                vPrioDrawItemNo = aStartDrawItemNo - 1;  // 上一个最后的DrawItem
                vStartItemNo    = DrawItems[aStartDrawItemNo].ItemNo;
                vStartOffset    = DrawItems[aStartDrawItemNo].CharOffs;
                vParaStyle      = Style.ParaStyles[Items[vStartItemNo].ParaNo];
                if (DrawItems[aStartDrawItemNo].LineFirst)
                {
                    vPos.X = vParaStyle.LeftIndentPix;
                    vPos.Y = DrawItems[vPrioDrawItemNo].Rect.Bottom;
                }
                else
                {
                    vPos.X = DrawItems[vPrioDrawItemNo].Rect.Right;
                    vPos.Y = DrawItems[vPrioDrawItemNo].Rect.Top;
                }
            }
            else  // 是第一个
            {
                vPrioDrawItemNo = -1;
                vStartItemNo    = 0;
                vStartOffset    = 1;
                vParaStyle      = Style.ParaStyles[Items[vStartItemNo].ParaNo];
                vPos.X          = vParaStyle.LeftIndentPix;
                vPos.Y          = 0;
            }

            Style.ApplyTempStyle(HCStyle.Null);
            FormatItemToDrawItems(vStartItemNo, vStartOffset, vParaStyle.LeftIndentPix,
                                  FWidth - vParaStyle.RightIndentPix, FWidth, ref vPos, ref vPrioDrawItemNo);

            for (int i = vStartItemNo + 1; i <= aLastItemNo; i++)  // 格式
            {
                if (Items[i].ParaFirst)
                {
                    vParaStyle = Style.ParaStyles[Items[i].ParaNo];
                    vPos.X     = vParaStyle.LeftIndentPix;
                }

                FormatItemToDrawItems(i, 1, vParaStyle.LeftIndentPix,
                                      FWidth - vParaStyle.RightIndentPix, FWidth, ref vPos, ref vPrioDrawItemNo);
            }

            DrawItems.DeleteFormatMark();
        }
Esempio n. 9
0
        public virtual int GetMatchParaNo(HCStyle aStyle, int aCurParaNo)
        {
            if (DoMatchCurPara(aStyle.ParaStyles[aCurParaNo]))
            {
                return(aCurParaNo);
            }

            using (HCParaStyle vParaStyle = new HCParaStyle())
            {
                vParaStyle.AssignEx(aStyle.ParaStyles[aCurParaNo]);
                DoMatchNewPara(vParaStyle);
                return(aStyle.GetParaNo(vParaStyle, true));
            }
        }
Esempio n. 10
0
        protected override bool DoMatchCurPara(HCParaStyle aParaStyle)
        {
            bool vResult = FSpaceMode == aParaStyle.LineSpaceMode;

            if (vResult)
            {
                if (FSpaceMode == ParaLineSpaceMode.plsFix)
                {
                    return(FSpace == aParaStyle.LineSpace);
                }
                else
                if (FSpaceMode == ParaLineSpaceMode.plsMult)
                {
                    return(FSpace == aParaStyle.LineSpace);
                }
                else
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 11
0
        public int GetParaNo(HCParaStyle aParaStyle, bool aCreateIfNull)
        {
            int Result = -1;

            for (int i = 0; i <= FParaStyles.Count - 1; i++)
            {
                if (FParaStyles[i].EqualsEx(aParaStyle))
                {
                    Result = i;
                    return(Result);
                }
            }

            if (aCreateIfNull && (Result < 0))
            {
                HCParaStyle vParaStyle = new HCParaStyle();
                vParaStyle.AssignEx(aParaStyle);
                FParaStyles.Add(vParaStyle);
                Result = FParaStyles.Count - 1;
            }

            return(Result);
        }
Esempio n. 12
0
        private void DoFormatRectItemToDrawItem(HCCustomRectItem vRectItem, int aItemNo, int aFmtLeft, int aContentWidth, int aFmtRight, int aOffset,
                                                bool vParaFirst, HCParaStyle aParaStyle, ref POINT aPos, ref RECT vRect, ref bool vLineFirst, ref int aLastDrawItemNo, ref int vRemainderWidth)
        {
            vRectItem.FormatToDrawItem(this, aItemNo);
            int vWidth = aFmtRight - aPos.X;

            if ((vRectItem.Width > vWidth) && (!vLineFirst))  // 当前行剩余宽度放不下且不是行首
            {
                // 偏移到下一行
                FinishLine(aItemNo, aLastDrawItemNo, vWidth);
                aPos.X     = aFmtLeft;
                aPos.Y     = DrawItems[aLastDrawItemNo].Rect.Bottom;
                vLineFirst = true;  // 作为行首
            }

            // 当前行空余宽度能放下或放不下但已经是行首了
            vRect.Left   = aPos.X;
            vRect.Top    = aPos.Y;
            vRect.Right  = vRect.Left + vRectItem.Width;
            vRect.Bottom = vRect.Top + vRectItem.Height + Style.LineSpaceMin;
            NewDrawItem(aItemNo, aOffset, 1, vRect, vParaFirst, vLineFirst, ref aLastDrawItemNo);

            vRemainderWidth = aFmtRight - vRect.Right;  // 放入后的剩余量
        }
Esempio n. 13
0
 protected override bool DoMatchCurPara(HCParaStyle aParaStyle)
 {
     return(aParaStyle.BreakRough == FBreakRough);
 }
Esempio n. 14
0
        /// <summary> 转换指定Item指定Offs格式化为DItem </summary>
        /// <param name="AItemNo">指定的Item</param>
        /// <param name="AOffset">指定的格式化起始位置</param>
        /// <param name="AContentWidth">当前Data格式化宽度</param>
        /// <param name="APageContenBottom">当前页格式化底部位置</param>
        /// <param name="APos">起始位置</param>
        /// <param name="ALastDNo">起始DItemNo前一个值</param>
        /// <param name="vPageBoundary">数据页底部边界</param>
        private void FormatItemToDrawItems(int aItemNo, int aOffset, int aFmtLeft, int aFmtRight, int aContentWidth, ref POINT aPos, ref int aLastDrawItemNo)
        {
            if (!Items[aItemNo].Visible)
            {
                return;
            }

            bool             vParaFirst = false, vLineFirst = false;
            HCCustomRectItem vRectItem = null;
            string           vText     = "";
            RECT             vRect     = new RECT();

            int          vRemainderWidth = 0;
            HCCustomItem vItem           = Items[aItemNo];
            HCParaStyle  vParaStyle      = Style.ParaStyles[vItem.ParaNo];

            if (vItem.ParaFirst && (aOffset == 1))
            {
                vParaFirst = true;
                vLineFirst = true;
                aPos.X    += vParaStyle.FirstIndentPix;
            }
            else  // 非段第1个
            {
                vParaFirst = false;
                vLineFirst = (aPos.X == aFmtLeft) && (DrawItems[aLastDrawItemNo].Width != 0);
            }

            if (!vItem.Visible)  // 不显示的Item
            {
                vRect.Left   = aPos.X;
                vRect.Top    = aPos.Y;
                vRect.Right  = vRect.Left;
                vRect.Bottom = vRect.Top + 5;
                NewDrawItem(aItemNo, aOffset, vItem.Length, vRect, vParaFirst, vLineFirst, ref aLastDrawItemNo);
            }
            else
            if (vItem.StyleNo < HCStyle.Null)
            {
                vRectItem = vItem as HCCustomRectItem;
                DoFormatRectItemToDrawItem(vRectItem, aItemNo, aFmtLeft, aContentWidth, aFmtRight, aOffset,
                                           vParaFirst, ref aPos, ref vRect, ref vLineFirst, ref aLastDrawItemNo, ref vRemainderWidth);
            }
            else  // 文本
            {
                CalcItemFormatHeigh(vItem);
                vRemainderWidth = aFmtRight - aPos.X;

                if (aOffset != 1)
                {
                    vText = vItem.Text.Substring(aOffset - 1, vItem.Length - aOffset + 1);
                }
                else
                {
                    vText = vItem.Text;
                }

                if (vText == "")
                {
                    vRect.Left   = aPos.X;
                    vRect.Top    = aPos.Y;
                    vRect.Right  = vRect.Left;
                    vRect.Bottom = vRect.Top + FItemFormatHeight;  //DefaultCaretHeight;
                    vParaFirst   = true;
                    vLineFirst   = true;
                    NewDrawItem(aItemNo, aOffset, 0, vRect, vParaFirst, vLineFirst, ref aLastDrawItemNo);
                    vParaFirst = false;
                }
                else  // 非空Item
                {
                    int vItemLen = vText.Length;
                    if (vItemLen > 38347922)
                    {
                        throw new Exception(HC.HCS_EXCEPTION_STRINGLENGTHLIMIT);
                    }

                    int[] vCharWidths = new int[vItemLen];

                    int[] vCharWArr = null;
                    int   viLen     = vItemLen;
                    if (viLen > FormatTextCut)
                    {
                        vCharWArr = new int[FormatTextCut];
                    }

                    int  vIndex = 0, viBase = 0;
                    SIZE vSize = new SIZE();
                    while (viLen > FormatTextCut)
                    {
                        Style.TempCanvas.GetTextExtentExPoint(vText.Substring(vIndex, FormatTextCut), FormatTextCut, vCharWArr, ref vSize);  // 超过65535数组元素取不到值
                        for (int i = 0; i <= FormatTextCut - 1; i++)
                        {
                            vCharWidths[vIndex + i] = vCharWArr[i] + viBase;
                        }

                        viLen  -= FormatTextCut;
                        vIndex += FormatTextCut;
                        viBase  = vCharWidths[vIndex - 1];
                    }

                    vCharWArr = new int[viLen];
                    Style.TempCanvas.GetTextExtentExPoint(vText.Substring(vIndex, viLen), viLen, vCharWArr, ref vSize);  // 超过65535数组元素取不到值


                    for (int i = 0; i <= viLen - 1; i++)
                    {
                        vCharWidths[vIndex + i] = vCharWArr[i] + viBase;
                    }

                    //SetLength(vCharWArr, 0);
                    DoFormatTextItemToDrawItems(vItem, aOffset, vText, 1, aFmtRight - aPos.X, 0, aItemNo, vItemLen, aFmtLeft, aContentWidth, aFmtRight, vCharWidths,
                                                ref vParaFirst, ref vLineFirst, ref aPos, ref vRect, ref vRemainderWidth, ref aLastDrawItemNo);
                    //SetLength(vCharWidths, 0);
                }
            }

            // 计算下一个的位置
            if (aItemNo == Items.Count - 1)
            {
                FinishLine(aItemNo, aLastDrawItemNo, vRemainderWidth);
            }
            else  // 不是最后一个,则为下一个Item准备位置
            {
                if (Items[aItemNo + 1].ParaFirst)
                {
                    FinishLine(aItemNo, aLastDrawItemNo, vRemainderWidth);
                    // 偏移到下一行顶端,准备另起一行
                    aPos.X = 0;
                    aPos.Y = DrawItems[aLastDrawItemNo].Rect.Bottom;  // 不使用 vRect.Bottom 因为如果行中间有高的,会修正其bottom
                }
                else  // 下一个不是段起始
                {
                    aPos.X = vRect.Right;  // 下一个的起始坐标
                }
            }
        }
Esempio n. 15
0
 protected override bool DoMatchCurPara(HCParaStyle aParaStyle)
 {
     return(aParaStyle.RightIndent == FIndent);
 }
Esempio n. 16
0
 protected override void DoMatchNewPara(HCParaStyle aParaStyle)
 {
     aParaStyle.RightIndent = FIndent;
 }
Esempio n. 17
0
 protected override bool DoMatchCurPara(HCParaStyle aParaStyle)
 {
     return(aParaStyle.BackColor == FBackColor);
 }
Esempio n. 18
0
 protected override void DoMatchNewPara(HCParaStyle aParaStyle)
 {
     aParaStyle.BackColor = FBackColor;
 }
Esempio n. 19
0
 protected override bool DoMatchCurPara(HCParaStyle aParaStyle)
 {
     return(aParaStyle.LineSpaceMode == FSpaceMode);
 }
Esempio n. 20
0
 protected override void DoMatchNewPara(HCParaStyle aParaStyle)
 {
     aParaStyle.LineSpaceMode = FSpaceMode;
 }
Esempio n. 21
0
 protected override bool DoMatchCurPara(HCParaStyle aParaStyle)
 {
     return(aParaStyle.AlignVert == FAlign);
 }
Esempio n. 22
0
 protected override void DoMatchNewPara(HCParaStyle aParaStyle)
 {
     aParaStyle.AlignVert = FAlign;
 }
Esempio n. 23
0
 protected override void DoMatchNewPara(HCParaStyle aParaStyle)
 {
     aParaStyle.BreakRough = FBreakRough;
 }
Esempio n. 24
0
 protected abstract void DoMatchNewPara(HCParaStyle aParaStyle);
Esempio n. 25
0
 protected abstract bool DoMatchCurPara(HCParaStyle aParaStyle);
Esempio n. 26
0
        /// <summary> 从指定偏移和指定位置开始格式化Text </summary>
        /// <param name="aCharOffset">文本格式化的起始偏移</param>
        /// <param name="aPlaceWidth">呈放文本的宽度</param>
        /// <param name="aBasePos">vCharWidths中对应偏移的起始位置</param>
        private void DoFormatTextItemToDrawItems(HCCustomItem vItem, int aOffset, string vText, int aCharOffset, int aPlaceWidth, int aBasePos,
                                                 int aItemNo, int vItemLen, int aFmtLeft, int aContentWidth, int aFmtRight,
                                                 int[] vCharWidths, HCParaStyle aParaStyle, ref bool vParaFirst, ref bool vLineFirst, ref POINT aPos, ref RECT vRect,
                                                 ref int vRemainderWidth, ref int aLastDrawItemNo)
        {
            int viPlaceOffset,   // 能放下第几个字符
                viBreakOffset,   // 第几个字符放不下
                vFirstCharWidth; // 第一个字符的宽度
            bool vSqueeze = false;

            vLineFirst      = vParaFirst || ((aPos.X == aFmtLeft) && (DrawItems[aLastDrawItemNo].Width != 0));
            viBreakOffset   = 0;                                       // 换行位置,第几个字符放不下
            vFirstCharWidth = vCharWidths[aCharOffset - 1] - aBasePos; // 第一个字符的宽度

            if (aPlaceWidth < 0)
            {
                viBreakOffset = 1;
            }
            else
            {
                if (Style.FormatVersion == 2)
                {
                    vSqueeze = false;
                    for (int i = aCharOffset - 1; i <= vItemLen - 1; i++)
                    {
                        if (vCharWidths[i] - aBasePos > aPlaceWidth)
                        {
                            if (HC.PosCharHC(vText[i], HC.LineSqueezeChar) > 0)
                            {
                                if (vCharWidths[i] - aBasePos - aPlaceWidth > 3)  // (vCharWidths[i] - vCharWidths[i - 1]) / 2
                                {
                                    vSqueeze = true;
                                    continue;
                                }
                            }

                            viBreakOffset = i + 1;
                            break;
                        }
                    }
                }
                else
                {
                    for (int i = aCharOffset - 1; i <= vItemLen - 1; i++)
                    {
                        if (vCharWidths[i] - aBasePos > aPlaceWidth)
                        {
                            viBreakOffset = i + 1;
                            break;
                        }
                    }
                }
            }

            if (viBreakOffset < 1)  // 当前行剩余空间把vText全放置下了
            {
                vRect.Left   = aPos.X;
                vRect.Top    = aPos.Y;
                vRect.Right  = vRect.Left + vCharWidths[vItemLen - 1] - aBasePos; // 使用自定义测量的结果
                vRect.Bottom = vRect.Top + FItemFormatHeight;
                NewDrawItem(aItemNo, aOffset + aCharOffset - 1, vItemLen - aCharOffset + 1, vRect, vParaFirst, vLineFirst, ref aLastDrawItemNo);
                vParaFirst = false;

                vRemainderWidth = aFmtRight - vRect.Right;  // 放入最多后的剩余量
            }
            else
            if (viBreakOffset == 1)                         // 当前行剩余空间连第一个字符也放不下
            {
                if (vFirstCharWidth > aFmtRight - aFmtLeft) // Data的宽度不足一个字符
                {
                    vRect.Left   = aPos.X;
                    vRect.Top    = aPos.Y;
                    vRect.Right  = vRect.Left + vCharWidths[vItemLen - 1] - aBasePos; // 使用自定义测量的结果
                    vRect.Bottom = vRect.Top + FItemFormatHeight;
                    NewDrawItem(aItemNo, aOffset + aCharOffset - 1, 1, vRect, vParaFirst, vLineFirst, ref aLastDrawItemNo);
                    vParaFirst = false;

                    vRemainderWidth = aFmtRight - vRect.Right;  // 放入最多后的剩余量
                    FinishLine(aItemNo, aLastDrawItemNo, vRemainderWidth);

                    // 偏移到下一行顶端,准备另起一行
                    aPos.X = aFmtLeft;
                    aPos.Y = DrawItems[aLastDrawItemNo].Rect.Bottom;  // 不使用 vRect.Bottom 因为如果行中间有高的,会修正vRect.Bottom

                    if (aCharOffset < vItemLen)
                    {
                        DoFormatTextItemToDrawItems(vItem, aOffset, vText, aCharOffset + 1, aFmtRight - aPos.X, vCharWidths[aCharOffset - 1],
                                                    aItemNo, vItemLen, aFmtLeft, aContentWidth, aFmtRight, vCharWidths, aParaStyle,
                                                    ref vParaFirst, ref vLineFirst, ref aPos, ref vRect, ref vRemainderWidth, ref aLastDrawItemNo);
                    }
                }
                else  // Data的宽度足够一个字符
                if ((HC.PosCharHC(vText[aCharOffset - 1], HC.DontLineFirstChar) > 0) &&
                    (Items[aItemNo - 1].StyleNo > HCStyle.Null) &&
                    (DrawItems[aLastDrawItemNo].CharLen > 1))
                {
                    _FormatBreakTextDrawItem(aItemNo, aFmtLeft, aFmtRight, ref aLastDrawItemNo, ref aPos, ref vRect, ref vRemainderWidth, ref vParaFirst);      // 上一个重新分裂
                    CalcItemFormatHeigh(vItem);

                    DoFormatTextItemToDrawItems(vItem, aOffset, vText, aCharOffset, aFmtRight - aPos.X, aBasePos, aItemNo, vItemLen, aFmtLeft, aContentWidth,
                                                aFmtRight, vCharWidths, aParaStyle, ref vParaFirst, ref vLineFirst, ref aPos, ref vRect, ref vRemainderWidth, ref aLastDrawItemNo);
                }
                else      // 整体下移到下一行
                {
                    vRemainderWidth = aPlaceWidth;
                    FinishLine(aItemNo, aLastDrawItemNo, vRemainderWidth);
                    // 偏移到下一行开始计算
                    aPos.X = aFmtLeft;
                    aPos.Y = DrawItems[aLastDrawItemNo].Rect.Bottom;
                    DoFormatTextItemToDrawItems(vItem, aOffset, vText, aCharOffset, aFmtRight - aPos.X, aBasePos,
                                                aItemNo, vItemLen, aFmtLeft, aContentWidth, aFmtRight, vCharWidths, aParaStyle,
                                                ref vParaFirst, ref vLineFirst, ref aPos, ref vRect, ref vRemainderWidth, ref aLastDrawItemNo);
                }
            }
            else  // 当前行剩余宽度能放下当前Text的一部分
            {
                if (vFirstCharWidth > aFmtRight - aFmtLeft)  // Data的宽度不足一个字符
                {
                    viPlaceOffset = viBreakOffset;
                }
                else
                {
                    viPlaceOffset = viBreakOffset - 1;                                       // 第viBreakOffset个字符放不下,前一个能放下
                }
                FindLineBreak(vText, aParaStyle.BreakRough, aCharOffset, ref viPlaceOffset); // 判断从viPlaceOffset后打断是否合适

                if ((viPlaceOffset == 0) && (aPos.X > aFmtLeft))                             // 能放下的都不合适放到当前行且不是行首格式化,整体下移
                {
                    vRemainderWidth = aPlaceWidth;
                    FinishLine(aItemNo, aLastDrawItemNo, vRemainderWidth);
                    aPos.X = aFmtLeft;  // 偏移到下一行开始计算
                    aPos.Y = DrawItems[aLastDrawItemNo].Rect.Bottom;
                    DoFormatTextItemToDrawItems(vItem, aOffset, vText, aCharOffset, aFmtRight - aPos.X, aBasePos, aItemNo, vItemLen,
                                                aFmtLeft, aContentWidth, aFmtRight, vCharWidths, aParaStyle,
                                                ref vParaFirst, ref vLineFirst, ref aPos, ref vRect, ref vRemainderWidth, ref aLastDrawItemNo);
                }
                else  // 有适合放到当前行的内容
                {
                    if (viPlaceOffset < aCharOffset)  // 找不到截断位置,就在原位置截断(如整行文本都是逗号)
                    {
                        if (vFirstCharWidth > aFmtRight - aFmtLeft)  // Data的宽度不足一个字符
                        {
                            viPlaceOffset = viBreakOffset;
                        }
                        else
                        {
                            viPlaceOffset = viBreakOffset - 1;
                        }
                    }

                    vRect.Left   = aPos.X;
                    vRect.Top    = aPos.Y;
                    vRect.Right  = vRect.Left + vCharWidths[viPlaceOffset - 1] - aBasePos; // 使用自定义测量的结果
                    vRect.Bottom = vRect.Top + FItemFormatHeight;

                    NewDrawItem(aItemNo, aOffset + aCharOffset - 1, viPlaceOffset - aCharOffset + 1, vRect, vParaFirst, vLineFirst, ref aLastDrawItemNo);
                    vParaFirst = false;

                    if (vSqueeze)
                    {
                        vRemainderWidth = 0;
                    }
                    else
                    {
                        vRemainderWidth = aFmtRight - vRect.Right;  // 放入最多后的剩余量
                    }
                    FinishLine(aItemNo, aLastDrawItemNo, vRemainderWidth);

                    // 偏移到下一行顶端,准备另起一行
                    aPos.X = aFmtLeft;
                    aPos.Y = DrawItems[aLastDrawItemNo].Rect.Bottom;  // 不使用 vRect.Bottom 因为如果行中间有高的,会修正vRect.Bottom

                    if (viPlaceOffset < vItemLen)
                    {
                        DoFormatTextItemToDrawItems(vItem, aOffset, vText, viPlaceOffset + 1, aFmtRight - aPos.X, vCharWidths[viPlaceOffset - 1],
                                                    aItemNo, vItemLen, aFmtLeft, aContentWidth, aFmtRight, vCharWidths, aParaStyle,
                                                    ref vParaFirst, ref vLineFirst, ref aPos, ref vRect, ref vRemainderWidth, ref aLastDrawItemNo);
                    }
                }
            }
        }
Esempio n. 27
0
        /// <summary> 重整行 </summary>
        /// <param name="AEndDItemNo">行最后一个DItem</param>
        /// <param name="aRemWidth">行剩余宽度</param>
        private void FinishLine(int aItemNo, int aLineEndDItemNo, int aRemWidth)
        {
            int vLineBegDItemNo,  // 行第一个DItem
                vMaxBottom,
                viSplitW, vW,
                vLineSpaceCount,   // 当前行分几份
                vDItemSpaceCount,  // 当前DrawItem分几份
                vExtraW,
                viSplitMod,
                vDLen;

            // 根据行中最高的DrawItem处理其他DrawItem的高度
            vLineBegDItemNo = aLineEndDItemNo;
            for (int i = aLineEndDItemNo; i >= 0; i--)  // 得到行起始DItemNo
            {
                if (DrawItems[i].LineFirst)
                {
                    vLineBegDItemNo = i;
                    break;
                }
            }
            //Assert((vLineBegDItemNo >= 0), '断言失败:行起始DItemNo小于0!');
            // 找行DrawItem中最高的
            vMaxBottom = DrawItems[aLineEndDItemNo].Rect.Bottom;  // 先默认行最后一个DItem的Rect底位置最大
            for (int i = aLineEndDItemNo - 1; i >= vLineBegDItemNo; i--)
            {
                if (DrawItems[i].Rect.Bottom > vMaxBottom)
                {
                    vMaxBottom = DrawItems[i].Rect.Bottom;  // 记下最大的Rect底位置
                }
            }

            // 根据最高的处理行间距,并影响到同行DrawItem
            for (int i = aLineEndDItemNo; i >= vLineBegDItemNo; i--)
            {
                DrawItems[i].Rect.Bottom = vMaxBottom;
            }

            // 处理对齐方式,放在这里,是因为方便计算行起始和结束DItem,避免绘制时的运算
            HCParaStyle vParaStyle = Style.ParaStyles[Items[aItemNo].ParaNo];

            switch (vParaStyle.AlignHorz)  // 段内容水平对齐方式
            {
            case ParaAlignHorz.pahLeft:    // 默认
                break;

            case ParaAlignHorz.pahRight:
            {
                for (int i = aLineEndDItemNo; i >= vLineBegDItemNo; i--)
                {
                    DrawItems[i].Rect.Offset(aRemWidth, 0);
                }
            }
            break;

            case ParaAlignHorz.pahCenter:
            {
                viSplitW = aRemWidth / 2;
                for (int i = aLineEndDItemNo; i >= vLineBegDItemNo; i--)
                {
                    DrawItems[i].Rect.Offset(viSplitW, 0);
                }
            }
            break;

            case ParaAlignHorz.pahJustify:      // 20170220001 两端、分散对齐相关处理
            case ParaAlignHorz.pahScatter:
            {
                if (vParaStyle.AlignHorz == ParaAlignHorz.pahJustify) // 两端对齐
                {
                    if (IsParaLastDrawItem(aLineEndDItemNo))          // 两端对齐,段最后一行不处理
                    {
                        return;
                    }
                }
                else                                                             // 分散对齐,空行或只有一个字符时居中
                {
                    if (vLineBegDItemNo == aLineEndDItemNo)                      // 行只有一个DrawItem
                    {
                        if (Items[DrawItems[vLineBegDItemNo].ItemNo].Length < 2) // 此DrawItem对应的内容长度不足2个按居中处理
                        {
                            viSplitW = aRemWidth / 2;
                            DrawItems[vLineBegDItemNo].Rect.Offset(viSplitW, 0);
                            return;
                        }
                    }
                }

                vLineSpaceCount = 0;
                vExtraW         = 0;
                viSplitMod      = 0;
                viSplitW        = aRemWidth;
                ushort[] vDrawItemSplitCounts = new ushort[aLineEndDItemNo - vLineBegDItemNo + 1]; // 当前行各DItem分几份

                for (int i = vLineBegDItemNo; i <= aLineEndDItemNo; i++)                           // 计算空余分成几份
                {
                    if (GetDrawItemStyle(i) < HCStyle.Null)                                        // RectItem
                    {
                        if ((Items[DrawItems[i].ItemNo] as HCCustomRectItem).JustifySplit() &&
                            (vLineBegDItemNo != aLineEndDItemNo))
                        {          // 分散对齐占间距
                            if (i != aLineEndDItemNo)
                            {
                                vDItemSpaceCount = 1;          // Graphic等占间距
                            }
                            else
                            {
                                vDItemSpaceCount = 0;
                            }
                        }
                        else
                        {
                            vDItemSpaceCount = 0;         // Tab等不占间距
                        }
                    }
                    else                                                              // TextItem
                    {
                        vDItemSpaceCount = GetJustifyCount(GetDrawItemText(i), null); // 当前DItem分了几份
                        if ((i == aLineEndDItemNo) && (vDItemSpaceCount > 0))         // 行尾的DItem,少分一个
                        {
                            vDItemSpaceCount--;
                        }
                    }

                    vDrawItemSplitCounts[i - vLineBegDItemNo] = (ushort)vDItemSpaceCount; // 记录当前DItem分几份
                    vLineSpaceCount = vLineSpaceCount + vDItemSpaceCount;                 // 记录行内总共分几份
                }

                if (vLineSpaceCount > 1)                      // 份数大于1
                {
                    viSplitW   = aRemWidth / vLineSpaceCount; // 每一份的大小
                    viSplitMod = aRemWidth % vLineSpaceCount; // 余数
                }

                // 行中第一个DrawItem增加的空间
                if (vDrawItemSplitCounts[0] > 0)
                {
                    DrawItems[vLineBegDItemNo].Rect.Width += vDrawItemSplitCounts[0] * viSplitW;

                    if (viSplitMod > 0)          // 额外的没有分完
                    {
                        vDLen = DrawItems[vLineBegDItemNo].CharLen;
                        if (viSplitMod > vDLen)          // 足够分
                        {
                            DrawItems[vLineBegDItemNo].Rect.Right += vDLen;
                            viSplitMod = viSplitMod - vDLen;
                        }
                        else         // 不够分
                        {
                            DrawItems[vLineBegDItemNo].Rect.Right += viSplitMod;
                            viSplitMod = 0;
                        }
                    }
                }

                for (int i = vLineBegDItemNo + 1; i <= aLineEndDItemNo; i++)            // 以第一个为基准,其余各DrawItem增加的空间
                {
                    vW = DrawItems[i].Width;                                            // DrawItem原来Width
                    if (vDrawItemSplitCounts[i - vLineBegDItemNo] > 0)                  // 有分到间距
                    {
                        vExtraW = vDrawItemSplitCounts[i - vLineBegDItemNo] * viSplitW; // 多分到的width
                        if (viSplitMod > 0)                                             // 额外的没有分完
                        {
                            if (GetDrawItemStyle(i) < HCStyle.Null)
                            {
                                if ((Items[DrawItems[i].ItemNo] as HCCustomRectItem).JustifySplit())
                                {
                                    vExtraW++;          // 当前DrawItem多分一个像素
                                    viSplitMod--;       // 额外的减少一个像素
                                }
                            }
                            else
                            {
                                vDLen = DrawItems[i].CharLen;
                                if (viSplitMod > vDLen)
                                {
                                    vExtraW    = vExtraW + vDLen;
                                    viSplitMod = viSplitMod - vDLen;
                                }
                                else
                                {
                                    vExtraW    = vExtraW + viSplitMod;
                                    viSplitMod = 0;
                                }
                            }
                        }
                    }
                    else          // 没有分到间距
                    {
                        vExtraW = 0;
                    }

                    DrawItems[i].Rect.Left  = DrawItems[i - 1].Rect.Right;
                    DrawItems[i].Rect.Right = DrawItems[i].Rect.Left + vW + vExtraW;
                }
            }
            break;
            }
        }