static CssLineBox GetLine(HitInfo hitInfo) { switch (hitInfo.hitObjectKind) { default: case HitObjectKind.Unknown: { return null; throw new NotSupportedException(); } case HitObjectKind.LineBox: { return (CssLineBox)hitInfo.hitObject; } case HitObjectKind.Run: { return ((CssRun)hitInfo.hitObject).HostLine; } case HitObjectKind.CssBox: { return null; } } }
void SetupEndHitPoint(CssBoxHitChain startChain, CssBoxHitChain endChain, IHtmlTextService textService) { //find global location of end point HitInfo endHit = endChain.GetLastHit(); int xposOnEndLine = 0; CssLineBox endline = null; //find endline first _endHitRunCharIndex = 0; _endHitRun = null; switch (endHit.hitObjectKind) { default: { throw new NotSupportedException(); } case HitObjectKind.Run: { CssRun endRun = (CssRun)endHit.hitObject; #if DEBUG //if (endRun.Text != null && endRun.Text.Contains("Jose")) //{ //} if (endHit.localX > 23) { } System.Diagnostics.Debug.WriteLine(endHit.localX); #endif endRun.FindSelectionPoint(textService, endHit.localX, out int run_sel_index, out int run_sel_offset); endline = endRun.HostLine; xposOnEndLine = (int)(endRun.Left + run_sel_offset); _endHitRunCharIndex = run_sel_index; #if DEBUG System.Diagnostics.Debug.WriteLine(_endHitRunCharIndex); #endif _endHitRun = endRun; } break; case HitObjectKind.LineBox: { endline = (CssLineBox)endHit.hitObject; xposOnEndLine = endHit.localX; } break; case HitObjectKind.CssBox: { CssBox hitBox = (CssBox)endHit.hitObject; endline = FindNearestLine(hitBox, endChain.RootGlobalY, 5); xposOnEndLine = endHit.localX; } break; } #if DEBUG if (xposOnEndLine == 0) { } #endif //---------------------------------- _selectedLines = new List <CssLineBox>(); if (_startHitHostLine == endline) { _selectedLines.Add(endline); _startHitHostLine.Select(_startLineBeginSelectionAtPixel, xposOnEndLine, _startHitRun, _startHitRunCharIndex, _endHitRun, _endHitRunCharIndex); return; //early exit here *** } //---------------------------------- //select on different line LineWalkVisitor lineWalkVisitor = null; if (FindCommonGround(startChain, endChain, out int breakAtLevel) && breakAtLevel > 0) { //multiple select //1. first part if (endChain.GetHitInfo(breakAtLevel).hitObject is CssBlockRun hitBlockRun) { _startHitHostLine.Select(_startLineBeginSelectionAtPixel, (int)hitBlockRun.Left, _startHitRun, _startHitRunCharIndex, _endHitRun, _endHitRunCharIndex); _selectedLines.Add(_startHitHostLine); lineWalkVisitor = new LineWalkVisitor(hitBlockRun); } else { _startHitHostLine.SelectPartialToEnd(_startLineBeginSelectionAtPixel, _startHitRun, _startHitRunCharIndex); _selectedLines.Add(_startHitHostLine); lineWalkVisitor = new LineWalkVisitor(_startHitHostLine); } } else { _startHitHostLine.SelectPartialToEnd(_startLineBeginSelectionAtPixel, _startHitRun, _startHitRunCharIndex); _selectedLines.Add(_startHitHostLine); lineWalkVisitor = new LineWalkVisitor(_startHitHostLine); } lineWalkVisitor.SetWalkTargetPosition(endChain.RootGlobalX, endChain.RootGlobalY); #if DEBUG int dbugExpectedId = 1; #endif lineWalkVisitor.Walk(endline, (lineCoverage, linebox, partialLineRun) => { #if DEBUG //System.Diagnostics.Debug.WriteLine("sel:" + linebox.dbugId); if (dbugExpectedId != linebox.dbugId) { } dbugExpectedId++; #endif switch (lineCoverage) { case LineCoverage.EndLine: { //found end line linebox.SelectPartialFromStart(xposOnEndLine, _endHitRun, _endHitRunCharIndex); _selectedLines.Add(linebox); } break; case LineCoverage.PartialLine: { linebox.SelectPartialFromStart((int)partialLineRun.Right, _endHitRun, _endHitRunCharIndex); _selectedLines.Add(linebox); } break; case LineCoverage.FullLine: { //check if hitpoint is in the line area linebox.SelectFull(); _selectedLines.Add(linebox); } break; } }); }