void TextFormatter::FormatPlainText(CFDC& dc, int& width, int& height, int fontsize, const wchar_t *text, int len, LineArray& lines) { lines.RemoveAll(); int save_width = m_width; bool save_justified = m_justified; m_width = width; m_justified = false; const wchar_t *top = text + len; Attr attr; attr.wa = 0; attr.fsize = fontsize; int curh = 0; while (text < top && curh < height) { const wchar_t *p_end = text; while (p_end < top && *p_end != '\r' && *p_end != '\n') ++p_end; Paragraph p(p_end - text); memcpy(p.str, text, (p_end - text)*sizeof(wchar_t)); for (int i = 0; i < p.cflags.size(); ++i) p.cflags[i].wa = attr.wa; p.findent = 3; // XXX int last = lines.GetSize(); FilePos fp = FilePos(); int lh = WrapLine(dc, p, fp, lines, curh, height - curh); if (lh < 0) { // it still might add something while (last < lines.GetSize()) curh += lines[last++].height; break; } curh += lh; while (p_end < top && (*p_end == '\r' || *p_end == '\n')) ++p_end; text = p_end; } m_width = save_width; m_justified = save_justified; // deduct ispace int min_ispace = -1, max_width = 0; for (int i = 0; i < lines.GetSize(); ++i) { const Line& ll = lines[i]; int w = 0; for (int j = 0; j < ll.dx.size(); ++j) w += ll.dx[j]; w += ll.ispace; if (max_width < w) max_width = w; if (min_ispace<0 || min_ispace>ll.ispace) min_ispace = ll.ispace; } if (min_ispace > 0) { for (int i = 0; i < lines.GetSize(); ++i) lines[i].ispace -= min_ispace; max_width -= min_ispace; } height = curh; width = max_width; }
bool TextFormatter::FormatBack(CFDC& dc, FilePos start, FilePos prev_top) { AdjustPos(start, true); if (start.para == 0 && start.off == 0) return false; // at the top m_lines.RemoveAll(); m_bot = start; for (int page = m_pages - 1; page >= 0; --page) { LineArray tmp; FilePos pos = start; int h = 0; // while there are still paragrahs before while (h < m_height && (pos.para>0 || pos.off > 0)) { // format entire paragraph LineArray cp; Paragraph para(m_tf->GetParagraph(pos.docid, pos.para)); if (pos.off < para.len) // double check args para.len = pos.off; else pos.off = para.len; FilePos fp = FilePos(pos.para, 0, pos.docid); WrapLine(dc, para, fp, cp, 0, 32768); // insert the formatted paragraph at start of list tmp.InsertAt(0, &cp); for (int i = 0; i < cp.GetSize(); ++i) h += cp[i].height; pos.off = 0; AdjustPos(pos, true); } // delete extra lines int j; // remove top lines for (h = 0, j = tmp.GetUpperBound(); j >= 0 && h + tmp[j].height <= m_height; --j) h += tmp[j].height; if (j < tmp.GetUpperBound()) { if (j >= 0 && prev_top != 0 && tmp[j + 1].pos >= prev_top) { --j; tmp.RemoveAt(0, j + 1); // now remove bottom lines for (h = j = 0; j < tmp.GetSize() && h + tmp[j].height <= m_height; ++j) h += tmp[j].height; if (j < tmp.GetSize()) tmp.RemoveAt(j, tmp.GetSize() - j); } else { tmp.RemoveAt(0, j + 1); } } // save lines m_lines.InsertAt(0, &tmp); m_pagelen.SetAtGrow(page, tmp.GetSize()); start = m_lines[0].pos; if (start.para == 0 && start.off == 0) // we reached the top of file return FormatFwd(dc, FilePos(0, 0, start.docid)); } // save positions m_top = m_lines[0].pos; Highlight(); // add one dummy line always Line l; l.pos = m_bot; m_lines.Add(l); return true; }