X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/03647350fc7cd141953c72e0284e928847d30f44..a02b2a9d31b9ebc9cb13e0ea744169bc355e2ea0:/src/richtext/richtextprint.cpp diff --git a/src/richtext/richtextprint.cpp b/src/richtext/richtextprint.cpp index 2efffa46a5..b491ac947b 100644 --- a/src/richtext/richtextprint.cpp +++ b/src/richtext/richtextprint.cpp @@ -54,6 +54,7 @@ void wxRichTextPrintout::OnPreparePrinting() m_pageBreaksStart.Clear(); m_pageBreaksEnd.Clear(); + m_pageYOffsets.Clear(); int lastStartPos = 0; @@ -66,7 +67,8 @@ void wxRichTextPrintout::OnPreparePrinting() { GetRichTextBuffer()->Invalidate(wxRICHTEXT_ALL); - GetRichTextBuffer()->Layout(*GetDC(), rect, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT); + wxRichTextDrawingContext context(GetRichTextBuffer()); + GetRichTextBuffer()->Layout(*GetDC(), context, rect, rect, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT); // Now calculate the page breaks @@ -80,57 +82,69 @@ void wxRichTextPrintout::OnPreparePrinting() // child is a paragraph wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); wxASSERT (child != NULL); - - wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); - while (node2) + if (child) { - wxRichTextLine* line = node2->GetData(); + 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 - yOffset; + bool hasHardPageBreak = ((node2 == child->GetLines().GetFirst()) && child->GetAttributes().HasPageBreak()); - 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 - // 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) + { + // New page starting at this line + int newY = rect.y; - 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 - // We increase the offset by the difference between new and old positions + int increaseOffsetBy = lineY - newY; + yOffset += increaseOffsetBy; - int increaseOffsetBy = lineY - newY; - yOffset += increaseOffsetBy; + if (!lastLine) + lastLine = line; - line->SetPosition(wxPoint(line->GetPosition().x, newY - child->GetPosition().y)); + m_pageBreaksStart.Add(lastStartPos); + m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd()); + m_pageYOffsets.Add(yOffset); - if (!lastLine) + lastStartPos = line->GetAbsoluteRange().GetStart(); lastLine = line; - m_pageBreaksStart.Add(lastStartPos); - m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd()); + m_numPages ++; - lastStartPos = line->GetAbsoluteRange().GetStart(); + // 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_numPages ++; - } + m_pageBreaksStart.Add(lastStartPos); + m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd()); + m_pageYOffsets.Add(yOffset); + } + } - lastLine = line; + lastLine = line; - node2 = node2->GetNext(); + node2 = node2->GetNext(); + } } node = node->GetNext(); } // Closing page break - if (m_pageBreaksStart.GetCount() == 0 || (m_pageBreaksEnd[m_pageBreaksEnd.GetCount()-1] < (GetRichTextBuffer()->GetRange().GetEnd()-1))) + if (m_pageBreaksStart.GetCount() == 0 || (m_pageBreaksEnd[m_pageBreaksEnd.GetCount()-1] < (GetRichTextBuffer()->GetOwnRange().GetEnd()-1))) { m_pageBreaksStart.Add(lastStartPos); - m_pageBreaksEnd.Add(GetRichTextBuffer()->GetRange().GetEnd()); + m_pageBreaksEnd.Add(GetRichTextBuffer()->GetOwnRange().GetEnd()); + m_pageYOffsets.Add(yOffset); } } } @@ -181,11 +195,11 @@ void wxRichTextPrintout::RenderPage(wxDC *dc, int page) if (page > 1 || m_headerFooterData.GetShowOnFirstPage()) { - if (m_headerFooterData.GetFont().Ok()) + if (m_headerFooterData.GetFont().IsOk()) dc->SetFont(m_headerFooterData.GetFont()); else dc->SetFont(*wxNORMAL_FONT); - if (m_headerFooterData.GetTextColour().Ok()) + if (m_headerFooterData.GetTextColour().IsOk()) dc->SetTextForeground(m_headerFooterData.GetTextColour()); else dc->SetTextForeground(*wxBLACK); @@ -274,7 +288,26 @@ void wxRichTextPrintout::RenderPage(wxDC *dc, int page) 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 */); + 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); } void wxRichTextPrintout::SetMargins(int top, int bottom, int left, int right) @@ -312,7 +345,7 @@ void wxRichTextPrintout::CalculateScaling(wxDC* dc, wxRect& textRect, wxRect& he // The dimensions used for indentation etc. have to be unscaled // during printing to be correct when scaling is applied. - if (!IsPreview()) + // if (!IsPreview()) m_richTextBuffer->SetScale(scale); // Calculate margins @@ -340,7 +373,7 @@ void wxRichTextPrintout::CalculateScaling(wxDC* dc, wxRect& textRect, wxRect& he !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_CENTRE).IsEmpty() || !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_RIGHT).IsEmpty()) { - if (m_headerFooterData.GetFont().Ok()) + if (m_headerFooterData.GetFont().IsOk()) dc->SetFont(m_headerFooterData.GetFont()); else dc->SetFont(*wxNORMAL_FONT); @@ -365,7 +398,7 @@ void wxRichTextPrintout::CalculateScaling(wxDC* dc, wxRect& textRect, wxRect& he !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_CENTRE).IsEmpty() || !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_RIGHT).IsEmpty()) { - if (m_headerFooterData.GetFont().Ok()) + if (m_headerFooterData.GetFont().IsOk()) dc->SetFont(m_headerFooterData.GetFont()); else dc->SetFont(*wxNORMAL_FONT); @@ -444,7 +477,7 @@ void wxRichTextPrinting::SetPrintData(const wxPrintData& printData) (*GetPrintData()) = printData; } -void wxRichTextPrinting::SetPageSetupData(const wxPageSetupData& pageSetupData) +void wxRichTextPrinting::SetPageSetupData(const wxPageSetupDialogData& pageSetupData) { (*GetPageSetupData()) = pageSetupData; } @@ -539,7 +572,7 @@ bool wxRichTextPrinting::DoPreview(wxRichTextPrintout *printout1, wxRichTextPrin // Pass two printout objects: for preview, and possible printing. wxPrintDialogData printDialogData(*GetPrintData()); wxPrintPreview *preview = new wxPrintPreview(printout1, printout2, &printDialogData); - if (!preview->Ok()) + if (!preview->IsOk()) { delete preview; return false; @@ -570,7 +603,7 @@ bool wxRichTextPrinting::DoPrint(wxRichTextPrintout *printout) void wxRichTextPrinting::PageSetup() { - if (!GetPrintData()->Ok()) + if (!GetPrintData()->IsOk()) { wxLogError(_("There was a problem during page setup: you may need to set a default printer.")); return;