void SetupEndHitPoint(CssBoxHitChain startChain, CssBoxHitChain endChain, IFonts ifonts)
{
//find global location of end point
HitInfo endHit = endChain.GetLastHit();
int xposOnEndLine = 0;
CssLineBox endline = null;
int run_sel_offset = 0;
//find endline first
this.endHitRunCharIndex = 0;
this.endHitRun = null;
switch (endHit.hitObjectKind)
{
default:
{
throw new NotSupportedException();
}
case HitObjectKind.Run:
{
CssRun endRun = (CssRun)endHit.hitObject;
//if (endRun.Text != null && endRun.Text.Contains("Jose"))
//{
//}
int run_sel_index;
endRun.FindSelectionPoint(ifonts,
endHit.localX,
out run_sel_index,
out run_sel_offset);
endline = endRun.HostLine;
xposOnEndLine = (int)(endRun.Left + run_sel_offset);
this.endHitRunCharIndex = run_sel_index;
this.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
//----------------------------------
this.selectedLines = new List<CssLineBox>();
if (startHitHostLine == endline)
{
this.selectedLines.Add(endline);
startHitHostLine.Select(startLineBeginSelectionAtPixel, xposOnEndLine,
this.startHitRun, this.startHitRunCharIndex,
this.endHitRun, this.endHitRunCharIndex);
return; //early exit here ***
}
//----------------------------------
//select on different line
LineWalkVisitor lineWalkVisitor = null;
int breakAtLevel;
if (FindCommonGround(startChain, endChain, out breakAtLevel) && breakAtLevel > 0)
{
var hit1 = endChain.GetHitInfo(breakAtLevel).hitObject;
var hitBlockRun = hit1 as CssBlockRun;
//multiple select
//1. first part
if (hitBlockRun != null)
{
startHitHostLine.Select(startLineBeginSelectionAtPixel, (int)hitBlockRun.Left,
this.startHitRun, this.startHitRunCharIndex,
this.endHitRun, this.endHitRunCharIndex);
selectedLines.Add(this.startHitHostLine);
lineWalkVisitor = new LineWalkVisitor(hitBlockRun);
}
else
{
startHitHostLine.SelectPartialToEnd(startLineBeginSelectionAtPixel, this.startHitRun, this.startHitRunCharIndex);
selectedLines.Add(this.startHitHostLine);
lineWalkVisitor = new LineWalkVisitor(startHitHostLine);
}
}
else
{
startHitHostLine.SelectPartialToEnd(startLineBeginSelectionAtPixel, this.startHitRun, this.startHitRunCharIndex);
selectedLines.Add(this.startHitHostLine);
lineWalkVisitor = new LineWalkVisitor(startHitHostLine);
}
lineWalkVisitor.SetWalkTargetPosition(endChain.RootGlobalX, endChain.RootGlobalY);
lineWalkVisitor.Walk(endline, (lineCoverage, linebox, partialLineRun) =>
{
switch (lineCoverage)
{
case LineCoverage.EndLine:
{
//found end line
linebox.SelectPartialFromStart(xposOnEndLine, this.endHitRun, this.endHitRunCharIndex);
selectedLines.Add(linebox);
}
break;
case LineCoverage.PartialLine:
{
linebox.SelectPartialFromStart((int)partialLineRun.Right, this.endHitRun, this.endHitRunCharIndex);
selectedLines.Add(linebox);
}
break;
case LineCoverage.FullLine:
{
//check if hitpoint is in the line area
linebox.SelectFull();
selectedLines.Add(linebox);
}
break;
}
});
}
static bool FindCommonGround(CssBoxHitChain startChain, CssBoxHitChain endChain, out int breakAtLevel)