Skip to content

Commit

Permalink
More work on Gtk text window printing
Browse files Browse the repository at this point in the history
  • Loading branch information
Blake-Madden committed Sep 14, 2023
1 parent b8ae287 commit 9913948
Show file tree
Hide file tree
Showing 4 changed files with 322 additions and 128 deletions.
144 changes: 69 additions & 75 deletions src/ui/controls/formattedtextctrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,67 +388,6 @@ void FormattedTextCtrl::OnPrint([[maybe_unused]] wxCommandEvent& event)
wxDELETE(dc);
wxDELETE(printOut);
#elif defined(__WXGTK__)
// format the header
//wxString headerText;
//if (GetLeftPrinterHeader().length() ||
// GetCenterPrinterHeader().length() ||
// GetRightPrinterHeader().length())
// {
// headerText = L"<table style=\"width:100%;\"><tr><td width=\"33%\">" +
// GetLeftPrinterHeader() + L"</td>";
// headerText += L"<td width=\"33%\" align=\"center\">" +
// GetCenterPrinterHeader() + L"</td>";
// headerText += L"<td width=\"33%\" align=\"right\">" +
// GetRightPrinterHeader() + L"</td></tr></table>";
// }
//// format the footer
//wxString footerText;
//if (GetLeftPrinterFooter().length() ||
// GetCenterPrinterFooter().length() ||
// GetRightPrinterFooter().length())
// {
// footerText = "<table style=\"width:100%;\"><tr><td width=\"33%\">" +
// GetLeftPrinterFooter() + L"</td>";
// footerText += "<td width=\"33%\" align=\"center\">" +
// GetCenterPrinterFooter() + L"</td>";
// footerText += "<td width=\"33%\" align=\"right\">" +
// GetRightPrinterFooter() + "</td></tr></table>";
// }

//wxString outputText = GetUnthemedFormattedTextHtml();
//wxHtmlPrintout* printOut = new wxHtmlPrintout(GetTitleName());
//printOut->SetHtmlText(outputText);
//if (headerText.length())
// { printOut->SetHeader(headerText); }
//if (footerText.length())
// { printOut->SetFooter(footerText); }

//wxPrinter printer;
//if (m_printData)
// {
// printer.GetPrintDialogData().SetPrintData(*m_printData);
// }
//printer.GetPrintDialogData().SetAllPages(true);
//printer.GetPrintDialogData().SetFromPage(1);
//printer.GetPrintDialogData().SetMinPage(1);
//printer.GetPrintDialogData().EnableSelection(false);
//if (!printer.Print(this, printOut, true) )
// {
// // just show a message if a real error occurred.
// // They may have just cancelled.
// if (printer.GetLastError() == wxPRINTER_ERROR)
// {
// wxMessageBox(_(L"An error occurred while printing.\n"
// "Your default printer may not be set correctly."),
// _(L"Print"), wxOK|wxICON_QUESTION);
// }
// }
//if (m_printData)
// {
// *m_printData = printer.GetPrintDialogData().GetPrintData();
// }
//wxDELETE(printOut);

// UNDER CONSTRUCTION!!!
if (m_printData)
{
Expand All @@ -465,11 +404,66 @@ void FormattedTextCtrl::OnPrint([[maybe_unused]] wxCommandEvent& event)
}
}
const wxSize paperSize = wxThePrintPaperDatabase->GetSize(m_printData->GetPaperId());
const double PaperWidthInInches = (paperSize.GetWidth() / 10) * 0.0393700787;
const double PaperHeightInInches = (paperSize.GetHeight() / 10) * 0.0393700787;
const double paperWidthInInches = (paperSize.GetWidth() / 10) * 0.0393700787;
const double paperHeightInInches = (paperSize.GetHeight() / 10) * 0.0393700787;

GtkPrintOperation* operation = gtk_print_operation_new();

GtkPrintSettings* settings = gtk_print_settings_new();
gtk_print_settings_set_paper_width(settings, paperWidthInInches, GTK_UNIT_INCH);
gtk_print_settings_set_paper_height(settings, paperHeightInInches, GTK_UNIT_INCH);
if (m_printData)
{
gtk_print_settings_set_orientation(settings,
(m_printData->GetOrientation() == wxLANDSCAPE ?
GTK_PAGE_ORIENTATION_LANDSCAPE : GTK_PAGE_ORIENTATION_PORTRAIT));
gtk_print_settings_set_n_copies(settings, m_printData->GetNoCopies());
}
gtk_print_operation_set_print_settings(operation, settings);

_GtkPrintData printData;
printData.m_markupContent = GetUnthemedFormattedText().utf8_string();

printData.m_leftPrintHeader = ExpandUnixPrintString(GetLeftPrinterHeader());
printData.m_centerPrintHeader = ExpandUnixPrintString(GetCenterPrinterHeader());
printData.m_rightPrintHeader = ExpandUnixPrintString(GetRightPrinterHeader());
printData.m_leftPrintFooter = ExpandUnixPrintString(GetLeftPrinterFooter());
printData.m_centerPrintFooter = ExpandUnixPrintString(GetCenterPrinterFooter());
printData.m_rightPrintFooter = ExpandUnixPrintString(GetRightPrinterFooter());

g_signal_connect(G_OBJECT(operation), "begin-print",
G_CALLBACK(_GtkBeginPrint), static_cast<gpointer>(&printData));
g_signal_connect(G_OBJECT(operation), "draw-page",
G_CALLBACK(_GtkDrawPage), static_cast<gpointer>(&printData));
g_signal_connect(G_OBJECT(operation), "end-print",
G_CALLBACK(_GtkEndPrint), static_cast<gpointer>(&printData));

GError* error{ nullptr };
const gint printResult = gtk_print_operation_run(operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
GTK_WINDOW(GetHandle()), &error);

if (printResult == GTK_PRINT_OPERATION_RESULT_APPLY)
{
if (settings != nullptr)
{ g_object_unref(settings); }
settings = g_object_ref(gtk_print_operation_get_print_settings(operation));
m_printData->SetNoCopies(gtk_print_settings_get_n_copies(settings));
m_printData->SetOrientation(
(gtk_print_settings_get_orientation(settings) == GTK_PAGE_ORIENTATION_LANDSCAPE) ?
wxLANDSCAPE : wxPORTRAIT);
}
else if (error)
{
wxMessageBox(wxString::Format(
_(L"An error occurred while printing.\n%s"),
error->message),
_(L"Print"), wxOK|wxICON_QUESTION);

g_error_free(error);
}

GtkPrinter printer;
printer.Paginate(GetUnthemedFormattedText().utf8_str(), wxSize(PaperWidthInInches*96, PaperHeightInInches*96));
g_object_unref(operation);
g_object_unref(settings);
#else
const wxSize paperSize = wxThePrintPaperDatabase->GetSize(m_printData->GetPaperId());
const double PaperWidthInInches = (paperSize.GetWidth()/10) * 0.0393700787;
Expand All @@ -487,9 +481,9 @@ void FormattedTextCtrl::OnPrint([[maybe_unused]] wxCommandEvent& event)
safe_divide<size_t>((PaperHeightInInches- .5f) * 72, textWidth);

// format the header
wxString expandedLeftHeader = ExpandMacPrintString(GetLeftPrinterHeader());
wxString expandedCenterHeader = ExpandMacPrintString(GetCenterPrinterHeader());
wxString expandedRightHeader = ExpandMacPrintString(GetRightPrinterHeader());
wxString expandedLeftHeader = ExpandUnixPrintString(GetLeftPrinterHeader());
wxString expandedCenterHeader = ExpandUnixPrintString(GetCenterPrinterHeader());
wxString expandedRightHeader = ExpandUnixPrintString(GetRightPrinterHeader());

wxString fullHeader = expandedLeftHeader;
if (spacesCount >=
Expand All @@ -509,9 +503,9 @@ void FormattedTextCtrl::OnPrint([[maybe_unused]] wxCommandEvent& event)
}

// format the footer
wxString expandedLeftFooter = ExpandMacPrintString(GetLeftPrinterFooter());
wxString expandedCenterFooter = ExpandMacPrintString(GetCenterPrinterFooter());
wxString expandedRightFooter = ExpandMacPrintString(GetRightPrinterFooter());
wxString expandedLeftFooter = ExpandUnixPrintString(GetLeftPrinterFooter());
wxString expandedCenterFooter = ExpandUnixPrintString(GetCenterPrinterFooter());
wxString expandedRightFooter = ExpandUnixPrintString(GetRightPrinterFooter());

wxString fullFooter = expandedLeftFooter;
if (spacesCount >=
Expand Down Expand Up @@ -1464,10 +1458,10 @@ wxString FormattedTextCtrl::GtkGetFormattedText(const GtkFormat format, const bo
GSList* tags = gtk_text_iter_get_toggled_tags(&start, true);
wxString firstTag;
if (format == GtkFormat::HtmlFormat)
{ firstTag = GtkTextTagToHtmlSpanTag(GTK_TEXT_TAG(tags->data)); }
{ firstTag = _GtkTextTagToHtmlSpanTag(GTK_TEXT_TAG(tags->data)); }
else
{
firstTag = GtkTextTagToRtfTag(GTK_TEXT_TAG(tags->data), colorTable, fontTable);
firstTag = _GtkTextTagToRtfTag(GTK_TEXT_TAG(tags->data), colorTable, fontTable);
// just get the font family. The face name in Pango includes other
// descriptives strings that we don't use here
g_object_get(G_OBJECT(tags->data),
Expand Down Expand Up @@ -1500,9 +1494,9 @@ wxString FormattedTextCtrl::GtkGetFormattedText(const GtkFormat format, const bo
if (gtk_text_iter_starts_tag(&start, tag))
{
if (format == GtkFormat::HtmlFormat)
{ currentTagText += GtkTextTagToHtmlSpanTag(tag); }
{ currentTagText += _GtkTextTagToHtmlSpanTag(tag); }
else
{ currentTagText += GtkTextTagToRtfTag(tag, colorTable, fontTable); }
{ currentTagText += _GtkTextTagToRtfTag(tag, colorTable, fontTable); }
}
// any tags at the current iterator that might end a formatting block
// (there might be more than one, though unlikely)
Expand Down
4 changes: 1 addition & 3 deletions src/ui/controls/formattedtextctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,8 @@ class FormattedTextCtrl final : public wxTextCtrl
{ return m_waterMark; }
/// @}
private:
#ifdef __WXOSX__
[[nodiscard]]
wxString ExpandMacPrintString(const wxString& printString) const
wxString ExpandUnixPrintString(const wxString& printString) const
{
const wxDateTime now = wxDateTime::Now();
wxString expandedString = printString;
Expand All @@ -369,7 +368,6 @@ class FormattedTextCtrl final : public wxTextCtrl

return expandedString;
}
#endif
#ifdef __WXGTK__
enum class GtkFormat
{
Expand Down
41 changes: 4 additions & 37 deletions src/ui/controls/gtk/gtktextview-helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@

#ifdef __WXGTK__

//-------------------------------------------------
constexpr wxColourBase::ChannelType FloatingPointChannelToByteChannel(const double val)
{ return static_cast<wxColourBase::ChannelType>(std::floor(val >= 1.0 ? 255 : val * 256.0)); }

//-------------------------------------------------
constexpr GdkRGBA PangoAttributeToGdkRGBA(const PangoAttribute* attr)
{
return GdkRGBA
Expand All @@ -26,41 +28,6 @@ constexpr GdkRGBA PangoAttributeToGdkRGBA(const PangoAttribute* attr)
};
}

//-------------------------------------------------
void GtkPrinter::Paginate(const gchar* markup, const wxSize pageDrawingArea)
{
PangoFontMap* fontmap = pango_cairo_font_map_new_for_font_type(CAIRO_FONT_TYPE_FT);
if (fontmap == nullptr)
{ wxLogWarning(L"Freetype not supported in text window printer."); }

pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(fontmap), 96);
PangoContext* context = pango_font_map_create_context(fontmap);
g_object_unref(fontmap);

PangoLayout* layout = pango_layout_new(context);
g_object_unref(context);

pango_layout_set_width(layout, pageDrawingArea.GetWidth() * PANGO_SCALE); // ???
pango_layout_set_markup(layout, markup, -1);

PangoRectangle rect;
std::vector<gint> lineHeights;
gulong totalHeight{ 0 };
for (auto lines = pango_layout_get_lines_readonly(layout);
lines != nullptr;
lines = lines->next)
{
PangoLayoutLine* line{ static_cast<PangoLayoutLine*>(lines->data) };
pango_layout_line_get_pixel_extents(line, nullptr, &rect);
lineHeights.push_back(rect.height);
totalHeight += rect.height;
}
wxLogDebug("Page content area: %d x %d", pageDrawingArea.GetWidth(), pageDrawingArea.GetHeight());
wxLogDebug("Total lines and height: %zu and %ld", lineHeights.size(), totalHeight);

g_object_unref(layout);
}

//-------------------------------------------------
void
text_buffer_insert_markup_real (GtkTextBuffer *buffer,
Expand Down Expand Up @@ -255,7 +222,7 @@ text_buffer_set_markup (GtkTextBuffer *buffer,
}

//-------------------------------------------------
wxString GtkTextTagToHtmlSpanTag(const GtkTextTag* tag)
wxString _GtkTextTagToHtmlSpanTag(const GtkTextTag* tag)
{
wxString text = L"<span";
wxString styleParams = L" style=\"";
Expand Down Expand Up @@ -342,7 +309,7 @@ wxString GtkTextTagToHtmlSpanTag(const GtkTextTag* tag)
}

//-------------------------------------------------
wxString GtkTextTagToRtfTag(const GtkTextTag* tag,
wxString _GtkTextTagToRtfTag(const GtkTextTag* tag,
std::vector<wxColour>& colorTable,
std::vector<wxString>& fontTable)
{
Expand Down
Loading

0 comments on commit 9913948

Please sign in to comment.