// render all the objects in a page (or any composite object private void ProcessPage(System.Drawing.Graphics g, IEnumerable p) { // TODO: (Peter) Support can grow and can shrink foreach (PageItem pi in p) { if (pi is PageTextHtml) { // PageTextHtml is actually a composite object (just like a page) ProcessHtml(pi as PageTextHtml, g); continue; } if (pi is PageLine) { PageLine pl = pi as PageLine; DrawLine(pl.SI.BColorLeft, pl.SI.BStyleLeft, pl.SI.BWidthLeft, g, PixelsX(pl.X + _left - _hScroll), PixelsY(pl.Y + _top - _vScroll), PixelsX(pl.X2 + _left - _hScroll), PixelsY(pl.Y2 + _top - _vScroll)); continue; } RectangleF rect = new RectangleF(PixelsX(pi.X + _left - _hScroll), PixelsY(pi.Y + _top - _vScroll), PixelsX(pi.W), PixelsY(pi.H)); if ((pi is PagePolygon) || (pi is PageCurve)) { // intentionally empty; polygon's rectangles aren't calculated } if (pi.SI.BackgroundImage != null) { // put out any background image PageImage i = pi.SI.BackgroundImage; DrawImageBackground(i, pi.SI, g, rect); } if (pi is PageText) { // TODO: enable can shrink, can grow // 2005 spec file, page 9, in the text box has // CanGrow and CanShrink PageText pt = pi as PageText; DrawString(pt, g, rect); } else if (pi is PageImage) { PageImage i = pi as PageImage; DrawImage(i, g, rect); } else if (pi is PageRectangle) { this.DrawBackground(g, rect, pi.SI); } else if (pi is PageEllipse) { PageEllipse pe = pi as PageEllipse; DrawEllipse(pe, g, rect); } else if (pi is PagePie) { PagePie pp = pi as PagePie; DrawPie(pp, g, rect); } else if (pi is PagePolygon) { PagePolygon ppo = pi as PagePolygon; FillPolygon(ppo, g, rect); } else if (pi is PageCurve) { PageCurve pc = pi as PageCurve; DrawCurve(pc.SI.BColorLeft, pc.SI.BStyleLeft, pc.SI.BWidthLeft, g, pc.Points, pc.Offset, pc.Tension); } DrawBorder(pi, g, rect); } // TO: convert System.Drawing.Graphics to Xwt.Drawing.Context and draw it to this.g Bitmap bm = new Bitmap(gImg.Width, gImg.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); g.DrawImage(bm, gImg.Width, gImg.Height); // Xwt.Drawing.Image.FromStream does not work. It crashes with both wpf and gtk // As a work around save the image to a temporary file and load it into xwt using the // FromFile method. System.IO.MemoryStream s = new System.IO.MemoryStream(); gImg.Save(s, System.Drawing.Imaging.ImageFormat.Png); Xwt.Drawing.Image img = Xwt.Drawing.Image.FromStream(s); xwtContext.DrawImage(img, new Xwt.Rectangle(0, 0, gImg.Width, gImg.Height), new Xwt.Rectangle(0, 0, gImg.Width, gImg.Height)); img.Dispose(); }
private void DrawString(PageText pt, Graphics g, RectangleF r) { StyleInfo si = pt.SI; string s = pt.Text; Font drawFont = null; StringFormat drawFormat = null; Brush drawBrush = null; try { // STYLE System.Drawing.FontStyle fs = 0; if (si.FontStyle == FontStyleEnum.Italic) { fs |= System.Drawing.FontStyle.Italic; } switch (si.TextDecoration) { case TextDecorationEnum.Underline: fs |= System.Drawing.FontStyle.Underline; break; case TextDecorationEnum.LineThrough: fs |= System.Drawing.FontStyle.Strikeout; break; case TextDecorationEnum.Overline: case TextDecorationEnum.None: break; } // WEIGHT switch (si.FontWeight) { case FontWeightEnum.Bold: case FontWeightEnum.Bolder: case FontWeightEnum.W500: case FontWeightEnum.W600: case FontWeightEnum.W700: case FontWeightEnum.W800: case FontWeightEnum.W900: fs |= System.Drawing.FontStyle.Bold; break; default: break; } try { drawFont = new Font(si.GetFontFamily(), si.FontSize, fs); // si.FontSize already in points } catch (ArgumentException) { drawFont = new Font("Arial", si.FontSize, fs); // if this fails we'll let the error pass thru } // ALIGNMENT drawFormat = new StringFormat(); switch (si.TextAlign) { case TextAlignEnum.Right: drawFormat.Alignment = StringAlignment.Far; break; case TextAlignEnum.Center: drawFormat.Alignment = StringAlignment.Center; break; case TextAlignEnum.Left: default: drawFormat.Alignment = StringAlignment.Near; break; } if (pt.SI.WritingMode == WritingModeEnum.tb_rl) { drawFormat.FormatFlags |= StringFormatFlags.DirectionRightToLeft; drawFormat.FormatFlags |= StringFormatFlags.DirectionVertical; } switch (si.VerticalAlign) { case VerticalAlignEnum.Bottom: drawFormat.LineAlignment = StringAlignment.Far; break; case VerticalAlignEnum.Middle: drawFormat.LineAlignment = StringAlignment.Center; break; case VerticalAlignEnum.Top: default: drawFormat.LineAlignment = StringAlignment.Near; break; } // draw the background DrawBackground(g, r, si); // adjust drawing rectangle based on padding // http://www.fyireporting.com/forum/viewtopic.php?t=892 //A.S.> convert pt to px if needed(when printing we need px, when draw preview - pt) RectangleF r2; if (g.PageUnit == GraphicsUnit.Pixel) { r2 = new RectangleF(r.Left + (si.PaddingLeft * g.DpiX) / 72, r.Top + (si.PaddingTop * g.DpiX) / 72, r.Width - ((si.PaddingLeft + si.PaddingRight) * g.DpiX) / 72, r.Height - ((si.PaddingTop + si.PaddingBottom) * g.DpiX) / 72); } else { // adjust drawing rectangle based on padding r2 = new RectangleF(r.Left + si.PaddingLeft, r.Top + si.PaddingTop, r.Width - si.PaddingLeft - si.PaddingRight, r.Height - si.PaddingTop - si.PaddingBottom); } drawBrush = new SolidBrush(si.Color); if (si.TextAlign == TextAlignEnum.Justified) { GraphicsExtended.DrawStringJustified(g, pt.Text, drawFont, drawBrush, r2); } else if (pt.NoClip) // request not to clip text { g.DrawString(pt.Text, drawFont, drawBrush, new PointF(r.Left, r.Top), drawFormat); } else { g.DrawString(pt.Text, drawFont, drawBrush, r2, drawFormat); } } finally { if (drawFont != null) { drawFont.Dispose(); } if (drawFormat != null) { drawFont.Dispose(); } if (drawBrush != null) { drawBrush.Dispose(); } } }
public static string[] MeasureString(PageText pt, Graphics g, out float[] width) { StyleInfo si = pt.SI; string s = pt.Text; System.Drawing.Font drawFont = null; StringFormat drawFormat = null; SizeF ms; string[] sa = null; width = null; try { // STYLE System.Drawing.FontStyle fs = 0; if (si.FontStyle == FontStyleEnum.Italic) fs |= System.Drawing.FontStyle.Italic; // WEIGHT switch (si.FontWeight) { case FontWeightEnum.Bold: case FontWeightEnum.Bolder: case FontWeightEnum.W500: case FontWeightEnum.W600: case FontWeightEnum.W700: case FontWeightEnum.W800: case FontWeightEnum.W900: fs |= System.Drawing.FontStyle.Bold; break; default: break; } drawFont = new System.Drawing.Font(StyleInfo.GetFontFamily(si.FontFamilyFull), si.FontSize, fs); drawFormat = new StringFormat(); drawFormat.Alignment = StringAlignment.Near; // Measure string // pt.NoClip indicates that this was generated by PageTextHtml Build. It has already word wrapped. if (pt.NoClip || pt.SI.WritingMode == WritingModeEnum.tb_rl) // TODO: support multiple lines for vertical text { ms = MeasureString(s, g, drawFont, drawFormat); width = new float[1]; width[0] = Measurement.PointsFromPixels(ms.Width, g.DpiX); // convert to points from pixels sa = new string[1]; sa[0] = s; return sa; } // handle multiple lines; // 1) split the string into the forced line breaks (ie "\n and \r") // 2) foreach of the forced line breaks; break these into words and recombine s = s.Replace("\r\n", "\n"); // don't want this to result in double lines string[] flines = s.Split(LINEBREAK); List<string> lines = new List<string>(); List<float> lineWidths = new List<float>(); // remove the size reserved for left and right padding float ptWidth = pt.W - pt.SI.PaddingLeft - pt.SI.PaddingRight; if (ptWidth <= 0) ptWidth = 1; foreach (string tfl in flines) { string fl; if (tfl.Length > 0 && tfl[tfl.Length - 1] == ' ') fl = tfl.TrimEnd(' '); else fl = tfl; // Check if entire string fits into a line ms = MeasureString(fl, g, drawFont, drawFormat); float tw = Measurement.PointsFromPixels(ms.Width, g.DpiX); if (tw <= ptWidth) { // line fits don't need to break it down further lines.Add(fl); lineWidths.Add(tw); continue; } // Line too long; need to break into multiple lines // 1) break line into parts; then build up again keeping track of word positions string[] parts = fl.Split(WORDBREAK); // this is the maximum split of lines StringBuilder sb = new StringBuilder(fl.Length); CharacterRange[] cra = new CharacterRange[parts.Length]; for (int i = 0; i < parts.Length; i++) { int sc = sb.Length; // starting character sb.Append(parts[i]); // endding character if (i != parts.Length - 1) // last item doesn't need blank sb.Append(" "); int ec = sb.Length; CharacterRange cr = new CharacterRange(sc, ec - sc); cra[i] = cr; // add to character array } // 2) Measure the word locations within the line string wfl = sb.ToString(); WordStartFinish[] wordLocations = MeasureString(wfl, g, drawFont, drawFormat, cra); if (wordLocations == null) continue; // 3) Loop thru creating new lines as needed int startLoc = 0; CharacterRange crs = cra[startLoc]; CharacterRange cre = cra[startLoc]; float cwidth = wordLocations[0].end; // length of the first float bwidth = wordLocations[0].start; // characters need a little extra on start string ts; bool bLine = true; for (int i = 1; i < cra.Length; i++) { cwidth = wordLocations[i].end - wordLocations[startLoc].start + bwidth; if (cwidth > ptWidth) { // time for a new line cre = cra[i - 1]; ts = wfl.Substring(crs.First, cre.First + cre.Length - crs.First); lines.Add(ts); lineWidths.Add(wordLocations[i - 1].end - wordLocations[startLoc].start + bwidth); // Find the first non-blank character of the next line while (i < cra.Length && cra[i].Length == 1 && fl[cra[i].First] == ' ') { i++; } if (i < cra.Length) // any lines left? { // yes, continue on startLoc = i; crs = cre = cra[startLoc]; cwidth = wordLocations[i].end - wordLocations[startLoc].start + bwidth; } else // no, we can stop bLine = false; // bwidth = wordLocations[startLoc].start - wordLocations[startLoc - 1].end; } else cre = cra[i]; } if (bLine) { ts = fl.Substring(crs.First, cre.First + cre.Length - crs.First); lines.Add(ts); lineWidths.Add(cwidth); } } // create the final array from the Lists string[] la = lines.ToArray(); width = lineWidths.ToArray(); return la; } finally { if (drawFont != null) drawFont.Dispose(); if (drawFormat != null) drawFont.Dispose(); } }
// render all the objects in a page (or any composite object private void ProcessPage(Graphics g, IEnumerable p, RectangleF clipRect, bool bHitList) { // TODO: (Peter) Support can grow and can shrink foreach (PageItem pi in p) { //if (pi is PageTextHtml) //{ // PageTextHtml is actually a composite object (just like a page) // if (SelectTool && bHitList) // { // RectangleF hr = new RectangleF(PixelsX(pi.X + _left - _hScroll), PixelsY(pi.Y + _top - _vScroll), // PixelsX(pi.W), PixelsY(pi.H)); // _HitList.Add(new HitListEntry(hr, pi)); // } // ProcessHtml(pi as PageTextHtml, g, clipRect, bHitList); // continue; //} if (pi is PageLine) { PageLine pl = pi as PageLine; DrawLine(pl.SI.BColorLeft, pl.SI.BStyleLeft, pl.SI.BWidthLeft, g, PixelsX(pl.X + _left - _hScroll), PixelsY(pl.Y + _top - _vScroll), PixelsX(pl.X2 + _left - _hScroll), PixelsY(pl.Y2 + _top - _vScroll)); continue; } RectangleF rect = new RectangleF(PixelsX(pi.X + _left - _hScroll), PixelsY(pi.Y + _top - _vScroll), PixelsX(pi.W), PixelsY(pi.H)); // Maintain the hit list //if (bHitList) //{ // if (SelectTool) // { // we need all PageText and PageImage items that have been displayed // if (pi is PageText || pi is PageImage) // { // _HitList.Add(new HitListEntry(rect, pi)); // } // } // // Only care about items with links and tips // else if (pi.HyperLink != null || pi.BookmarkLink != null || pi.Tooltip != null) // { // HitListEntry hle; // if (pi is PagePolygon) // hle = new HitListEntry(pi as PagePolygon, _left - _hScroll, _top - _vScroll, this); // else // hle = new HitListEntry(rect, pi); // _HitList.Add(hle); // } //} if ((pi is PagePolygon) || (pi is PageCurve)) { // intentionally empty; polygon's rectangles aren't calculated } else if (!rect.IntersectsWith(clipRect)) { continue; } if (pi.SI.BackgroundImage != null) { // put out any background image PageImage i = pi.SI.BackgroundImage; DrawImageBackground(i, pi.SI, g, rect); } if (pi is PageText) { // TODO: enable can shrink, can grow // 2005 spec file, page 9, in the text box has // CanGrow and CanShrink PageText pt = pi as PageText; DrawString(pt, g, rect); } else if (pi is PageImage) { PageImage i = pi as PageImage; DrawImage(i, g, rect); } else if (pi is PageRectangle) { this.DrawBackground(g, rect, pi.SI); } else if (pi is PageEllipse) { PageEllipse pe = pi as PageEllipse; DrawEllipse(pe, g, rect); } else if (pi is PagePie) { PagePie pp = pi as PagePie; DrawPie(pp, g, rect); } else if (pi is PagePolygon) { PagePolygon ppo = pi as PagePolygon; FillPolygon(ppo, g, rect); } else if (pi is PageCurve) { PageCurve pc = pi as PageCurve; DrawCurve(pc.SI.BColorLeft, pc.SI.BStyleLeft, pc.SI.BWidthLeft, g, pc.Points, pc.Offset, pc.Tension); } DrawBorder(pi, g, rect); } }
private void ProcessPage(Cairo.Context g, IEnumerable p) { foreach (PageItem pi in p) { if (pi is PageTextHtml) // PageTextHtml is actually a composite object (just like a page) { ProcessHtml(pi as PageTextHtml, g); continue; } if (pi is PageLine) { PageLine pl = pi as PageLine; DrawLine( pl.SI.BColorLeft.ToCairoColor(), pl.SI.BStyleLeft, pl.SI.BWidthLeft, g, PixelsX(pl.X), PixelsY(pl.Y), PixelsX(pl.X2), PixelsY(pl.Y2) ); continue; } // RectangleF rect = new RectangleF(PixelsX(pi.X), PixelsY(pi.Y), PixelsX(pi.W), PixelsY(pi.H)); Cairo.Rectangle rect = new Cairo.Rectangle(PixelsX(pi.X), PixelsY(pi.Y), PixelsX(pi.W), PixelsY(pi.H)); if (pi.SI.BackgroundImage != null) { // put out any background image PageImage i = pi.SI.BackgroundImage; DrawImage(i, g, rect); continue; } if (pi is PageText) { PageText pt = pi as PageText; DrawString(pt, g, rect); } if (pi is PageImage) { PageImage i = pi as PageImage; DrawImage(i, g, rect); } if (pi is PageRectangle) { //DrawBackground(g, rect, pi.SI); } // else if (pi is PageEllipse) // { // PageEllipse pe = pi as PageEllipse; // DrawEllipse(pe, g, rect); // } // else if (pi is PagePie) // { // PagePie pp = pi as PagePie; // DrawPie(pp, g, rect); // } // else if (pi is PagePolygon) // { // PagePolygon ppo = pi as PagePolygon; // FillPolygon(ppo, g, rect); // } // else if (pi is PageCurve) // { // PageCurve pc = pi as PageCurve; // DrawCurve(pc.SI.BColorLeft, pc.SI.BStyleLeft, pc.SI.BWidthLeft, // g, pc.Points, pc.Offset, pc.Tension); // } // DrawBorder(pi, g, rect); } }
private void DrawString(PageText pt, Cairo.Context g, Cairo.Rectangle r) { StyleInfo si = pt.SI; string s = pt.Text; g.Save(); layout = Pango.CairoHelper.CreateLayout(g); // Font drawFont = null; // StringFormat drawFormat = null; // Brush drawBrush = null; // STYLE // System.Drawing.FontStyle fs = 0; // if (si.FontStyle == FontStyleEnum.Italic) // fs |= System.Drawing.FontStyle.Italic; //Pango fonts are scaled to 72dpi, Windows fonts uses 96dpi float fontsize = (si.FontSize * 72 / 96); var font = Pango.FontDescription.FromString(string.Format("{0} {1}", si.GetFontFamily().Name, fontsize * PixelsX(1))); if (si.FontStyle == FontStyleEnum.Italic) { font.Style = Pango.Style.Italic; } // // switch (si.TextDecoration) // { // case TextDecorationEnum.Underline: // fs |= System.Drawing.FontStyle.Underline; // break; // case TextDecorationEnum.LineThrough: // fs |= System.Drawing.FontStyle.Strikeout; // break; // case TextDecorationEnum.Overline: // case TextDecorationEnum.None: // break; // } // WEIGHT // switch (si.FontWeight) // { // case FontWeightEnum.Bold: // case FontWeightEnum.Bolder: // case FontWeightEnum.W500: // case FontWeightEnum.W600: // case FontWeightEnum.W700: // case FontWeightEnum.W800: // case FontWeightEnum.W900: // fs |= System.Drawing.FontStyle.Bold; // break; // default: // break; // } // try // { // drawFont = new Font(si.GetFontFamily(), si.FontSize, fs); // si.FontSize already in points // } // catch (ArgumentException) // { // drawFont = new Font("Arial", si.FontSize, fs); // if this fails we'll let the error pass thru // } //font.AbsoluteSize = (int)(PixelsX (si.FontSize)); switch (si.FontWeight) { case FontWeightEnum.Bold: case FontWeightEnum.Bolder: case FontWeightEnum.W500: case FontWeightEnum.W600: case FontWeightEnum.W700: case FontWeightEnum.W800: case FontWeightEnum.W900: font.Weight = Pango.Weight.Bold; break; } Pango.FontDescription oldfont = layout.FontDescription; layout.FontDescription = font; // ALIGNMENT // drawFormat = new StringFormat(); // switch (si.TextAlign) // { // case TextAlignEnum.Right: // drawFormat.Alignment = StringAlignment.Far; // break; // case TextAlignEnum.Center: // drawFormat.Alignment = StringAlignment.Center; // break; // case TextAlignEnum.Left: // default: // drawFormat.Alignment = StringAlignment.Near; // break; // } switch (si.TextAlign) { case TextAlignEnum.Right: layout.Alignment = Pango.Alignment.Right; break; case TextAlignEnum.Center: layout.Alignment = Pango.Alignment.Center; break; case TextAlignEnum.Left: default: layout.Alignment = Pango.Alignment.Left; break; } layout.Width = Pango.Units.FromPixels((int)(r.Width - si.PaddingLeft - si.PaddingRight - 2)); // layout.Width = (int)Pango.Units.FromPixels((int)r.Width); layout.SetText(s); // if (pt.SI.WritingMode == WritingModeEnum.tb_rl) // { // drawFormat.FormatFlags |= StringFormatFlags.DirectionRightToLeft; // drawFormat.FormatFlags |= StringFormatFlags.DirectionVertical; // } // switch (si.VerticalAlign) // { // case VerticalAlignEnum.Bottom: // drawFormat.LineAlignment = StringAlignment.Far; // break; // case VerticalAlignEnum.Middle: // drawFormat.LineAlignment = StringAlignment.Center; // break; // case VerticalAlignEnum.Top: // default: // drawFormat.LineAlignment = StringAlignment.Near; // break; // } // Pango.Rectangle logical; Pango.Rectangle ink; layout.GetExtents(out ink, out logical); double height = logical.Height / Pango.Scale.PangoScale; double y = 0; switch (si.VerticalAlign) { case VerticalAlignEnum.Top: y = r.Y + si.PaddingTop; break; case VerticalAlignEnum.Middle: y = r.Y + (r.Height - height) / 2; break; case VerticalAlignEnum.Bottom: y = r.Y + (r.Height - height) - si.PaddingBottom; break; } // draw the background DrawBackground(g, r, si); // adjust drawing rectangle based on padding // Cairo.Rectangle r2 = new Cairo.Rectangle(r.X + si.PaddingLeft, // r.Y + si.PaddingTop, // r.Width - si.PaddingLeft - si.PaddingRight, // r.Height - si.PaddingTop - si.PaddingBottom); Cairo.Rectangle box = new Cairo.Rectangle( r.X + si.PaddingLeft + 1, y, r.Width, r.Height); //drawBrush = new SolidBrush(si.Color); g.Color = si.Color.ToCairoColor(); // if (pt.NoClip) // request not to clip text // { // g.DrawString(pt.Text, drawFont, drawBrush, new PointF(r.Left, r.Top), drawFormat); // //HighlightString(g, pt, new RectangleF(r.Left, r.Top, float.MaxValue, float.MaxValue),drawFont, drawFormat); // } // else // { // g.DrawString(pt.Text, drawFont, drawBrush, r2, drawFormat); // //HighlightString(g, pt, r2, drawFont, drawFormat); // } g.MoveTo(box.X, box.Y); Pango.CairoHelper.ShowLayout(g, layout); layout.FontDescription = oldfont; g.Restore(); }
// render all the objects in a page (or any composite object private void ProcessPage(Graphics g, IEnumerable p, RectangleF clipRect, bool bHitList) { foreach (PageItem pi in p) { if (pi is PageTextHtml) { // PageTextHtml is actually a composite object (just like a page) if (SelectTool && bHitList) { RectangleF hr = new RectangleF(PixelsX(pi.X + _left - _hScroll), PixelsY(pi.Y + _top - _vScroll), PixelsX(pi.W), PixelsY(pi.H)); _HitList.Add(new HitListEntry(hr, pi)); } ProcessHtml(pi as PageTextHtml, g, clipRect, bHitList); continue; } if (pi is PageLine) { PageLine pl = pi as PageLine; DrawLine(pl.SI.BColorLeft, pl.SI.BStyleLeft, pl.SI.BWidthLeft, g, PixelsX(pl.X + _left - _hScroll), PixelsY(pl.Y + _top - _vScroll), PixelsX(pl.X2 + _left - _hScroll), PixelsY(pl.Y2 + _top - _vScroll)); continue; } RectangleF rect = new RectangleF(PixelsX(pi.X + _left - _hScroll), PixelsY(pi.Y + _top - _vScroll), PixelsX(pi.W), PixelsY(pi.H)); // Maintain the hit list if (bHitList) { if (SelectTool) { // we need all PageText and PageImage items that have been displayed if (pi is PageText || pi is PageImage) { _HitList.Add(new HitListEntry(rect, pi)); } } // Only care about items with links and tips else if (pi.HyperLink != null || pi.BookmarkLink != null || pi.Tooltip != null) { _HitList.Add(new HitListEntry(rect, pi)); } } if (!rect.IntersectsWith(clipRect)) { continue; } if (pi.SI.BackgroundImage != null) { // put out any background image PageImage i = pi.SI.BackgroundImage; DrawImageBackground(i, pi.SI, g, rect); } if (pi is PageText) { PageText pt = pi as PageText; DrawString(pt, g, rect); } else if (pi is PageImage) { PageImage i = pi as PageImage; DrawImage(i, g, rect); } else if (pi is PageRectangle) { this.DrawBackground(g, rect, pi.SI); } DrawBorder(pi, g, rect); } }
private void HighlightString(Graphics g, PageText dtext, RectangleF r, Font f, StringFormat sf) { if (_HighlightText == null || _HighlightText.Length == 0) { return; // nothing to highlight } bool bhighlightItem = dtext == _HighlightItem || (_HighlightItem != null && dtext.HtmlParent == _HighlightItem); if (!(_HighlightAll || bhighlightItem)) { return; // not highlighting all and not on current highlight item } string hlt = _HighlightCaseSensitive ? _HighlightText : _HighlightText.ToLower(); string text = _HighlightCaseSensitive ? dtext.Text : dtext.Text.ToLower(); if (text.IndexOf(hlt) < 0) { return; // string not in text } StringFormat sf2 = null; try { // Create a CharacterRange array with the highlight location and length // Handle multiple occurences of text List <CharacterRange> rangel = new List <CharacterRange>(); int loc = text.IndexOf(hlt); int hlen = hlt.Length; int len = text.Length; while (loc >= 0) { rangel.Add(new CharacterRange(loc, hlen)); if (loc + hlen < len) // out of range of text { loc = text.IndexOf(hlt, loc + hlen); } else { loc = -1; } } if (rangel.Count <= 0) // we should have gotten one; but { return; } CharacterRange[] ranges = rangel.ToArray(); // Construct a new StringFormat object. sf2 = sf.Clone() as StringFormat; // Set the ranges on the StringFormat object. sf2.SetMeasurableCharacterRanges(ranges); // Get the Regions to highlight by calling the // MeasureCharacterRanges method. Region[] charRegion = g.MeasureCharacterRanges(dtext.Text, f, r, sf2); // Fill in the region using a semi-transparent color to highlight foreach (Region rg in charRegion) { Color hl = bhighlightItem ? _HighlightItemColor : _HighlightAllColor; g.FillRegion(new SolidBrush(Color.FromArgb(50, hl)), rg); } } catch { } // if highlighting fails we don't care; need to continue finally { if (sf2 != null) { sf2.Dispose(); } } }
private void DrawString(PageText pt, Graphics g, RectangleF r) { StyleInfo si = pt.SI; string s = pt.Text; Font drawFont = null; StringFormat drawFormat = null; Brush drawBrush = null; try { // STYLE System.Drawing.FontStyle fs = 0; if (si.FontStyle == FontStyleEnum.Italic) { fs |= System.Drawing.FontStyle.Italic; } switch (si.TextDecoration) { case TextDecorationEnum.Underline: fs |= System.Drawing.FontStyle.Underline; break; case TextDecorationEnum.LineThrough: fs |= System.Drawing.FontStyle.Strikeout; break; case TextDecorationEnum.Overline: case TextDecorationEnum.None: break; } // WEIGHT switch (si.FontWeight) { case FontWeightEnum.Bold: case FontWeightEnum.Bolder: case FontWeightEnum.W500: case FontWeightEnum.W600: case FontWeightEnum.W700: case FontWeightEnum.W800: case FontWeightEnum.W900: fs |= System.Drawing.FontStyle.Bold; break; default: break; } try { drawFont = new Font(si.GetFontFamily(), si.FontSize, fs); // si.FontSize already in points } catch (ArgumentException) { drawFont = new Font("Arial", si.FontSize, fs); // if this fails we'll let the error pass thru } // ALIGNMENT drawFormat = new StringFormat(); switch (si.TextAlign) { case TextAlignEnum.Right: drawFormat.Alignment = StringAlignment.Far; break; case TextAlignEnum.Center: drawFormat.Alignment = StringAlignment.Center; break; case TextAlignEnum.Left: default: drawFormat.Alignment = StringAlignment.Near; break; } if (pt.SI.WritingMode == WritingModeEnum.tb_rl) { drawFormat.FormatFlags |= StringFormatFlags.DirectionRightToLeft; drawFormat.FormatFlags |= StringFormatFlags.DirectionVertical; } switch (si.VerticalAlign) { case VerticalAlignEnum.Bottom: drawFormat.LineAlignment = StringAlignment.Far; break; case VerticalAlignEnum.Middle: drawFormat.LineAlignment = StringAlignment.Center; break; case VerticalAlignEnum.Top: default: drawFormat.LineAlignment = StringAlignment.Near; break; } // draw the background DrawBackground(g, r, si); // adjust drawing rectangle based on padding RectangleF r2 = new RectangleF(r.Left + si.PaddingLeft, r.Top + si.PaddingTop, r.Width - si.PaddingLeft - si.PaddingRight, r.Height - si.PaddingTop - si.PaddingBottom); drawBrush = new SolidBrush(si.Color); if (pt.NoClip) // request not to clip text { g.DrawString(pt.Text, drawFont, drawBrush, new PointF(r.Left, r.Top), drawFormat); HighlightString(g, pt, new RectangleF(r.Left, r.Top, float.MaxValue, float.MaxValue), drawFont, drawFormat); } else { g.DrawString(pt.Text, drawFont, drawBrush, r2, drawFormat); HighlightString(g, pt, r2, drawFont, drawFormat); } if (SelectTool) { if (pt.AllowSelect && _SelectList.Contains(pt)) { g.FillRectangle(new SolidBrush(Color.FromArgb(50, _SelectItemColor)), r2); } } } finally { if (drawFont != null) { drawFont.Dispose(); } if (drawFormat != null) { drawFont.Dispose(); } if (drawBrush != null) { drawBrush.Dispose(); } } }