/* A fix for handling column cases TODO FIXME */ private void UpdateSelectionCol(System.Windows.Point pos, DocPage page) { bool new_page = true; TextLine start_line, end_line; double x = 0, y, w = 0, h; bool found_first = false; bool above_anchor = true; bool first_line_full = false; bool last_line_full = false; for (int kk = 0; kk < m_textSelect.Count; kk++) if (m_textSelect[kk].pagenum == page.PageNum) new_page = false; /* See if we have gone back to a previous page */ if (!new_page && page.PageNum != m_textSelect[m_textSelect.Count - 1].pagenum) { DocPage curr_page = m_docPages[m_textSelect[m_textSelect.Count - 1].pagenum]; curr_page.SelHeight = 0; curr_page.SelWidth = 0; m_textSelect.RemoveAt(m_textSelect.Count - 1); m_lineptrs[curr_page.PageNum].Clear(); curr_page.SelectedLines.Clear(); } if (new_page) { /* New page */ page.SelX = pos.X; page.SelY = pos.Y; page.SelAnchorX = m_docPages[m_textSelect[m_textSelect.Count - 1].pagenum].SelAnchorX; if (m_textSelect[m_textSelect.Count - 1].pagenum > page.PageNum) { page.SelAnchorY = page.Height; } else { page.SelAnchorY = 0; } page.SelColor = m_regionselect; textSelectInfo_t info = new textSelectInfo_t(); info.pagenum = page.PageNum; info.first_line_full = false; info.last_line_full = false; m_textSelect.Add(info); /* Create new holder for lines highlighted */ m_lineptrs[page.PageNum] = new LinesText(); } if (page.TextBlocks == null || page.TextBlocks.Count == 0) return; /* Width changes translate across the pages */ for (int jj = 0; jj < m_textSelect.Count; jj++) { DocPage curr_page = m_docPages[m_textSelect[jj].pagenum]; x = Math.Min(pos.X, curr_page.SelAnchorX); w = Math.Max(pos.X, curr_page.SelAnchorX) - x; curr_page.SelX = x; curr_page.SelWidth = w; } /* Height is just the current page */ y = Math.Min(pos.Y, page.SelAnchorY); h = Math.Max(pos.Y, page.SelAnchorY) - y; /* Determine if we are going up or down */ if (pos.Y > page.SelAnchorY) above_anchor = false; page.SelY = y; page.SelHeight = h; /* Clear out what we currently have */ m_lineptrs[page.PageNum].Clear(); /* Stuff already selected above us */ if (m_textSelect.Count > 1) found_first = true; /* Moving backwards through pages */ if (m_textSelect.Count > 1 && m_textSelect[m_textSelect.Count - 2].pagenum > page.PageNum) found_first = false; /* To properly handle the multiple columns we have to find the last * line and make sure that all blocks between our first and last * line are included. To do this we do an initial step through the * blocks looking at our intersections */ int first_block = -1; int last_block = -1; for (int jj = 0; jj < page.TextBlocks.Count; jj++ ) { var intersect_blk = page.TextBlocks[jj].CheckIntersection(x, y, w, h); if (intersect_blk == Intersection_t.NONE && first_block != -1) { last_block = jj; /* NB: this is just past last block */ break; } else if (intersect_blk != Intersection_t.NONE && first_block == -1) first_block = jj; /* NB: this is the first block */ } if (first_block == -1) return; if (last_block == -1) { /* Only 1 block */ last_block = first_block + 1; } for (int jj = first_block; jj < last_block; jj++) { /* Text blocks are already scaled. Lines are not */ var intersect_blk = page.TextBlocks[jj].CheckIntersection(x, y, w, h); var lines = page.TextBlocks[jj].TextLines; if (jj == first_block || jj == last_block - 1) { /* Partial cases */ if (intersect_blk == Intersection_t.FULL) { for (int kk = 0; kk < lines.Count; kk++) m_lineptrs[page.PageNum].Add(lines[kk]); if (jj == first_block) { first_line_full = true; found_first = true; } if (jj == last_block - 1) { last_line_full = true; } } else if (intersect_blk == Intersection_t.PARTIAL) { for (int kk = 0; kk < lines.Count; kk++) { double scale = m_doczoom / lines[kk].Scale; var intersect_line = lines[kk].CheckIntersection(x * scale, y * scale, w * scale, h * scale); if (intersect_line == Intersection_t.FULL) { m_lineptrs[page.PageNum].Add(lines[kk]); found_first = true; if (jj == 0 && kk == 0) first_line_full = true; if (jj == page.TextBlocks.Count - 1 && kk == lines.Count - 1) last_line_full = true; } else if (intersect_line == Intersection_t.PARTIAL) { double val; var lett = lines[kk].TextCharacters; /* Now go through the width. */ if (found_first) { if (above_anchor) val = page.SelAnchorX; else val = pos.X; /* our second partial line */ if (val > lines[kk].X * scale + lines[kk].Width * scale) m_lineptrs[page.PageNum].Add(lines[kk]); else { /* Use either anchor point or mouse pos */ end_line = new TextLine(); end_line.TextCharacters = new List<TextCharacter>(); end_line.Height = 0; end_line.Scale = m_doczoom; for (int mm = 0; mm < lett.Count; mm++) { double letscale = m_doczoom / lett[mm].Scale; if (lett[mm].X * letscale < val) { /* Can set to special color for debug */ end_line.Color = m_textselectcolor; /* special color for debug */ //end_line.Color = "#4000FF00"; end_line.Height = lines[kk].Height * scale; end_line.Width = lett[mm].X * letscale + lett[mm].Width * letscale - lines[kk].X * scale; end_line.Y = lines[kk].Y * scale; end_line.X = lines[kk].X * scale; end_line.TextCharacters.Add(lett[mm]); } else break; } if (end_line.Height != 0) m_lineptrs[page.PageNum].Add(end_line); } } else { if (!above_anchor) val = page.SelAnchorX; else val = pos.X; /* our first partial line */ found_first = true; if (val < lines[kk].X * scale) m_lineptrs[page.PageNum].Add(lines[kk]); else { start_line = new TextLine(); start_line.TextCharacters = new List<TextCharacter>(); start_line.Height = 0; start_line.Scale = m_doczoom; /* Use either anchor point or mouse pos */ for (int mm = 0; mm < lett.Count; mm++) { double letscale = m_doczoom / lett[mm].Scale; if (lett[mm].X * letscale + lett[mm].Width * letscale >= val) { start_line.Color = m_textselectcolor; /* special color for debug */ //start_line.Color = "#40FF0000"; start_line.Height = lines[kk].Height * scale; start_line.Width = lines[kk].X * scale + lines[kk].Width * scale - lett[mm].X * letscale; start_line.X = lett[mm].X * letscale; start_line.Y = lines[kk].Y * scale; start_line.TextCharacters.Add(lett[mm]); break; } } if (start_line.Height > 0) m_lineptrs[page.PageNum].Add(start_line); } } } } } } else { /* Add all the lines for the blocks between the first and last */ for (int kk = 0; kk < lines.Count; kk++) m_lineptrs[page.PageNum].Add(lines[kk]); } } var txtsel = m_textSelect[m_textSelect.Count - 1]; txtsel.first_line_full = first_line_full; txtsel.last_line_full = last_line_full; m_textSelect[m_textSelect.Count - 1] = txtsel; /* Adjust for scale before assigning */ var temp = m_lineptrs[page.PageNum]; for (int kk = 0; kk < temp.Count; kk++) { var rect_item = temp[kk]; double factor = m_doczoom / rect_item.Scale; temp[kk].Height = temp[kk].Height * factor; temp[kk].Width = temp[kk].Width * factor; temp[kk].X = temp[kk].X * factor; temp[kk].Y = temp[kk].Y * factor; temp[kk].Scale = m_doczoom; } page.SelectedLines = m_lineptrs[page.PageNum]; }
private void InitTextSelection(DocPage page) { if (m_textSelect != null) ClearSelections(); else m_textSelect = new List<textSelectInfo_t>(); m_intxtselect = true; textSelectInfo_t selinfo = new textSelectInfo_t(); selinfo.pagenum = page.PageNum; selinfo.first_line_full = false; selinfo.last_line_full = false; m_textSelect.Add(selinfo); }