qsciprinter.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // This module implements the QsciPrinter class.
  2. //
  3. // Copyright (c) 2017 Riverbank Computing Limited <info@riverbankcomputing.com>
  4. //
  5. // This file is part of QScintilla.
  6. //
  7. // This file may be used under the terms of the GNU General Public License
  8. // version 3.0 as published by the Free Software Foundation and appearing in
  9. // the file LICENSE included in the packaging of this file. Please review the
  10. // following information to ensure the GNU General Public License version 3.0
  11. // requirements will be met: http://www.gnu.org/copyleft/gpl.html.
  12. //
  13. // If you do not wish to use this file under the terms of the GPL version 3.0
  14. // then you may purchase a commercial license. For more information contact
  15. // info@riverbankcomputing.com.
  16. //
  17. // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  18. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19. #include "Qsci/qsciprinter.h"
  20. #if !defined(QT_NO_PRINTER)
  21. #include <QPrinter>
  22. #include <QPainter>
  23. #include <QStack>
  24. #include "Qsci/qsciscintillabase.h"
  25. // The ctor.
  26. QsciPrinter::QsciPrinter(QPrinter::PrinterMode mode)
  27. : QPrinter(mode), mag(0), wrap(QsciScintilla::WrapWord)
  28. {
  29. }
  30. // The dtor.
  31. QsciPrinter::~QsciPrinter()
  32. {
  33. }
  34. // Format the page before the document text is drawn.
  35. void QsciPrinter::formatPage(QPainter &, bool, QRect &, int)
  36. {
  37. }
  38. // Print a range of lines to a printer.
  39. int QsciPrinter::printRange(QsciScintillaBase *qsb, int from, int to)
  40. {
  41. // Sanity check.
  42. if (!qsb)
  43. return false;
  44. // Setup the printing area.
  45. QRect def_area;
  46. def_area.setX(0);
  47. def_area.setY(0);
  48. def_area.setWidth(width());
  49. def_area.setHeight(height());
  50. // Get the page range.
  51. int pgFrom, pgTo;
  52. pgFrom = fromPage();
  53. pgTo = toPage();
  54. // Find the position range.
  55. long startPos, endPos;
  56. endPos = qsb->SendScintilla(QsciScintillaBase::SCI_GETLENGTH);
  57. startPos = (from > 0 ? qsb -> SendScintilla(QsciScintillaBase::SCI_POSITIONFROMLINE,from) : 0);
  58. if (to >= 0)
  59. {
  60. long toPos = qsb -> SendScintilla(QsciScintillaBase::SCI_POSITIONFROMLINE,to + 1);
  61. if (endPos > toPos)
  62. endPos = toPos;
  63. }
  64. if (startPos >= endPos)
  65. return false;
  66. QPainter painter(this);
  67. bool reverse = (pageOrder() == LastPageFirst);
  68. bool needNewPage = false;
  69. qsb -> SendScintilla(QsciScintillaBase::SCI_SETPRINTMAGNIFICATION,mag);
  70. qsb -> SendScintilla(QsciScintillaBase::SCI_SETPRINTWRAPMODE,wrap);
  71. for (int i = 1; i <= numCopies(); ++i)
  72. {
  73. // If we are printing in reverse page order then remember the start
  74. // position of each page.
  75. QStack<long> pageStarts;
  76. int currPage = 1;
  77. long pos = startPos;
  78. while (pos < endPos)
  79. {
  80. // See if we have finished the requested page range.
  81. if (pgTo > 0 && pgTo < currPage)
  82. break;
  83. // See if we are going to render this page, or just see how much
  84. // would fit onto it.
  85. bool render = false;
  86. if (pgFrom == 0 || pgFrom <= currPage)
  87. {
  88. if (reverse)
  89. pageStarts.push(pos);
  90. else
  91. {
  92. render = true;
  93. if (needNewPage)
  94. {
  95. if (!newPage())
  96. return false;
  97. }
  98. else
  99. needNewPage = true;
  100. }
  101. }
  102. QRect area = def_area;
  103. formatPage(painter,render,area,currPage);
  104. pos = qsb -> SendScintilla(QsciScintillaBase::SCI_FORMATRANGE,render,&painter,area,pos,endPos);
  105. ++currPage;
  106. }
  107. // All done if we are printing in normal page order.
  108. if (!reverse)
  109. continue;
  110. // Now go through each page on the stack and really print it.
  111. while (!pageStarts.isEmpty())
  112. {
  113. --currPage;
  114. long ePos = pos;
  115. pos = pageStarts.pop();
  116. if (needNewPage)
  117. {
  118. if (!newPage())
  119. return false;
  120. }
  121. else
  122. needNewPage = true;
  123. QRect area = def_area;
  124. formatPage(painter,true,area,currPage);
  125. qsb->SendScintilla(QsciScintillaBase::SCI_FORMATRANGE,true,&painter,area,pos,ePos);
  126. }
  127. }
  128. return true;
  129. }
  130. // Set the print magnification in points.
  131. void QsciPrinter::setMagnification(int magnification)
  132. {
  133. mag = magnification;
  134. }
  135. // Set the line wrap mode.
  136. void QsciPrinter::setWrapMode(QsciScintilla::WrapMode wmode)
  137. {
  138. wrap = wmode;
  139. }
  140. #endif