GDIHitTestMetrics HitTestPoint(PointF pt, out bool isTrailingHit) { GDIHitTestMetrics hitTextMetrics = new GDIHitTestMetrics(); int pos = 0; GDIHitTestMetrics m; isTrailingHit = false; // if (txtHitRect.Count == 0) { bool ret = CreateHwnd(); if (ret == false) { return(hitTextMetrics); } SizeF sizeF; if (g != null) { sizeF = g.MeasureString("x", ForeFont); } else { sizeF = TextRenderer.MeasureText("x", ForeFont); } hitTextMetrics = new GDIHitTestMetrics() { TextPosition = pos, Left = 0, Top = 0, Width = 1, Height = sizeF.Height, Length = 1 }; return(hitTextMetrics); } //if (rowMetricsList == null) rowMetricsList = ComputeRowMetricsList(); // float h = rowMetricsList[rowMetricsList.Count() - 1].Top + rowMetricsList[rowMetricsList.Count() - 1].Height; for (int i = 0; i < rowMetricsList.Count(); i++) { m = rowMetricsList[i]; if ((pt.Y >= m.Top && pt.Y <= (m.Top + m.Height)) || pt.Y < rowMetricsList[0].Top || pt.Y > h) { if (pt.Y < rowMetricsList[0].Top) { m = rowMetricsList[0]; } else if (pt.Y > h) { m = rowMetricsList[rowMetricsList.Count() - 1]; } if (pt.X >= m.Left && pt.X <= (m.Left + m.Width)) { for (int j = m.TextPosition; j < m.TextPosition + m.Length; j++) { if (pt.X >= txtHitRect[j].Left && pt.X <= (txtHitRect[j].Left + txtHitRect[j].Width)) { float a = pt.X - txtHitRect[j].Left; float b = txtHitRect[j].Right - pt.X; if (a <= b) { isTrailingHit = false; } else { isTrailingHit = true; } pos = j; break; } } } else if (pt.X < m.Left) { pos = m.TextPosition; isTrailingHit = false; break; } else { pos = m.TextPosition + m.Length - 1; isTrailingHit = true; break; } } } hitTextMetrics = new GDIHitTestMetrics() { TextPosition = pos, Left = txtHitRect[pos].Left, Top = txtHitRect[pos].Top, Width = txtHitRect[pos].Width, Height = txtHitRect[pos].Height, Length = 1 }; return(hitTextMetrics); }
GDIHitTestMetrics[] ComputeRowMetricsList() { RectangleF baseRect = txtHitRect[0]; GDIHitTestMetrics hitTestMetrics = new GDIHitTestMetrics(); int startPos = 0; List <GDIHitTestMetrics> rowMetricsSet = new List <GDIHitTestMetrics>(); RectangleF rect; for (int i = 0; i < txtHitRect.Count(); i++) { rect = txtHitRect[i]; if ((rect.Top >= baseRect.Top && rect.Top < baseRect.Bottom) || (rect.Bottom >= baseRect.Bottom && rect.Bottom < baseRect.Top)) { if (rect.Top < baseRect.Top) { baseRect.Y = rect.Top; baseRect.Height += baseRect.Top - rect.Top; } if (rect.Bottom > baseRect.Bottom) { baseRect.Height += rect.Bottom - baseRect.Bottom; } baseRect.Width = rect.Right - baseRect.Left; } else { hitTestMetrics = new GDIHitTestMetrics() { TextPosition = startPos, Left = baseRect.Left, Top = baseRect.Top, Width = baseRect.Width, Height = baseRect.Height, Length = i - startPos }; rowMetricsSet.Add(hitTestMetrics); startPos = i; baseRect = txtHitRect[i]; } } hitTestMetrics = new GDIHitTestMetrics() { TextPosition = startPos, Left = baseRect.Left, Top = baseRect.Top, Width = baseRect.Width, Height = baseRect.Height, Length = txtHitRect.Count() - startPos }; rowMetricsSet.Add(hitTestMetrics); return(rowMetricsSet.ToArray()); }
GDIHitTestMetrics[] HitTestTextRange(int textPosition, int textLength) { RectangleF baseRect; RectangleF rect; List <GDIHitTestMetrics> hitTextMetricsList = new List <GDIHitTestMetrics>(); GDIHitTestMetrics hitTextMetrics; int startPos; if (txtHitRect.Count == 0) { SizeF sizeF; if (g != null) { sizeF = g.MeasureString("x", ForeFont); } else { sizeF = TextRenderer.MeasureText("x", ForeFont); } hitTextMetrics = new GDIHitTestMetrics() { TextPosition = 0, Left = 0, Top = 0, Width = 1, Height = sizeF.Height, Length = 1 }; hitTextMetricsList.Add(hitTextMetrics); return(hitTextMetricsList.ToArray()); } if (textPosition >= txtHitRect.Count) { textPosition = txtHitRect.Count() - 1; } if (textPosition < 0) { textPosition = 0; } baseRect = txtHitRect[textPosition]; startPos = textPosition; // for (int i = textPosition - 1; i >= 0; i--) { rect = txtHitRect[i]; if ((rect.Top >= baseRect.Top && rect.Top < baseRect.Bottom) || (rect.Bottom >= baseRect.Bottom && rect.Bottom < baseRect.Top)) { if (rect.Top < baseRect.Top) { baseRect.Y = rect.Top; baseRect.Height += baseRect.Top - rect.Top; } if (rect.Bottom > baseRect.Bottom) { baseRect.Height += rect.Bottom - baseRect.Bottom; } } } // for (int i = textPosition + 1; i < textLength + textPosition; i++) { rect = txtHitRect[i]; if ((rect.Top >= baseRect.Top && rect.Top < baseRect.Bottom) || (rect.Bottom >= baseRect.Bottom && rect.Bottom < baseRect.Top)) { if (rect.Top < baseRect.Top) { baseRect.Y = rect.Top; baseRect.Height += baseRect.Top - rect.Top; } if (rect.Bottom > baseRect.Bottom) { baseRect.Height += rect.Bottom - baseRect.Bottom; } baseRect.Width = rect.Right - baseRect.Left; } else { hitTextMetrics = new GDIHitTestMetrics() { TextPosition = startPos, Left = baseRect.Left, Top = baseRect.Top, Width = baseRect.Width, Height = baseRect.Height, Length = i - startPos + 1 }; hitTextMetricsList.Add(hitTextMetrics); startPos = i; baseRect = txtHitRect[i]; } } // for (int i = textLength + textPosition; i < txtHitRect.Count(); i++) { rect = txtHitRect[i]; if ((rect.Top >= baseRect.Top && rect.Top < baseRect.Bottom) || (rect.Bottom >= baseRect.Bottom && rect.Bottom < baseRect.Top)) { if (rect.Top < baseRect.Top) { baseRect.Y = rect.Top; baseRect.Height += baseRect.Top - rect.Top; } if (rect.Bottom > baseRect.Bottom) { baseRect.Height += rect.Bottom - baseRect.Bottom; } } else { break; } } hitTextMetrics = new GDIHitTestMetrics() { TextPosition = startPos, Left = baseRect.Left, Top = baseRect.Top, Width = baseRect.Width, Height = baseRect.Height, Length = textLength + textPosition - startPos }; hitTextMetricsList.Add(hitTextMetrics); return(hitTextMetricsList.ToArray()); }