private void CreateHyperlinkClickablePart(RichTextPart richtextpart, Point location, int widthRichTextPart, int heightLineFontsize) { HyperlinkClickablePart hyperlinkClickablepart = new HyperlinkClickablePart(); hyperlinkClickablepart.location = location; hyperlinkClickablepart.width = widthRichTextPart; hyperlinkClickablepart.height = heightLineFontsize; hyperlinkClickablepart.richtextpart = richtextpart; this.hyperlinkclickablepart.Add(hyperlinkClickablepart); }
private void btnAddRichtext_Click(object sender, EventArgs e) { SolidBrush textcolor = new SolidBrush(this.pnlSelectTextColor.BackColor); RichTextPart richtextpartFS12 = new RichTextPart(this.tbNewText.Text, "arial", 12, textcolor, (FontStyle)this.getTextStylesValue()); if (this.chxNewLine.Checked) { richtextpartFS12.AppendNewLine = true; } if (this.chxHyperlink.Checked) { richtextpartFS12.Href = this.tbHyperlink.Text; } this.markupRichtextControl.Append(richtextpartFS12); this.Refresh(); }
protected override void OnPaint(PaintEventArgs paintEvtArgs) { int widthWithoutMargin = this.Width - this.Margin.Horizontal; Point location = new Point(0, 0); for (int i = 0; i < this.richtextparts.Count; ++i) { RichTextPart richTextPart = this.richtextparts[i]; if (richTextPart.IsLine) { Point linestart = location; Point lineend = location; linestart.X += MARGIN_LINE_LEFT; linestart.Y += MARGIN_LINE_TOP; lineend.X += this.Width - MARGIN_LINE_RIGHT; lineend.Y += MARGIN_LINE_TOP; richTextPart.DrawLine(paintEvtArgs, linestart, lineend); location.Y += LINE_HEIGHT; continue; } if (richTextPart.PrependBullit) { richTextPart.Text = "• " + richTextPart.Text; } if (richTextPart.Text.Length == 0) { continue; } SizeF textsize = richTextPart.GetSizeText(paintEvtArgs); int heightLineFontsize = Convert.ToInt32(textsize.Height); int widthRichTextPart = Convert.ToInt32(textsize.Width); // Check if richTextPart needs to be an extra line/multiple line(s). if (location.X + widthRichTextPart >= widthWithoutMargin) { int posstartpartofrichtextpart = 0; int restTextLength = richTextPart.Text.Length - posstartpartofrichtextpart; int widthpartoftextpart = 0; int lastspacerichtextpart = 0; int lastdotrichtextpart = 0; // Check foreach characters where to split in this richtext part for (int n = 0; n < richTextPart.Text.Length; ++n) { if (richTextPart.Text[n] == ' ') { lastspacerichtextpart = n; } else if (richTextPart.Text[n] == '.') { lastdotrichtextpart = n; } int posstartwrap = n; if (this.wordwrapmodus == WordWrapMode.OnCharacter || lastspacerichtextpart == 0 && this.wordwrapmodus == WordWrapMode.OnWord) { posstartwrap = n; } else if (this.wordwrapmodus == WordWrapMode.OnWord || lastdotrichtextpart == 0 && this.wordwrapmodus == WordWrapMode.OnSentence) { posstartwrap = lastspacerichtextpart; } else if (this.wordwrapmodus == WordWrapMode.OnSentence) { posstartwrap = lastdotrichtextpart; } int textlengthpartofrichtextpart = posstartwrap - posstartpartofrichtextpart; if (textlengthpartofrichtextpart == 0) { continue; } widthpartoftextpart = richTextPart.GetWidthTextPart(paintEvtArgs, posstartpartofrichtextpart, textlengthpartofrichtextpart); int widthcharpartoftextpart = richTextPart.GetWidthTextPart(paintEvtArgs, posstartpartofrichtextpart, n - posstartpartofrichtextpart); int charlocx = location.X + widthcharpartoftextpart; if (charlocx >= widthWithoutMargin) { // A new line in control is needed for part of richtextpart. richTextPart.DrawPart(paintEvtArgs, location, posstartpartofrichtextpart, textlengthpartofrichtextpart); if (!String.IsNullOrEmpty(richTextPart.Href)) { this.CreateHyperlinkClickablePart(richTextPart, location, widthpartoftextpart, heightLineFontsize); } // Update location position for next subpart of the richtextpart. location.X = 0; location.Y += heightLineFontsize; // Update start position character and textlength for spliting next subpart of the richtextpart over multiple lines. posstartpartofrichtextpart = posstartwrap; restTextLength = richTextPart.Text.Length - posstartpartofrichtextpart; widthRichTextPart = richTextPart.GetWidthTextPart(paintEvtArgs, posstartpartofrichtextpart, restTextLength); } } // Draw rest of characters that still fit on one a line. richTextPart.DrawPart(paintEvtArgs, location, posstartpartofrichtextpart, restTextLength); if (!String.IsNullOrEmpty(richTextPart.Href)) { widthpartoftextpart = richTextPart.GetWidthTextPart(paintEvtArgs, posstartpartofrichtextpart, restTextLength); this.CreateHyperlinkClickablePart(richTextPart, location, widthpartoftextpart, heightLineFontsize); } } else { if (!String.IsNullOrEmpty(richTextPart.Href)) { this.CreateHyperlinkClickablePart(richTextPart, location, widthRichTextPart, heightLineFontsize); } richTextPart.Draw(paintEvtArgs, location); } if (richTextPart.PrependBullit) { richTextPart.Text = richTextPart.Text.Substring(2); } location = this.UpdateLocationNewRichTextPart(widthRichTextPart, heightLineFontsize, location, widthWithoutMargin); if (richTextPart.AppendNewLine) { location.Y += heightLineFontsize; location.X = 0; } } }
/// <summary> /// Add a new part of rich text to this control. /// </summary> /// <param name="newRichTextPart"></param> public void Append(RichTextPart newRichTextPart) { this.richtextparts.Add(newRichTextPart); }
/// <summary> /// Parse the markup to RichTextParts and add them to the markuptextcontrol. /// </summary> /// <param name="markup"></param> public void ParseMarkup(string markup) { MarkupTokenizer tokonizer = new MarkupTokenizer(markup); tokonizer.FindTokens(); MarkupToken[] markuptokens = tokonizer.GetTokens(); SolidBrush solidbrushTextcolorDefault = new SolidBrush(Color.Black); RichTextPart richtextpart = null; bool previous_markuptokon_hyperlinktext = false; for (int i = 0; i < markuptokens.Length; ++i) { if (markuptokens[i].IsLine) { richtextpart = new RichTextPart(Pens.Black); this.markuptextcontrol.Append(richtextpart); } else { switch (markuptokens[i].CharLeft) { case '#': // head int headlevel = markuptokens[i].Level; richtextpart = new RichTextPart(markuptokens[i].Text, this.fontfamily, this.headsfontsizes[headlevel], solidbrushTextcolorDefault, FontStyle.Bold); richtextpart.AppendNewLine = true; this.markuptextcontrol.Append(richtextpart); previous_markuptokon_hyperlinktext = false; break; case '-': // list richtextpart = new RichTextPart(markuptokens[i].Text, this.fontfamily, this.fontsizedefault, solidbrushTextcolorDefault, FontStyle.Regular); richtextpart.PrependBullit = true; richtextpart.AppendNewLine = true; this.markuptextcontrol.Append(richtextpart); previous_markuptokon_hyperlinktext = false; break; case '*': case '_': // emphasis int emphasislevel = markuptokens[i].Level; int emphasisfontstyle = (int)FontStyle.Italic; if (emphasislevel >= 1) { emphasisfontstyle = (int)FontStyle.Bold; } if (emphasislevel >= 2) { emphasisfontstyle += (int)FontStyle.Italic; } richtextpart = new RichTextPart(markuptokens[i].Text, this.fontfamily, this.fontsizedefault, solidbrushTextcolorDefault, (FontStyle)emphasisfontstyle); this.markuptextcontrol.Append(richtextpart); previous_markuptokon_hyperlinktext = false; break; case '~': // strikethrough richtextpart = new RichTextPart(markuptokens[i].Text, this.fontfamily, this.fontsizedefault, solidbrushTextcolorDefault, FontStyle.Strikeout); this.markuptextcontrol.Append(richtextpart); previous_markuptokon_hyperlinktext = false; break; case '[': // hyperlink text previous_markuptokon_hyperlinktext = true; break; case '(': // hyperlink url if (previous_markuptokon_hyperlinktext && i > 0) { FontStyle fontsylehyperlink = FontStyle.Underline; SolidBrush solidbrushHyperlink = new SolidBrush(Color.Blue); richtextpart = new RichTextPart(markuptokens[i - 1].Text, this.fontfamily, this.fontsizedefault, solidbrushHyperlink, fontsylehyperlink); richtextpart.Href = markuptokens[i].Text; this.markuptextcontrol.Append(richtextpart); } previous_markuptokon_hyperlinktext = false; break; case '`': // TODO: literally and code highlighting previous_markuptokon_hyperlinktext = false; break; default: if (markuptokens[i].Nomarkup) { richtextpart = new RichTextPart(markuptokens[i].Text, this.fontfamily, this.fontsizedefault, solidbrushTextcolorDefault, FontStyle.Regular); richtextpart.AppendNewLine = markuptokens[i].TextAppendNewLine; this.markuptextcontrol.Append(richtextpart); } break; } } } this.markuptextcontrol.Refresh(); }