Пример #1
0
void Printer::flowRender()
{
	// add extra padding at the bottom to pages with height not divisible by view port
	int paddingBottom = pageSize.height() - (webView->page()->mainFrame()->contentsSize().height() % pageSize.height());
	QString styleString = QString::fromUtf8("padding-bottom: ") + QString::number(paddingBottom) + "px;";
	webView->page()->mainFrame()->findFirstElement("body").setAttribute("style", styleString);

	// render the Qwebview
	QPainter painter;
	QRect viewPort(0, 0, 0, 0);
	painter.begin(paintDevice);
	painter.setRenderHint(QPainter::Antialiasing);
	painter.setRenderHint(QPainter::SmoothPixmapTransform);

	// get all references to dontbreak divs
	int start = 0, end = 0;
	int fullPageResolution = webView->page()->mainFrame()->contentsSize().height();
	QWebElementCollection dontbreak = webView->page()->mainFrame()->findAllElements(".dontbreak");
	foreach (QWebElement dontbreakElement, dontbreak) {
		if ((dontbreakElement.geometry().y() + dontbreakElement.geometry().height()) - start < pageSize.height()) {
			// One more element can be placed
			end = dontbreakElement.geometry().y() + dontbreakElement.geometry().height();
		} else {
			// fill the page with background color
			QRect fullPage(0, 0, pageSize.width(), pageSize.height());
			QBrush fillBrush(templateOptions->color_palette.color1);
			painter.fillRect(fullPage, fillBrush);
			QRegion reigon(0, 0, pageSize.width(), end - start);
			viewPort.setRect(0, start, pageSize.width(), end - start);

			// render the base Html template
			webView->page()->mainFrame()->render(&painter, QWebFrame::ContentsLayer, reigon);

			// scroll the webview to the next page
			webView->page()->mainFrame()->scroll(0, dontbreakElement.geometry().y() - start);

			// rendering progress is 4/5 of total work
			emit(progessUpdated((end * 80.0 / fullPageResolution) + done));

			// add new pages only in print mode, while previewing we don't add new pages
			if (printMode == Printer::PRINT)
				static_cast<QPrinter*>(paintDevice)->newPage();
			else {
				painter.end();
				return;
			}
			start = dontbreakElement.geometry().y();
		}
	}
	// render the remianing page
	QRect fullPage(0, 0, pageSize.width(), pageSize.height());
	QBrush fillBrush(templateOptions->color_palette.color1);
	painter.fillRect(fullPage, fillBrush);
	QRegion reigon(0, 0, pageSize.width(), end - start);
	webView->page()->mainFrame()->render(&painter, QWebFrame::ContentsLayer, reigon);

	painter.end();
}
Пример #2
0
int QPrinter::metric( int m ) const
{
    int val;
    PageSize s = pageSize();
#if defined(CHECK_RANGE)
    ASSERT( (uint)s < (uint)NPageSize );
#endif
    static int widths[]	 = { 595, 516, 612, 612, 541,
			     2384, 1684, 1191, 842, 420, 297, 210, 148, 105,
			     2920, 2064, 91, 1460, 1032, 729, 516, 363, 258,
			     181, 127, 461, 297, 312, 595, 1224, 792 };

    static int heights[] = { 842, 729, 792, 1009, 720,
			     3370, 2384, 1684, 1191, 595, 420, 297, 210, 148,
			     4127, 2920, 127, 2064, 1460, 1032, 729, 516, 363,
			     258, 181, 648, 684, 624, 935, 792, 1224 };
    switch ( m ) {
	case QPaintDeviceMetrics::PdmWidth:
	    val = orient == Portrait ? widths[ s ] : heights[ s ];
	    if ( !fullPage() )
		val -= 2*margins().width();
	    break;
	case QPaintDeviceMetrics::PdmHeight:
	    val = orient == Portrait ? heights[ s ] : widths[ s ];
	    if ( !fullPage() )
		val -= 2*margins().height();
	    break;
	case QPaintDeviceMetrics::PdmDpiX:
	    val = 72;
	    break;
	case QPaintDeviceMetrics::PdmDpiY:
	    val = 72;
	    break;
	case QPaintDeviceMetrics::PdmWidthMM:
	    val = metric( QPaintDeviceMetrics::PdmWidth );
	    val = (val * 254 + 360) / 720; // +360 to get the right rounding
	    break;
	case QPaintDeviceMetrics::PdmHeightMM:
	    val = metric( QPaintDeviceMetrics::PdmHeight );
	    val = (val * 254 + 360) / 720;
	    break;
	case QPaintDeviceMetrics::PdmNumColors:
	    val = 16777216;
	    break;
	case QPaintDeviceMetrics::PdmDepth:
	    val = 24;
	    break;
	default:
	    val = 0;
#if defined(CHECK_RANGE)
	    qWarning( "QPixmap::metric: Invalid metric command" );
#endif
    }
    return val;
}
Пример #3
0
bool QPrinter::newPage()
{
  if (state != PST_ACTIVE)
    return FALSE;
  if (PMSessionEndPage(psession) != noErr)  { //end the last page
    state = PST_ERROR;
    return FALSE;
  }

  if (PMSessionBeginPage(psession, pformat, 0) != noErr)  { //start a new one
    state = PST_ERROR;
    return FALSE;
  }
  if (PMSessionGetGraphicsContext(psession, kPMGraphicsContextQuickdraw, &hd) != noErr) {
    state = PST_ERROR;
    return FALSE;
  }

  if (fullPage()) {
    uint top, left, bottom, right;
    qt_get_margins(pformat, &top, &left, &bottom, &right);
    QMacSavedPortInfo mp(this);
    SetOrigin(top, left);
  } else {
    QMacSavedPortInfo mp(this);
    SetOrigin(0, 0);
  }
  return TRUE;
}
Пример #4
0
bool QPrinter::cmd(int c, QPainter *, QPDevCmdParam *)
{
  if (!psession && PMCreateSession(&psession) != noErr)
    return FALSE;

  if (c ==  PdcBegin) {                     // begin; start printing
    if (state != PST_IDLE) {
      qDebug("Qt: internal: printer: two PdcBegin(s).");
      return FALSE;
    }

    //just to be sure they've been setup
    prepare(&pformat);
    prepare(&psettings);

    //validate the settings
    if (PMSessionValidatePrintSettings(psession, psettings, kPMDontWantBoolean) != noErr)
      return FALSE;
    if (PMSessionValidatePageFormat(psession, pformat, kPMDontWantBoolean) != noErr)
      return FALSE;

    if (PMSessionBeginDocument(psession, psettings, pformat) != noErr) //begin the document
      return FALSE;


    if (PMSessionBeginPage(psession, pformat, 0) != noErr) //begin the page
      return FALSE;
    if (PMSessionGetGraphicsContext(psession, kPMGraphicsContextQuickdraw,
                                    &hd) != noErr) //get the gworld
      return FALSE;
    state = PST_ACTIVE;
    if (fullPage()) {
      uint top, left, bottom, right;
      qt_get_margins(pformat, &top, &left, &bottom, &right);
      QMacSavedPortInfo mp(this);
      SetOrigin(top, left);
    } else {
      QMacSavedPortInfo mp(this);
      SetOrigin(0, 0);
    }
  } else if (c == PdcEnd) {
    if (hd && state != PST_IDLE) {
      PMSessionEndPage(psession);
      PMSessionEndDocument(psession);
      hd = NULL;
    }
    state  = PST_IDLE;
  } else {                                    // all other commands...
    if (state == PST_ABORTED || ((state == PST_ACTIVE || state == PST_ERROR) && PMSessionError(psession) != noErr))
      return FALSE;
  }
  return TRUE;
}
Пример #5
0
int KPrinter::metric(int m) const
{
	if (d->m_pagesize == NULL || !option( "kde-printsize" ).isEmpty())
		return d->m_wrapper->qprinterMetric(m);

	int	val(0);
	bool	land = (orientation() == KPrinter::Landscape);
	uint	res(d->m_wrapper->resolution()), top = res/2, left = res/2, bottom = res/3, right = res/2;
	margins( &top, &left, &bottom, &right );
	switch ( m )
	{
		case QPaintDeviceMetrics::PdmWidth:
			val = (land ? ( int )d->m_pagesize->pageHeight() : ( int )d->m_pagesize->pageWidth());
			if ( res != 72 )
				val = (val * res + 36) / 72;
			if ( !fullPage() )
				val -= ( left + right );
			break;
		case QPaintDeviceMetrics::PdmHeight:
			val = (land ? ( int )d->m_pagesize->pageWidth() : ( int )d->m_pagesize->pageHeight());
			if ( res != 72 )
				val = (val * res + 36) / 72;
			if ( !fullPage() )
				val -= ( top + bottom );
			break;
		case QPaintDeviceMetrics::PdmWidthMM:
			val = metric( QPaintDeviceMetrics::PdmWidth );
			val = (val * 254 + 5*res) / (10*res); // +360 to get the right rounding
			break;
		case QPaintDeviceMetrics::PdmHeightMM:
			val = metric( QPaintDeviceMetrics::PdmHeight );
			val = (val * 254 + 5*res) / (10*res);
			break;
		default:
			val = d->m_wrapper->qprinterMetric(m);
			break;
	}
	return val;
}
Пример #6
0
int QPrinter::metric(int m) const
{
  int val = 1;
  switch (m) {
    case QPaintDeviceMetrics::PdmWidth: {
      bool orientInSync = true;
      PMOrientation o;
      QPrinter::Orientation tmpOrient = orientation();
      if (PMGetOrientation(pformat, &o) == noErr) {
        orientInSync = ((o == kPMPortrait && tmpOrient == Portrait)
                        || o == kPMLandscape && tmpOrient == Landscape);
      }
      PageSize s = pageSize();
      if (s >= QPrinter::Custom) {
        val = tmpOrient == Portrait ? customPaperSize_.width() : customPaperSize_.height();
      } else {
        if (state == PST_ACTIVE || (tmpOrient == Portrait || orientInSync)) {
          val = qt_get_PDMWidth(pformat, fullPage());
        } else {
          val = qt_get_PDMHeight(pformat, fullPage());
        }
      }
      break;
    }
    case QPaintDeviceMetrics::PdmHeight: {
      bool orientInSync = true;
      PMOrientation o;
      QPrinter::Orientation tmpOrient = orientation();
      if (PMGetOrientation(pformat, &o) == noErr) {
        orientInSync = ((o == kPMPortrait && tmpOrient == Portrait)
                        || o == kPMLandscape && tmpOrient == Landscape);
      }
      PageSize s = pageSize();
      if (s >= QPrinter::Custom) {
        val = tmpOrient == Portrait ? customPaperSize_.height() : customPaperSize_.width();
      } else {
        if (state == PST_ACTIVE || (tmpOrient == Portrait || orientInSync)) {
          val = qt_get_PDMHeight(pformat, fullPage());
        } else {
          val = qt_get_PDMWidth(pformat, fullPage());
        }
      }
      break;
    }
    // We don't have to worry about the printer state here as metric() does that for us.
    case QPaintDeviceMetrics::PdmWidthMM:
      val = metric(QPaintDeviceMetrics::PdmWidth);
      val = (val * 254 + 5 * res) / (10 * res);
      break;
    case QPaintDeviceMetrics::PdmHeightMM:
      val = metric(QPaintDeviceMetrics::PdmHeight);
      val = (val * 254 + 5 * res) / (10 * res);
      break;
    case QPaintDeviceMetrics::PdmPhysicalDpiX:
    case QPaintDeviceMetrics::PdmPhysicalDpiY: {
      PMPrinter printer;
      if (PMSessionGetCurrentPrinter(psession, &printer) == noErr) {
        PMResolution resolution;
        PMPrinterGetPrinterResolution(printer, kPMCurrentValue, &resolution);
        val = (int)resolution.vRes;
        break;
      }
      //otherwise fall through
    }
    case QPaintDeviceMetrics::PdmDpiY:
    case QPaintDeviceMetrics::PdmDpiX:
      val = res;
      break;
    case QPaintDeviceMetrics::PdmNumColors:
      val = (1 << metric(QPaintDeviceMetrics::PdmDepth));
      break;
    case QPaintDeviceMetrics::PdmDepth:
      val = 24;
      break;
    default:
      val = 0;
#if defined(QT_CHECK_RANGE)
      qWarning("Qt: QPixmap::metric: Invalid metric command");
#endif
  }
  return val;
}
Пример #7
0
// TODO:  speed stats
// TODO:  faster: max_advance_width
int RenderFb::render(Pagination* pagination, unsigned int pageNum, bool doBlit)
{
    clc::Log::info("ocher.renderer.fb", "render page %u %u", pageNum, doBlit);
    m_penX = settings.marginLeft;
    m_penY = settings.marginTop + g_ft->getAscender();
    if (doBlit)
        m_fb->clear();

    unsigned int layoutOffset;
    unsigned int strOffset;
    if (!pageNum) {
        layoutOffset = 0;
        strOffset = 0;
    } else if (! pagination->get(pageNum-1, &layoutOffset, &strOffset)) {
        // Previous page not already paginated?
        // Perhaps at end of book?
        clc::Log::error("ocher.renderer.fb", "page %u not found", pageNum);
        return -1;
    }

    const unsigned int N = m_layout.size();
    const char *raw = m_layout.data();
    Rect fullPage(0, 0, m_fb->width(), m_fb->height());
    ASSERT(layoutOffset < N);
    for (unsigned int i = layoutOffset; i < N; ) {
        ASSERT(i+2 <= N);
        uint16_t code = *(uint16_t*)(raw+i);
        i += 2;

        unsigned int opType = (code>>12)&0xf;
        unsigned int op = (code>>8)&0xf;
        unsigned int arg = code & 0xff;
        switch (opType) {
            case Layout::OpPushTextAttr:
                clc::Log::trace("ocher.render.fb", "OpPushTextAttr");
                switch (op) {
                    case Layout::AttrBold:
                        pushAttrs();
                        a[ai].b = 1;
                        break;
                    case Layout::AttrUnderline:
                        pushAttrs();
                        a[ai].ul = 1;
                        break;
                    case Layout::AttrItalics:
                        pushAttrs();
                        a[ai].em = 1;
                        break;
                    case Layout::AttrSizeRel:
                        pushAttrs();
                        clc::Log::debug("ocher.render.fb", "font rel %d", (int)arg);
                        a[ai].pts += (int)arg;
                        m_ft->setSize(a[ai].pts);
                        break;
                    case Layout::AttrSizeAbs:
                        pushAttrs();
                        clc::Log::debug("ocher.render.fb", "font abs %d", (int)arg);
                        a[ai].pts = (int)arg;
                        m_ft->setSize(a[ai].pts);
                        break;
                    default:
                        clc::Log::error("ocher.render.fb", "unknown OpPushTextAttr");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpPushLineAttr:
                clc::Log::debug("ocher.render.fb", "OpPushLineAttr");
                switch (op) {
                    case Layout::LineJustifyLeft:
                        break;
                    case Layout::LineJustifyCenter:
                        break;
                    case Layout::LineJustifyFull:
                        break;
                    case Layout::LineJustifyRight:
                        break;
                    default:
                        clc::Log::error("ocher.render.fb", "unknown OpPushLineAttr");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpCmd:
                switch (op) {
                    case Layout::CmdPopAttr:
                        clc::Log::trace("ocher.render.fb", "OpCmd CmdPopAttr");
                        if (arg == 0)
                            arg = 1;
                        while (arg--)
                            popAttrs();
                        // TODO:  only reset what has changed
                        clc::Log::debug("ocher.render.fb", "font pop %d", a[ai].pts);
                        m_ft->setSize(a[ai].pts);
                        break;
                    case Layout::CmdOutputStr: {
                        clc::Log::trace("ocher.render.fb", "OpCmd CmdOutputStr");
                        ASSERT(i + sizeof(clc::Buffer*) <= N);
                        clc::Buffer *str = *(clc::Buffer**)(raw+i);
                        ASSERT(strOffset <= str->size());
                        int breakOffset = outputWrapped(str, strOffset, doBlit);
                        strOffset = 0;
                        if (breakOffset >= 0) {
                            pagination->set(pageNum, i-2, breakOffset);
                            clc::Log::debug("ocher.renderer.fb", "page %u break", pageNum);
                            if (doBlit)
                                m_fb->update(&fullPage, false);
                            return 0;
                        }
                        i += sizeof(clc::Buffer*);
                        break;
                    }
                    case Layout::CmdForcePage:
                        clc::Log::trace("ocher.render.fb", "OpCmd CmdForcePage");
                        break;
                    default:
                        clc::Log::error("ocher.render.fb", "unknown OpCmd");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpSpacing:
                break;
            case Layout::OpImage:
                break;
            default:
                clc::Log::error("ocher.render.fb", "unknown op type");
                ASSERT(0);
                break;
        };
    }
    clc::Log::debug("ocher.renderer.fb", "page %u done", pageNum);
    if (doBlit)
        m_fb->update(&fullPage, false);
    return 1;
}
Пример #8
0
void KPrinter::translateQtOptions()
{
	d->m_wrapper->setCreator(creator());
	d->m_wrapper->setDocName(docName());
	d->m_wrapper->setFullPage(fullPage());
	d->m_wrapper->setColorMode((QPrinter::ColorMode)colorMode());
	d->m_wrapper->setOrientation((QPrinter::Orientation)orientation());
	if ( !option( "kde-printsize" ).isEmpty() )
		d->m_wrapper->setPageSize( ( QPrinter::PageSize )option( "kde-printsize" ).toInt() );
	else
		d->m_wrapper->setPageSize((QPrinter::PageSize)pageSize());
	d->m_wrapper->setOutputToFile(true);
	d->m_wrapper->setOutputFileName(d->m_tmpbuffer);
	d->m_wrapper->setNumCopies(option("kde-qtcopies").isEmpty() ? 1 : option("kde-qtcopies").toInt());
	if (!option("kde-margin-top").isEmpty())
	{
		/**
		 * Scale margings as the margin widget always stores values
		 * in dot units ( 1/72th in ), to be resolution independent
		 * when specified by the user ( who usually specifies margins
		 * in metric units ).
		 */
		int res = resolution();
		d->m_wrapper->setMargins(
				( int )( ( option("kde-margin-top").toFloat() * res + 71 ) / 72 ),
				( int )( ( option("kde-margin-left").toFloat() * res + 71 ) / 72 ),
				( int )( ( option("kde-margin-bottom").toFloat() * res + 71 ) / 72 ),
				( int )( ( option("kde-margin-right").toFloat() * res + 71 ) / 72 ) );
	}
	else if ( d->m_pagesize != NULL )
	{
		int res = resolution();
		DrPageSize *ps = d->m_pagesize;
		int top = ( int )( ps->topMargin() * res + 71 ) / 72;
		int left = ( int )( ps->leftMargin() * res + 71 ) / 72;
		int bottom = ( int )( ps->bottomMargin() * res + 71 ) / 72;
		int right = ( int )( ps->rightMargin() * res + 71 ) / 72;
		if ( !fullPage() )
		{
			// Printers can often print very close to the edges (PPD files say ImageArea==PaperDimension).
			// But that doesn't mean it looks good. Apps which use setFullPage(false) assume that
			// KPrinter will give them reasonable margins, so let's QMAX with defaults from Qt in that case.
			// Keep this in sync with KPMarginPage::initPageSize
			unsigned int it, il, ib, ir;
			d->m_wrapper->margins( &it, &il, &ib, &ir );
			top = QMAX( top, (int)it );
			left = QMAX( left, (int)il );
			bottom = QMAX( bottom, (int)ib );
			right = QMAX( right, (int)ir );
		}
		d->m_wrapper->setMargins( top, left, bottom, right );
	}
	/*else
	{
		int res = d->m_wrapper->resolution();
		d->m_wrapper->setMargins( res/3, res/2, res/3, res/2 );
	}*/
	// for special printers, copies are handled by Qt
	if (option("kde-isspecial") == "1")
		d->m_wrapper->setNumCopies(numCopies());
}