/// <summary> /// Allows for customised or precalculated ascent mesurements to be passed, fastest way to draw a string /// </summary> /// <param name="g"></param> /// <param name="pos"></param> /// <param name="fontTable"></param> /// <param name="mesurements"></param> public void drawString(Graphics g, PointF pos, FontFamily[] fontTable, lineInfo mesurements) { int i, j; string printString; Font printFont; SizeF charSize; //float across=pos.X; RTFChar fc; PointF charPos = pos; if (data == null) { return; } for (i = 0; i < data.Length; i++) { fc = data[i]; printString = fc.Char.ToString(); //adjust character position to meat the baseline charPos.Y = pos.Y + mesurements.baseline - mesurements.ascents[i]; //apend any characters drawn in the same style for (j = (i + 1); (j < data.Length) && (fc.compareFormat(data[j])); j++) { printString += data[j].Char; } //update i to the end of the common string i = j - 1; //cache the print font printFont = fc.getFont(fontTable); //charSize = fc.measure(g, fontTable); charSize = g.MeasureString(printString, printFont, 999, RTFLine.defalutFormat()); //draw the string g.DrawString(printString, printFont, new SolidBrush(fc.col), charPos, RTFLine.defalutFormat()); charPos.X += charSize.Width; } }
/// <summary> /// Add a line to a formatted string. /// </summary> /// <param name="fs">A formattedString</param> /// <param name="fl">A formattedLine</param> /// <returns>fl appended to fs.</returns> public static RTFString operator +(RTFString fs, RTFLine fl) { RTFString fsNew = fs; if (fsNew.lines == null) { fsNew.lines = new RTFLine[1] { fl }; } else { RTFLine[] newlines = new RTFLine[fs.lines.Length + 1]; fs.lines.CopyTo(newlines, 0); newlines[fs.lines.Length] = fl; fsNew.lines = newlines; } return(fsNew); }
/// <summary> /// Concatinated two lines into one. /// </summary> /// <param name="fl1">First formattedLine</param> /// <param name="fl2">Second formattedLine</param> /// <returns>Concatinated version of the two lines</returns> public static RTFLine operator +(RTFLine fl1, RTFLine fl2) { RTFLine newLine = fl1; if (fl1.data == null) { return(fl2); } if (fl2.data == null) { return(fl1); } RTFChar[] newData = new RTFChar[fl1.data.Length + fl2.data.Length]; fl1.data.CopyTo(newData, 0); fl2.data.CopyTo(newData, fl1.data.Length); newLine.data = newData; return(newLine); }
/// <summary> /// measure the dimensions of the line /// </summary> /// <param name="g">Graphics context</param> /// <param name="fontTable">Table of fonts</param> /// <returns>lineInfo struct with information on the line.</returns> public lineInfo measure(Graphics g, FontFamily[] fontTable) { int i; lineInfo info; info.mesurement = new SizeF(0.0f, 0.0f); info.baseline = 0; info.ascents = new float[0]; SizeF charSize; float ascent; if (data == null) { return(info); } info.ascents = new float[data.Length]; string printString; Font printFont; RTFChar fc; int j; for (i = 0; i < data.Length; i++) { fc = data[i]; printString = fc.Char.ToString(); //apend any characters drawn in the same style for (j = (i + 1); (j < data.Length) && (fc.compareFormat(data[j])); j++) { printString += data[j].Char; } printFont = fc.getFont(fontTable); charSize = g.MeasureString(printString, printFont, 999, RTFLine.defalutFormat()); ascent = fontTable[data[i].fontIndex].GetCellAscent(data[i].FontStyle); ascent = data[i].size * (ascent / fontTable[data[i].fontIndex].GetEmHeight(data[i].FontStyle)) * 1.3f; if (ascent > info.baseline) { info.baseline = ascent; } info.ascents[i] = ascent; for (int j2 = i; j2 < j; j2++) { info.ascents[j2] = ascent; } //update i to the end of the common string i = j - 1; //printFont = fc.getFont(fontTable); //charSize = g.MeasureString(printString, printFont,999,formattedLine.defalutFormat()); info.mesurement.Width += charSize.Width; if (charSize.Height > info.mesurement.Height) { info.mesurement.Height = charSize.Height; } } /* * for(i=0;i<data.Length;i++) * { * //set the height to the maximum character height * * charSize = data[i].measure(g, fontTable); * if(charSize.Height > info.mesurement.Height) * { * info.mesurement.Height = charSize.Height; * } * * //calculate the acsent of the character * ascent = fontTable[data[i].fontIndex].GetCellAscent(data[i].FontStyle); * * //convert to pixels * //ascent = data[i].size * (ascent / fontTable[data[i].fontIndex].GetEmHeight(data[i].FontStyle)); * //ascent = data[i].size / fontTable[data[i].fontIndex].GetEmHeight(data[i].FontStyle) * ascent; * ascent = data[i].size * (ascent / fontTable[data[i].fontIndex].GetEmHeight(data[i].FontStyle))*1.3f; * * //cache this in the mesurements for later use when rendering the string * info.ascents[i] = ascent; * * //baseline might not be related to the biggest font, but the one with the most ascent * if(ascent > info.baseline) * { * info.baseline = ascent; * } * info.mesurement.Width += charSize.Width; * } */ return(info); }
/// <summary> /// Creates a RTFString from rtf code. /// </summary> /// <param name="rtf">rtf code.</param> /// <returns>A formattedString version of the rtf code.</returns> public RTFString parseRTF(string rtf) { rtCapture.Rtf = rtf; rtCapture.SelectAll(); int numChars = rtCapture.SelectionLength; RTFString text = new RTFString(); text.invalidateMesurements(); RTFLine currentLine = new RTFLine(); RTFChar currentChar = new RTFChar(); ArrayList fontTable = new ArrayList(); int fontIndex; int i; for (i = 0; i < numChars; i++) { rtCapture.Select(i, 1); currentChar.FontStyle = rtCapture.SelectionFont.Style; currentChar.size = rtCapture.SelectionFont.Size; currentChar.Char = rtCapture.SelectedText[0]; currentChar.col = rtCapture.SelectionColor; if (currentChar.Char == '\r') { //do nothing } else if (currentChar.Char == '\n') { if (currentLine.count == 0) { fontIndex = fontTable.IndexOf(rtCapture.SelectionFont.FontFamily); if (fontIndex == -1) { fontIndex = fontTable.Add(rtCapture.SelectionFont.FontFamily); } currentChar.fontIndex = fontIndex; //append to line currentLine += currentChar; } //end line currentLine.horizontalAllignment = rtCapture.SelectionAlignment; currentLine.bulleted = rtCapture.SelectionBullet; text += currentLine; currentLine = new RTFLine(); } else { //check font table fontIndex = fontTable.IndexOf(rtCapture.SelectionFont.FontFamily); if (fontIndex == -1) { fontIndex = fontTable.Add(rtCapture.SelectionFont.FontFamily); } currentChar.fontIndex = fontIndex; //append to line currentLine += currentChar; } } //check if last line was not terminated and needs apending if (currentLine.data != null) { if (currentLine.data.Length > 0) { currentLine.horizontalAllignment = rtCapture.SelectionAlignment; text += currentLine; } } //build the font table text.fontTable = new FontFamily[fontTable.Count]; for (i = 0; i < fontTable.Count; i++) { text.fontTable[i] = (FontFamily)fontTable[i]; } return(text); }