void wxRichTextPrintout::OnPreparePrinting() { wxBusyCursor wait; m_numPages = 1; m_pageBreaksStart.Clear(); m_pageBreaksEnd.Clear(); int lastStartPos = 0; wxRect rect, headerRect, footerRect; /// Sets the DC scaling and returns important page rectangles CalculateScaling(GetDC(), rect, headerRect, footerRect); if (GetRichTextBuffer()) { GetRichTextBuffer()->Invalidate(wxRICHTEXT_ALL); GetRichTextBuffer()->Layout(*GetDC(), rect, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT); // Now calculate the page breaks int yOffset = 0; wxRichTextLine* lastLine = NULL; wxRichTextObjectList::compatibility_iterator node = GetRichTextBuffer()->GetChildren().GetFirst(); while (node) { // child is a paragraph wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); wxASSERT (child != NULL); wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); while (node2) { wxRichTextLine* line = node2->GetData(); // Set the line to the page-adjusted position line->SetPosition(wxPoint(line->GetPosition().x, line->GetPosition().y - yOffset)); int lineY = child->GetPosition().y + line->GetPosition().y; // Break the page if either we're going off the bottom, or this paragraph specifies // an explicit page break if (((lineY + line->GetSize().y) > rect.GetBottom()) || ((node2 == child->GetLines().GetFirst()) && child->GetAttributes().HasPageBreak())) { // New page starting at this line int newY = rect.y; // We increase the offset by the difference between new and old positions int increaseOffsetBy = lineY - newY; yOffset += increaseOffsetBy; line->SetPosition(wxPoint(line->GetPosition().x, newY - child->GetPosition().y)); if (!lastLine) lastLine = line; m_pageBreaksStart.Add(lastStartPos); m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd()); lastStartPos = line->GetAbsoluteRange().GetStart(); m_numPages ++; } lastLine = line; node2 = node2->GetNext(); } node = node->GetNext(); } // Closing page break if (m_pageBreaksStart.GetCount() == 0 || (m_pageBreaksEnd[m_pageBreaksEnd.GetCount()-1] < (GetRichTextBuffer()->GetRange().GetEnd()-1))) { m_pageBreaksStart.Add(lastStartPos); m_pageBreaksEnd.Add(GetRichTextBuffer()->GetRange().GetEnd()); } } }
void wxRichTextPrintout::OnPreparePrinting() { wxBusyCursor wait; m_numPages = 1; m_pageBreaksStart.Clear(); m_pageBreaksEnd.Clear(); m_pageYOffsets.Clear(); int lastStartPos = 0; wxRect rect, headerRect, footerRect; /// Sets the DC scaling and returns important page rectangles CalculateScaling(GetDC(), rect, headerRect, footerRect); if (GetRichTextBuffer()) { GetRichTextBuffer()->Invalidate(wxRICHTEXT_ALL); wxRichTextDrawingContext context(GetRichTextBuffer()); GetRichTextBuffer()->Layout(*GetDC(), context, rect, rect, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT); // Now calculate the page breaks int yOffset = 0; wxRichTextLine* lastLine = NULL; wxRichTextObjectList::compatibility_iterator node = GetRichTextBuffer()->GetChildren().GetFirst(); while (node) { // child is a paragraph wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); wxASSERT (child != NULL); if (child) { wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); while (node2) { wxRichTextLine* line = node2->GetData(); int lineY = child->GetPosition().y + line->GetPosition().y - yOffset; bool hasHardPageBreak = ((node2 == child->GetLines().GetFirst()) && child->GetAttributes().HasPageBreak()); // Break the page if either we're going off the bottom, or this paragraph specifies // an explicit page break if (((lineY + line->GetSize().y) > rect.GetBottom()) || hasHardPageBreak) { // Only if we're not at the start of the document, and // even then, only if either it's a hard break or if the object // can fit in a whole page (otherwise there's no point in making // the rest of this page blank). if (lastLine && (hasHardPageBreak || (line->GetSize().y <= rect.GetHeight()))) { // New page starting at this line int newY = rect.y; // We increase the offset by the difference between new and old positions int increaseOffsetBy = lineY - newY; yOffset += increaseOffsetBy; m_pageBreaksStart.Add(lastStartPos); m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd()); m_pageYOffsets.Add(yOffset); lastStartPos = line->GetAbsoluteRange().GetStart(); m_numPages ++; } lastLine = line; // Now create page breaks for the rest of the line, if it's larger than the page height int contentLeft = line->GetSize().y - rect.GetHeight(); while (contentLeft >= 0) { yOffset += rect.GetHeight(); contentLeft -= rect.GetHeight(); m_pageBreaksStart.Add(lastStartPos); m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd()); m_pageYOffsets.Add(yOffset); m_numPages ++; } } lastLine = line; node2 = node2->GetNext(); } } node = node->GetNext(); } // Closing page break m_pageBreaksStart.Add(lastStartPos); m_pageBreaksEnd.Add(GetRichTextBuffer()->GetOwnRange().GetEnd()); m_pageYOffsets.Add(yOffset); } }
void wxRichTextPrintout::RenderPage(wxDC *dc, int page) { if (!GetRichTextBuffer()) return; wxBusyCursor wait; wxRect textRect, headerRect, footerRect; /// Sets the DC scaling and returns important page rectangles CalculateScaling(dc, textRect, headerRect, footerRect); if (page > 1 || m_headerFooterData.GetShowOnFirstPage()) { if (m_headerFooterData.GetFont().Ok()) dc->SetFont(m_headerFooterData.GetFont()); else dc->SetFont(*wxNORMAL_FONT); if (m_headerFooterData.GetTextColour().Ok()) dc->SetTextForeground(m_headerFooterData.GetTextColour()); else dc->SetTextForeground(*wxBLACK); dc->SetBackgroundMode(wxTRANSPARENT); // Draw header, if any wxRichTextOddEvenPage oddEven = ((page % 2) == 1) ? wxRICHTEXT_PAGE_ODD : wxRICHTEXT_PAGE_EVEN; wxString headerTextCentre = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_CENTRE); wxString headerTextLeft = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_LEFT); wxString headerTextRight = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_RIGHT); if (!headerTextLeft.IsEmpty()) { SubstituteKeywords(headerTextLeft, GetTitle(), page, m_numPages); //int tx, ty; //dc->GetTextExtent(headerTextLeft, & tx, & ty); int x = headerRect.GetLeft(); int y = headerRect.GetX(); dc->DrawText(headerTextLeft, x, y); } if (!headerTextCentre.IsEmpty()) { SubstituteKeywords(headerTextCentre, GetTitle(), page, m_numPages); int tx, ty; dc->GetTextExtent(headerTextCentre, & tx, & ty); int x = headerRect.GetWidth()/2 - tx/2 + headerRect.GetLeft(); int y = headerRect.GetY(); dc->DrawText(headerTextCentre, x, y); } if (!headerTextRight.IsEmpty()) { SubstituteKeywords(headerTextRight, GetTitle(), page, m_numPages); int tx, ty; dc->GetTextExtent(headerTextRight, & tx, & ty); int x = headerRect.GetRight() - tx; int y = headerRect.GetY(); dc->DrawText(headerTextRight, x, y); } // Draw footer, if any wxString footerTextCentre = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_CENTRE); wxString footerTextLeft = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_LEFT); wxString footerTextRight = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_RIGHT); if (!footerTextLeft.IsEmpty()) { SubstituteKeywords(footerTextLeft, GetTitle(), page, m_numPages); int tx, ty; dc->GetTextExtent(footerTextLeft, & tx, & ty); int x = footerRect.GetLeft(); int y = footerRect.GetBottom() - ty; dc->DrawText(footerTextLeft, x, y); } if (!footerTextCentre.IsEmpty()) { SubstituteKeywords(footerTextCentre, GetTitle(), page, m_numPages); int tx, ty; dc->GetTextExtent(footerTextCentre, & tx, & ty); int x = footerRect.GetWidth()/2 - tx/2 + footerRect.GetLeft(); int y = footerRect.GetBottom() - ty; dc->DrawText(footerTextCentre, x, y); } if (!footerTextRight.IsEmpty()) { SubstituteKeywords(footerTextRight, GetTitle(), page, m_numPages); int tx, ty; dc->GetTextExtent(footerTextRight, & tx, & ty); int x = footerRect.GetRight() - tx; int y = footerRect.GetBottom() - ty; dc->DrawText(footerTextRight, x, y); } } wxRichTextRange rangeToDraw(m_pageBreaksStart[page-1], m_pageBreaksEnd[page-1]); GetRichTextBuffer()->Draw(*dc, rangeToDraw, wxRichTextRange(-1,-1), textRect, 0 /* descent */, wxRICHTEXT_DRAW_IGNORE_CACHE /* flags */); }
void wxRichTextPrintout::RenderPage(wxDC *dc, int page) { if (!GetRichTextBuffer()) return; wxBusyCursor wait; wxRect textRect, headerRect, footerRect; /// Sets the DC scaling and returns important page rectangles CalculateScaling(dc, textRect, headerRect, footerRect); if (page > 1 || m_headerFooterData.GetShowOnFirstPage()) { if (m_headerFooterData.GetFont().IsOk()) dc->SetFont(m_headerFooterData.GetFont()); else dc->SetFont(*wxNORMAL_FONT); if (m_headerFooterData.GetTextColour().IsOk()) dc->SetTextForeground(m_headerFooterData.GetTextColour()); else dc->SetTextForeground(*wxBLACK); dc->SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); // Draw header, if any wxRichTextOddEvenPage oddEven = ((page % 2) == 1) ? wxRICHTEXT_PAGE_ODD : wxRICHTEXT_PAGE_EVEN; wxString headerTextCentre = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_CENTRE); wxString headerTextLeft = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_LEFT); wxString headerTextRight = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_RIGHT); if (!headerTextLeft.IsEmpty()) { SubstituteKeywords(headerTextLeft, GetTitle(), page, m_numPages); //int tx, ty; //dc->GetTextExtent(headerTextLeft, & tx, & ty); int x = headerRect.GetLeft(); int y = headerRect.GetX(); dc->DrawText(headerTextLeft, x, y); } if (!headerTextCentre.IsEmpty()) { SubstituteKeywords(headerTextCentre, GetTitle(), page, m_numPages); int tx, ty; dc->GetTextExtent(headerTextCentre, & tx, & ty); int x = headerRect.GetWidth()/2 - tx/2 + headerRect.GetLeft(); int y = headerRect.GetY(); dc->DrawText(headerTextCentre, x, y); } if (!headerTextRight.IsEmpty()) { SubstituteKeywords(headerTextRight, GetTitle(), page, m_numPages); int tx, ty; dc->GetTextExtent(headerTextRight, & tx, & ty); int x = headerRect.GetRight() - tx; int y = headerRect.GetY(); dc->DrawText(headerTextRight, x, y); } // Draw footer, if any wxString footerTextCentre = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_CENTRE); wxString footerTextLeft = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_LEFT); wxString footerTextRight = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_RIGHT); if (!footerTextLeft.IsEmpty()) { SubstituteKeywords(footerTextLeft, GetTitle(), page, m_numPages); int tx, ty; dc->GetTextExtent(footerTextLeft, & tx, & ty); int x = footerRect.GetLeft(); int y = footerRect.GetBottom() - ty; dc->DrawText(footerTextLeft, x, y); } if (!footerTextCentre.IsEmpty()) { SubstituteKeywords(footerTextCentre, GetTitle(), page, m_numPages); int tx, ty; dc->GetTextExtent(footerTextCentre, & tx, & ty); int x = footerRect.GetWidth()/2 - tx/2 + footerRect.GetLeft(); int y = footerRect.GetBottom() - ty; dc->DrawText(footerTextCentre, x, y); } if (!footerTextRight.IsEmpty()) { SubstituteKeywords(footerTextRight, GetTitle(), page, m_numPages); int tx, ty; dc->GetTextExtent(footerTextRight, & tx, & ty); int x = footerRect.GetRight() - tx; int y = footerRect.GetBottom() - ty; dc->DrawText(footerTextRight, x, y); } } wxRichTextRange rangeToDraw(m_pageBreaksStart[page-1], m_pageBreaksEnd[page-1]); wxPoint oldOrigin = dc->GetLogicalOrigin(); double scaleX, scaleY; dc->GetUserScale(& scaleX, & scaleY); int yOffset = 0; if (page > 1) yOffset = m_pageYOffsets[page-2]; if (yOffset != oldOrigin.y) dc->SetLogicalOrigin(oldOrigin.x, oldOrigin.y + yOffset); dc->SetClippingRegion(wxRect(textRect.x, textRect.y + yOffset, textRect.width, textRect.height)); wxRichTextDrawingContext context(GetRichTextBuffer()); GetRichTextBuffer()->Draw(*dc, context, rangeToDraw, wxRichTextSelection(), textRect, 0 /* descent */, wxRICHTEXT_DRAW_IGNORE_CACHE|wxRICHTEXT_DRAW_PRINT /* flags */); dc->DestroyClippingRegion(); if (yOffset != oldOrigin.y) dc->SetLogicalOrigin(oldOrigin.x, oldOrigin.y); }