Ejemplo n.º 1
0
void xf_draw_screen_scaled(xfInfo* xfi)
{
	XTransform transform;
	Picture windowPicture;
	Picture primaryPicture;
	XRenderPictureAttributes pa;
	XRenderPictFormat* picFormat;

	picFormat = XRenderFindStandardFormat(xfi->display, PictStandardRGB24);
	pa.subwindow_mode = IncludeInferiors;
	primaryPicture = XRenderCreatePicture(xfi->display, xfi->primary, picFormat, CPSubwindowMode, &pa);
	windowPicture = XRenderCreatePicture(xfi->display, xfi->window->handle, picFormat, CPSubwindowMode, &pa);

	transform.matrix[0][0] = XDoubleToFixed(1);
	transform.matrix[0][1] = XDoubleToFixed(0);
	transform.matrix[0][2] = XDoubleToFixed(0);

	transform.matrix[1][0] = XDoubleToFixed(0);
	transform.matrix[1][1] = XDoubleToFixed(1);
	transform.matrix[1][2] = XDoubleToFixed(0);

	transform.matrix[2][0] = XDoubleToFixed(0);
	transform.matrix[2][1] = XDoubleToFixed(0);
	transform.matrix[2][2] = XDoubleToFixed(xfi->scale);

	XRenderSetPictureTransform(xfi->display, primaryPicture, &transform);
	XRenderComposite(xfi->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, 0, 0, xfi->currentWidth, xfi->currentHeight);
}
Ejemplo n.º 2
0
void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h, BOOL scale)
{
#ifdef WITH_XRENDER
	XTransform transform;
	Picture windowPicture;
	Picture primaryPicture;
	XRenderPictureAttributes pa;
	XRenderPictFormat* picFormat;
	XRectangle xr;

	picFormat = XRenderFindStandardFormat(xfc->display, PictStandardRGB24);
	pa.subwindow_mode = IncludeInferiors;
	primaryPicture = XRenderCreatePicture(xfc->display, xfc->primary, picFormat, CPSubwindowMode, &pa);
	windowPicture = XRenderCreatePicture(xfc->display, xfc->window->handle, picFormat, CPSubwindowMode, &pa);

	transform.matrix[0][0] = XDoubleToFixed(1);
	transform.matrix[0][1] = XDoubleToFixed(0);
	transform.matrix[0][2] = XDoubleToFixed(0);

	transform.matrix[1][0] = XDoubleToFixed(0);
	transform.matrix[1][1] = XDoubleToFixed(1);
	transform.matrix[1][2] = XDoubleToFixed(0);

	transform.matrix[2][0] = XDoubleToFixed(0);
	transform.matrix[2][1] = XDoubleToFixed(0);
	transform.matrix[2][2] = XDoubleToFixed(xfc->settings->ScalingFactor);

	if( (w != 0) && (h != 0) )
	{

		if(scale == TRUE)
		{
			xr.x = x * xfc->settings->ScalingFactor;
			xr.y = y * xfc->settings->ScalingFactor;
			xr.width = (w+1) * xfc->settings->ScalingFactor;
			xr.height = (h+1) * xfc->settings->ScalingFactor;
		}
		else
		{
			xr.x = x;
			xr.y = y;
			xr.width = w;
			xr.height = h;
		}

		XRenderSetPictureClipRectangles(xfc->display, primaryPicture, 0, 0, &xr, 1);
	}

	XRenderSetPictureTransform(xfc->display, primaryPicture, &transform);

	XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, xfc->offset_x, xfc->offset_y, xfc->currentWidth, xfc->currentHeight);

	XRenderFreePicture(xfc->display, primaryPicture);
	XRenderFreePicture(xfc->display, windowPicture);

#endif

}
Ejemplo n.º 3
0
 inline QEdge(const QPointF &pt1,
              const QPointF &pt2)
 {
     p1.x = XDoubleToFixed(pt1.x());
     p1.y = XDoubleToFixed(pt1.y());
     p2.x = XDoubleToFixed(pt2.x());
     p2.y = XDoubleToFixed(pt2.y());
     m = (pt1.x() - pt2.x()) ? (pt1.y() - pt2.y()) / (pt1.x() - pt2.x()) : 0;
     im = m ? 1/m : 0;
     b = pt1.y() - m * pt1.x();
     vertical = p1.x == p2.x;
     horizontal = p1.y == p2.y;
 }
Ejemplo n.º 4
0
    inline qreal xAt(const qreal &y) const
    {
        Q_ASSERT(p1.y != p2.y);
        XFixed yf = XDoubleToFixed(y);

        if (yf == p1.y)
            return XFixedToDouble(p1.x);
        else if (yf == p2.y)
            return XFixedToDouble(p2.x);

        return (!vertical) ? (((y - b)*im)) : pf1.x();
    }
Ejemplo n.º 5
0
static XFixed
XRenderComputeIntersect (XLineFixed *l1, XLineFixed *l2)
{
    /*
     * x = m1y + b1
     * x = m2y + b2
     * m1y + b1 = m2y + b2
     * y * (m1 - m2) = b2 - b1
     * y = (b2 - b1) / (m1 - m2)
     */
    double  m1 = XRenderComputeInverseSlope (l1);
    double  b1 = XRenderComputeXIntercept (l1, m1);
    double  m2 = XRenderComputeInverseSlope (l2);
    double  b2 = XRenderComputeXIntercept (l2, m2);

    return XDoubleToFixed ((b2 - b1) / (m1 - m2));
}
Ejemplo n.º 6
0
static void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h)
{
	XTransform transform;
	Picture windowPicture;
	Picture primaryPicture;
	XRenderPictureAttributes pa;
	XRenderPictFormat* picFormat;
	double xScalingFactor;
	double yScalingFactor;
	int x2;
	int y2;

	if (xfc->scaledWidth <= 0 || xfc->scaledHeight <= 0)
	{
		WLog_ERR(TAG, "the current window dimensions are invalid");
		return;
	}

	if (xfc->sessionWidth <= 0 || xfc->sessionHeight <= 0)
	{
		WLog_ERR(TAG, "the window dimensions are invalid");
		return;
	}

	xScalingFactor = xfc->sessionWidth / (double)xfc->scaledWidth;
	yScalingFactor = xfc->sessionHeight / (double)xfc->scaledHeight;

	XSetFillStyle(xfc->display, xfc->gc, FillSolid);
	XSetForeground(xfc->display, xfc->gc, 0);

	/* Black out possible space between desktop and window borders */
	{
		XRectangle box1 = { 0, 0, xfc->window->width, xfc->window->height };
		XRectangle box2 = { xfc->offset_x, xfc->offset_y, xfc->scaledWidth, xfc->scaledHeight };
		Region reg1 = XCreateRegion();
		Region reg2 = XCreateRegion();
		XUnionRectWithRegion(&box1, reg1, reg1);
		XUnionRectWithRegion(&box2, reg2, reg2);

		if (XSubtractRegion(reg1, reg2, reg1) && !XEmptyRegion(reg1))
		{
			XSetRegion(xfc->display, xfc->gc, reg1);
			XFillRectangle(xfc->display, xfc->window->handle, xfc->gc, 0, 0, xfc->window->width, xfc->window->height);
			XSetClipMask(xfc->display, xfc->gc, None);
		}

		XDestroyRegion(reg1);
		XDestroyRegion(reg2);
	}

	picFormat = XRenderFindVisualFormat(xfc->display, xfc->visual);

	pa.subwindow_mode = IncludeInferiors;
	primaryPicture = XRenderCreatePicture(xfc->display, xfc->primary, picFormat, CPSubwindowMode, &pa);
	windowPicture = XRenderCreatePicture(xfc->display, xfc->window->handle, picFormat, CPSubwindowMode, &pa);

	XRenderSetPictureFilter(xfc->display, primaryPicture, FilterBilinear, 0, 0);

	transform.matrix[0][0] = XDoubleToFixed(xScalingFactor);
	transform.matrix[0][1] = XDoubleToFixed(0.0);
	transform.matrix[0][2] = XDoubleToFixed(0.0);
	transform.matrix[1][0] = XDoubleToFixed(0.0);
	transform.matrix[1][1] = XDoubleToFixed(yScalingFactor);
	transform.matrix[1][2] = XDoubleToFixed(0.0);
	transform.matrix[2][0] = XDoubleToFixed(0.0);
	transform.matrix[2][1] = XDoubleToFixed(0.0);
	transform.matrix[2][2] = XDoubleToFixed(1.0);

	/* calculate and fix up scaled coordinates */
	x2 = x + w;
	y2 = y + h;
	x = floor(x / xScalingFactor) - 1;
	y = floor(y / yScalingFactor) - 1;
	w = ceil(x2 / xScalingFactor) + 1 - x;
	h = ceil(y2 / yScalingFactor) + 1 - y;

	XRenderSetPictureTransform(xfc->display, primaryPicture, &transform);
	XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, x, y, 0, 0, xfc->offset_x + x, xfc->offset_y + y, w, h);
	XRenderFreePicture(xfc->display, primaryPicture);
	XRenderFreePicture(xfc->display, windowPicture);
}
static gboolean
on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
  GdkGC *gc;
  XTransform transform;
  double scale;
  int wx, wy, ww, wh;
  int frame_left, frame_right, frame_top, frame_bottom;
  int thumbnail_width, thumbnail_height;
  int offset_x, offset_y;
  SSWindow *window;
  SSThumbnailer *thumbnailer;
  Display *display;
  display = gdk_x11_get_default_xdisplay ();
  thumbnailer = (SSThumbnailer *) data;
  window = thumbnailer->window;

  if (thumbnailer->thumbnail_pixmap == NULL) {
    initialize_thumbnailer_pictures (thumbnailer);
  }
  gc = gdk_gc_new (thumbnailer->thumbnail_pixmap);

  ss_xinerama_get_frame_extents (
      // TODO - should we cut out the ->workspace in the line below?
      window->workspace->screen->xinerama, window,
      &frame_left, &frame_right, &frame_top, &frame_bottom);

  wnck_window_get_geometry (window->wnck_window, &wx, &wy, &ww, &wh);

  scale = ww > wh ? ww : wh;
  scale /= (double) THUMBNAIL_SIZE;
  thumbnail_width = thumbnail_height = THUMBNAIL_SIZE;
  if (ww > wh) {
    thumbnail_height = wh * THUMBNAIL_SIZE / ww;
  } else {
    thumbnail_width = ww * THUMBNAIL_SIZE / wh;
  }
  
  transform.matrix[0][0] = XDoubleToFixed (scale);
  transform.matrix[0][1] = XDoubleToFixed (0.0);
  transform.matrix[0][2] = XDoubleToFixed (-frame_left * (scale - 1.0));
  transform.matrix[1][0] = XDoubleToFixed (0.0);
  transform.matrix[1][1] = XDoubleToFixed (scale);
  transform.matrix[1][2] = XDoubleToFixed (-frame_top * (scale - 1.0));
  transform.matrix[2][0] = XDoubleToFixed (0.0);
  transform.matrix[2][1] = XDoubleToFixed (0.0);
  transform.matrix[2][2] = XDoubleToFixed (1.0);
  XRenderSetPictureTransform (display, thumbnailer->window_picture,
      &transform);

  XRenderComposite (display, PictOpSrc,
    thumbnailer->window_picture, None, thumbnailer->thumbnail_picture,
    0, 0, 0, 0, 0, 0, THUMBNAIL_SIZE, THUMBNAIL_SIZE);

  offset_x = widget->allocation.x + (THUMBNAIL_SIZE - thumbnail_width) / 2;
  offset_y = widget->allocation.y + (THUMBNAIL_SIZE - thumbnail_height) / 2;

  gdk_draw_drawable (thumbnailer->drawing_area->window, gc,
      thumbnailer->thumbnail_pixmap, 0, 0,
      offset_x, offset_y, thumbnail_width, thumbnail_height);

  gdk_draw_rectangle (thumbnailer->drawing_area->window,
      thumbnailer->drawing_area->style->black_gc, FALSE,
      offset_x, offset_y, thumbnail_width - 1, thumbnail_height - 1);

  g_object_unref (gc);
  return FALSE;
}
Ejemplo n.º 8
0
void old_tesselate_polygon(QVector<XTrapezoid> *traps, const QPointF *pg, int pgSize,
                           bool winding)
{
    QVector<QEdge> edges;
    edges.reserve(128);
    qreal ymin(INT_MAX/256);
    qreal ymax(INT_MIN/256);

    //painter.begin(pg, pgSize);
    if (pg[0] != pg[pgSize-1])
        qWarning() << Q_FUNC_INFO << "Malformed polygon (first and last points must be identical)";
    // generate edge table
//     qDebug() << "POINTS:";
    for (int x = 0; x < pgSize-1; ++x) {
	QEdge edge;
        QPointF p1(Q27Dot5ToDouble(FloatToQ27Dot5(pg[x].x())),
                   Q27Dot5ToDouble(FloatToQ27Dot5(pg[x].y())));
        QPointF p2(Q27Dot5ToDouble(FloatToQ27Dot5(pg[x+1].x())),
                   Q27Dot5ToDouble(FloatToQ27Dot5(pg[x+1].y())));

//         qDebug() << "    "
//                  << p1;
	edge.winding = p1.y() > p2.y() ? 1 : -1;
	if (edge.winding > 0)
            qSwap(p1, p2);
        edge.p1.x = XDoubleToFixed(p1.x());
        edge.p1.y = XDoubleToFixed(p1.y());
        edge.p2.x = XDoubleToFixed(p2.x());
        edge.p2.y = XDoubleToFixed(p2.y());

	edge.m = (p1.y() - p2.y()) / (p1.x() - p2.x()); // line derivative
	edge.b = p1.y() - edge.m * p1.x(); // intersection with y axis
	edge.m = edge.m != 0.0 ? 1.0 / edge.m : 0.0; // inverted derivative
	edges.append(edge);
        ymin = qMin(ymin, qreal(XFixedToDouble(edge.p1.y)));
        ymax = qMax(ymax, qreal(XFixedToDouble(edge.p2.y)));
    }

    QList<const QEdge *> et; 	    // edge list
    for (int i = 0; i < edges.size(); ++i)
        et.append(&edges.at(i));

    // sort edge table by min y value
    qSort(et.begin(), et.end(), compareEdges);

    // eliminate shared edges
    for (int i = 0; i < et.size(); ++i) {
	for (int k = i+1; k < et.size(); ++k) {
            const QEdge *edgeI = et.at(i);
            const QEdge *edgeK = et.at(k);
            if (edgeK->p1.y > edgeI->p1.y)
                break;
   	    if (edgeI->winding != edgeK->winding &&
                isEqual(edgeI->p1, edgeK->p1) && isEqual(edgeI->p2, edgeK->p2)
		) {
 		et.removeAt(k);
		et.removeAt(i);
		--i;
		break;
	    }
	}
    }

    if (ymax <= ymin)
	return;
    QList<const QEdge *> aet; 	    // edges that intersects the current scanline

//     if (ymin < 0)
// 	ymin = 0;
//     if (paintEventClipRegion) // don't scan more lines than we have to
// 	ymax = paintEventClipRegion->boundingRect().height();

#ifdef QT_DEBUG_TESSELATOR
    qDebug("==> ymin = %f, ymax = %f", ymin, ymax);
#endif // QT_DEBUG_TESSELATOR

    currentY = ymin; // used by the less than op
    for (qreal y = ymin; y < ymax;) {
	// fill active edge table with edges that intersect the current line
	for (int i = 0; i < et.size(); ++i) {
            const QEdge *edge = et.at(i);
            if (edge->p1.y > XDoubleToFixed(y))
                break;
            aet.append(edge);
            et.removeAt(i);
            --i;
	}

	// remove processed edges from active edge table
	for (int i = 0; i < aet.size(); ++i) {
	    if (aet.at(i)->p2.y <= XDoubleToFixed(y)) {
		aet.removeAt(i);
 		--i;
	    }
	}
        if (aet.size()%2 != 0) {
#ifndef QT_NO_DEBUG
            qWarning("QX11PaintEngine: aet out of sync - this should not happen.");
#endif
            return;
        }

	// done?
	if (!aet.size()) {
            if (!et.size()) {
                break;
	    } else {
 		y = currentY = XFixedToDouble(et.at(0)->p1.y);
                continue;
	    }
        }

        // calculate the next y where we have to start a new set of trapezoids
	qreal next_y(INT_MAX/256);
 	for (int i = 0; i < aet.size(); ++i) {
            const QEdge *edge = aet.at(i);
 	    if (XFixedToDouble(edge->p2.y) < next_y)
 		next_y = XFixedToDouble(edge->p2.y);
        }

	if (et.size() && next_y > XFixedToDouble(et.at(0)->p1.y))
	    next_y = XFixedToDouble(et.at(0)->p1.y);

        int aetSize = aet.size();
	for (int i = 0; i < aetSize; ++i) {
	    for (int k = i+1; k < aetSize; ++k) {
                const QEdge *edgeI = aet.at(i);
                const QEdge *edgeK = aet.at(k);
		qreal m1 = edgeI->m;
		qreal b1 = edgeI->b;
		qreal m2 = edgeK->m;
		qreal b2 = edgeK->b;

		if (qAbs(m1 - m2) < 0.001)
                    continue;

                // ### intersect is not calculated correctly when optimized with -O2 (gcc)
                volatile qreal intersect = 0;
                if (!qIsFinite(b1))
                    intersect = (1.f / m2) * XFixedToDouble(edgeI->p1.x) + b2;
                else if (!qIsFinite(b2))
                    intersect = (1.f / m1) * XFixedToDouble(edgeK->p1.x) + b1;
                else
                    intersect = (b1*m1 - b2*m2) / (m1 - m2);

 		if (intersect > y && intersect < next_y)
		    next_y = intersect;
	    }
	}

        XFixed yf, next_yf;
        yf = qrealToXFixed(y);
        next_yf = qrealToXFixed(next_y);

        if (yf == next_yf) {
            y = currentY = next_y;
            continue;
        }

#ifdef QT_DEBUG_TESSELATOR
        qDebug("###> y = %f, next_y = %f, %d active edges", y, next_y, aet.size());
        qDebug("===> edges");
        dump_edges(et);
        qDebug("===> active edges");
        dump_edges(aet);
#endif
	// calc intersection points
 	QVarLengthArray<QIntersectionPoint> isects(aet.size()+1);
 	for (int i = 0; i < isects.size()-1; ++i) {
            const QEdge *edge = aet.at(i);
 	    isects[i].x = (edge->p1.x != edge->p2.x) ?
			  ((y - edge->b)*edge->m) : XFixedToDouble(edge->p1.x);
	    isects[i].edge = edge;
	}

	if (isects.size()%2 != 1)
	    qFatal("%s: number of intersection points must be odd", Q_FUNC_INFO);

	// sort intersection points
 	qSort(&isects[0], &isects[isects.size()-1], compareIntersections);
//         qDebug() << "INTERSECTION_POINTS:";
//  	for (int i = 0; i < isects.size(); ++i)
//             qDebug() << isects[i].edge << isects[i].x;

        if (winding) {
            // winding fill rule
            for (int i = 0; i < isects.size()-1;) {
                int winding = 0;
                const QEdge *left = isects[i].edge;
                const QEdge *right = 0;
                winding += isects[i].edge->winding;
                for (++i; i < isects.size()-1 && winding != 0; ++i) {
                    winding += isects[i].edge->winding;
                    right = isects[i].edge;
                }
                if (!left || !right)
                    break;
                //painter.addTrapezoid(&toXTrapezoid(yf, next_yf, *left, *right));
                traps->append(toXTrapezoid(yf, next_yf, *left, *right));
            }
        } else {
            // odd-even fill rule
            for (int i = 0; i < isects.size()-2; i += 2) {
                //painter.addTrapezoid(&toXTrapezoid(yf, next_yf, *isects[i].edge, *isects[i+1].edge));
                traps->append(toXTrapezoid(yf, next_yf, *isects[i].edge, *isects[i+1].edge));
            }
        }
	y = currentY = next_y;
    }

#ifdef QT_DEBUG_TESSELATOR
    qDebug("==> number of trapezoids: %d - edge table size: %d\n", traps->size(), et.size());

    for (int i = 0; i < traps->size(); ++i)
        dump_trap(traps->at(i));
#endif

    // optimize by unifying trapezoids that share left/right lines
    // and have a common top/bottom edge
//     for (int i = 0; i < tps.size(); ++i) {
// 	for (int k = i+1; k < tps.size(); ++k) {
// 	    if (i != k && tps.at(i).right == tps.at(k).right
// 		&& tps.at(i).left == tps.at(k).left
// 		&& (tps.at(i).top == tps.at(k).bottom
// 		    || tps.at(i).bottom == tps.at(k).top))
// 	    {
// 		tps[i].bottom = tps.at(k).bottom;
// 		tps.removeAt(k);
//                 i = 0;
// 		break;
// 	    }
// 	}
//     }
    //static int i = 0;
    //QImage img = painter.end();
    //img.save(QString("res%1.png").arg(i++), "PNG");
}
Ejemplo n.º 9
0
void
PixmapRenderer::drawPixmap(
	QPainter& painter, QPixmap const& pixmap)
{
#if !defined(Q_WS_X11)
	drawPixmapNoXRender(painter, pixmap);
#else
	QPaintDevice* const dev = painter.device();
	
	QPoint offset; // Both x and y will be either zero or negative.
	QPaintDevice* const redir_dev = QPainter::redirected(painter.device(), &offset);
	QPaintDevice* const paint_dev = redir_dev ? redir_dev : dev;

#if defined(ENABLE_OPENGL)
	if (dynamic_cast<QGLWidget*>(paint_dev)) {
		drawPixmapNoXRender(painter, pixmap);
		return;
	}
#endif

	QRect const device_rect(
		QRect(0, 0, dev->width(), dev->height()).translated(-offset)
	);
	
	QRectF const src_rect(pixmap.rect());
	
	Display* const dpy = QX11Info::display();
	Picture const src_pict = pixmap.x11PictureHandle();
	Picture dst_pict = 0;
	if (QWidget* widget = dynamic_cast<QWidget*>(paint_dev)) {
		dst_pict = widget->x11PictureHandle();
	} else if (QPixmap* pixmap = dynamic_cast<QPixmap*>(paint_dev)) {
		dst_pict = pixmap->x11PictureHandle();
	}
	
	if (!dst_pict) {
		drawPixmapNoXRender(painter, pixmap);
		return;
	}
	
	// Note that device transform already accounts for offset
	// within a destination surface.
	QTransform const src_to_dst(painter.deviceTransform());
	QTransform const dst_to_src(src_to_dst.inverted());
	QPolygonF const dst_poly(src_to_dst.map(src_rect));
	
	XTransform xform = {{
		{
			XDoubleToFixed(dst_to_src.m11()),
			XDoubleToFixed(dst_to_src.m21()),
			XDoubleToFixed(dst_to_src.m31())
		},
		{
			XDoubleToFixed(dst_to_src.m12()),
			XDoubleToFixed(dst_to_src.m22()),
			XDoubleToFixed(dst_to_src.m32())
		},
		{
			XDoubleToFixed(dst_to_src.m13()),
			XDoubleToFixed(dst_to_src.m23()),
			XDoubleToFixed(dst_to_src.m33())
		}
	}};
	
	XRenderSetPictureTransform(dpy, src_pict, &xform);

	char const* filter = "fast";
	if (painter.testRenderHint(QPainter::SmoothPixmapTransform)) {
		filter = "good";
	}
	
	XRenderSetPictureFilter(dpy, src_pict, filter, 0, 0);
	
	QRectF const dst_rect_precise(dst_poly.boundingRect());
	QRect const dst_rect_fitting(
		QPoint(
			int(ceil(dst_rect_precise.left())),
			int(ceil(dst_rect_precise.top()))
		),
		QPoint(
			int(floor(dst_rect_precise.right())) - 1,
			int(floor(dst_rect_precise.bottom())) - 1
		)
	);
	QRect dst_bounding_rect(device_rect);
	if (painter.hasClipping()) {
		QRect const clip_rect(
			src_to_dst.map(painter.clipPath()).boundingRect().toRect()
		);
		dst_bounding_rect = dst_bounding_rect.intersected(clip_rect);
	}
	QRect const dst_rect(dst_rect_fitting.intersect(dst_bounding_rect));
	
	// Note that XRenderComposite() expects destination coordinates
	// everywhere, even for source picture origin.
	XRenderComposite(
		dpy, PictOpSrc,
		src_pict, 0, dst_pict, dst_rect.left(), dst_rect.top(), 0, 0,
		dst_rect.left(), dst_rect.top(), dst_rect.width(), dst_rect.height()
	);
#endif
}
Ejemplo n.º 10
0
pictw_t *
simg_postprocess(session_t *ps, pictw_t *src, enum pict_posp_mode mode,
		int twidth, int theight, enum align alg, enum align valg,
		const XRenderColor *pc) {
	static const XRenderColor XRC_TRANS = {
		.red = 0, .green = 0, .blue = 0, .alpha = 0
	};
	if (!pc) pc = &XRC_TRANS;

	const int depth = 32;
	pictw_t *dest = NULL;
	bool transformed = false;

	if (!src) {
		if (twidth && theight) {
			if (!(dest = create_pictw(ps, twidth, theight, depth)))
				printfef("(): Failed to create Picture.");
			else
				XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, 0, 0,
						twidth, theight);
		}
		goto simg_postprocess_end;
	}

	if (!(twidth || theight)
			|| (twidth == src->width && theight == src->height))
		return src;

	// Determine composite paramaters. We have to do this before create
	// Picture because the width/height may need to be calculated.
	int width = src->width, height = src->height;
	if (!twidth) twidth = (double) theight / height * width;
	else if (!theight) theight = (double) twidth / width * height;
	double ratio_x = 1.0, ratio_y = 1.0;
	switch (mode) {
		case PICTPOSP_ORIG: break;
		case PICTPOSP_TILE: break;
		case PICTPOSP_SCALE:
		case PICTPOSP_SCALEK:
		case PICTPOSP_SCALEE:
		case PICTPOSP_SCALEEK:
							{
								if (twidth) ratio_x = (double) twidth / width;
								if (theight) ratio_y = (double) theight / height;
								if (PICTPOSP_SCALEK == mode || PICTPOSP_SCALEEK == mode)
									ratio_x = ratio_y = MIN(ratio_x, ratio_y);
								if (PICTPOSP_SCALEE == mode || PICTPOSP_SCALEEK == mode) {
									ratio_x = MAX(1.0f, ratio_x);
									ratio_y = MAX(1.0f, ratio_y);
								}
								width *= ratio_x;
								height *= ratio_y;
							}
							break;
		default:            assert(0); break;
	}

	if (!(dest = create_pictw(ps, twidth, theight, depth))) {
		printfef("(): Failed to create Picture.");
		goto simg_postprocess_end;
	}

	int x = 0, y = 0;
	int num_x = 1, num_y = 1;
	if (PICTPOSP_TILE == mode) {
	    // num_x = ceil((float) twidth / width);
	    // num_y = ceil((float) theight / height);
	    num_x = twidth / width;
	    num_y = theight / height;
	}
	switch (alg) {
		case ALIGN_LEFT:  break;
		case ALIGN_RIGHT: x = twidth - width * num_x; break;
		case ALIGN_MID:   x = (twidth - width * num_x) / 2; break;
	};
	switch (valg) {
		case ALIGN_LEFT:  break;
		case ALIGN_RIGHT: y = theight - height * num_y; break;
		case ALIGN_MID:   y = (theight - height * num_y) / 2; break;
	};
	x = MAX(x, 0);
	y = MAX(y, 0);
	int x2 = MIN(x + width * num_x, twidth),
			y2 = MIN(y + height * num_y, theight);
	/* if (pc->alpha) */ {
		if (src->depth >= 32)
			XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, 0, 0,
					twidth, theight);
		else {
			XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, 0, 0,
					twidth, y);
			XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, 0, y2,
					twidth, theight - y2);
			XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, 0, y,
					x, y2 - y);
			XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, x2, y,
					twidth - x2, y2 - y);
		}
	}
	if (src->pict) {
		if (1.0 != ratio_x || 1.0 != ratio_y) {
			XTransform transform = { .matrix = {
				{ XDoubleToFixed(1.0 / ratio_x), XDoubleToFixed(0.0), XDoubleToFixed(0.0) },
				{ XDoubleToFixed(0.0), XDoubleToFixed(1.0 / ratio_y), XDoubleToFixed(0.0) },
				{ XDoubleToFixed(0.0), XDoubleToFixed(0.0), XDoubleToFixed(1.0) },
			} };
			transformed = true;
			XRenderSetPictureTransform(ps->dpy, src->pict, &transform);
		}
Ejemplo n.º 11
0
int X11Grabber::grabFrame(Image<ColorRgb> & image)
{
	if (_XRenderAvailable && !_useXGetImage)
	{
		double scale_x = static_cast<double>(_windowAttr.width / _horizontalDecimation) / static_cast<double>(_windowAttr.width);
		double scale_y = static_cast<double>(_windowAttr.height / _verticalDecimation) / static_cast<double>(_windowAttr.height);
		double scale = std::min(scale_y, scale_x);
		
		_transform =
		{
			{
				{
					XDoubleToFixed(1),
					XDoubleToFixed(0),
					XDoubleToFixed(0)
				},
				{
					XDoubleToFixed(0),
					XDoubleToFixed(1),
					XDoubleToFixed(0)
				},
				{
					XDoubleToFixed(0),
					XDoubleToFixed(0),
					XDoubleToFixed(scale)
				}
			}
		};
		
		XRenderSetPictureTransform (_x11Display, _srcPicture, &_transform);
		
		XRenderComposite( _x11Display,					// dpy
					PictOpSrc,				// op
					_srcPicture,				// src
					None,					// mask
					_dstPicture,				// dst
					_cropLeft / _horizontalDecimation,	// src_x _cropLeft
					_cropTop / _verticalDecimation,		// src_y _cropTop
					0,					// mask_x
					0,					// mask_y
					0,					// dst_x
					0,					// dst_y
					_croppedWidth,				// width
					_croppedHeight);			// height
    
		XSync(_x11Display, False);
		
		if (_XShmAvailable)
		{
			XShmGetImage(_x11Display, _pixmap, _xImage, 0, 0, AllPlanes);
		}
		else
		{
			_xImage = XGetImage(_x11Display, _pixmap, 0, 0, _croppedWidth, _croppedHeight, AllPlanes, ZPixmap);   
		}
	}
	else
	{
		if (_XShmAvailable && !_useXGetImage) {
			XShmGetImage(_x11Display, _window, _xImage, _cropLeft, _cropTop, AllPlanes);
		}
		else
		{
			_xImage = XGetImage(_x11Display, _window, _cropLeft, _cropTop, _croppedWidth, _croppedHeight, AllPlanes, ZPixmap);
		}
	}

	if (_xImage == nullptr)
	{
		Error(_log, "Grab Failed!");
		return -1;
	}

	_imageResampler.processImage(reinterpret_cast<const uint8_t *>(_xImage->data), _xImage->width, _xImage->height, _xImage->bytes_per_line, PIXELFORMAT_BGR32, image);

	return 0;
}
Ejemplo n.º 12
0
void Canvas::copyScaleCanvas(const Canvas* canvas, const Rect& src, const Rect& dst)
{
    if (src.size == dst.size)
    {
        copyCanvas(canvas, src, dst.origin);
        return;
    }

    if (dst.size.w <= 0 || dst.size.h <= 0)
        return;

    XTransform xform = {{
        { XDoubleToFixed((double)src.size.w / dst.size.w), XDoubleToFixed(0), XDoubleToFixed(src.origin.x) },
        { XDoubleToFixed(0), XDoubleToFixed((double)src.size.h / dst.size.h), XDoubleToFixed(src.origin.y) },
        { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) },
    }};
    XRenderSetPictureTransform(display()->xdisplay(), canvas->xpicture(), &xform);

    Point offset = absolutePosition();

    XRenderComposite(
        display()->xdisplay(), PictOpOver,
        canvas->xpicture(), None, xpicture(),
        0, 0,
        0, 0,
        dst.origin.x + offset.x, dst.origin.y + offset.y,
        dst.size.w, dst.size.h
    );

    XTransform identity = {{
        { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) },
        { XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0) },
        { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) },
    }};
    XRenderSetPictureTransform(display()->xdisplay(), canvas->xpicture(), &identity);
}
Ejemplo n.º 13
0
void Canvas::copyRotatedCanvas(const Canvas* canvas, const Rect& src, const Point& origin)
{
    XTransform xform = {{
        { XDoubleToFixed(0), XDoubleToFixed(-1), XDoubleToFixed(0) },
        { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) },
        { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) },
    }};
    XRenderSetPictureTransform(display()->xdisplay(), canvas->xpicture(), &xform);

    Point offset = absolutePosition();

    XRenderComposite(
        display()->xdisplay(), PictOpOver,
        canvas->xpicture(), None, xpicture(),
//        src.origin.x, src.origin.y,
//        0, 0,
//        origin.x + offset.x, origin.y + offset.y,
//        src.size.w, src.size.h
        src.origin.x, -src.size.w,
        0, 0,
        origin.x + offset.x, origin.y + offset.y,
        src.size.w, src.size.h
    );

    XTransform identity = {{
        { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) },
        { XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0) },
        { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) },
    }};
    XRenderSetPictureTransform(display()->xdisplay(), canvas->xpicture(), &identity);
}
Ejemplo n.º 14
0
Archivo: do_traps.c Proyecto: aosm/X11
int
InitFixedTrapezoids(XParms xp, Parms p, int reps)
{
    int     i, numTraps;
    int     rows;
    int     x, y;
    int     size, skew;
    XTrapezoid	*curTrap;
    XRenderColor	color;

    pgc = xp->fggc;

    size = p->special;
    numTraps = p->objects;
    traps = (XTrapezoid *)malloc(numTraps * sizeof(XTrapezoid));
    curTrap = traps;
    x = size;
    y = 0;
    rows = 0;
    skew = size;
    aadraw = XftDrawCreate (xp->d, xp->w, 
			    xp->vinfo.visual, 
			    xp->cmap);
    if (p->font && !strcmp (p->font, "add"))
    {
	XRenderPictFormat   templ;
	templ.type = PictTypeDirect;
	templ.depth = 8;
	templ.direct.alpha = 0;
	templ.direct.alphaMask = 0xff;
	maskFormat = XRenderFindFormat (xp->d, 
					PictFormatType |
					PictFormatDepth |
					PictFormatAlpha |
					PictFormatAlphaMask,
					&templ,
					0);
    }
    else
	maskFormat = 0;
    color.red = 0;
    color.green = 0;
    color.blue = 0;
    color.alpha = 0xffff;
    if (!XftColorAllocValue (xp->d,
			     xp->vinfo.visual, 
			     xp->cmap,
			     &color, &aablack))
    {
	XftDrawDestroy (aadraw);
	aadraw = 0;
	return 0;
    }
    color.red = 0xffff;
    color.green = 0xffff;
    color.blue = 0xffff;
    color.alpha = 0xffff;
    if (!XftColorAllocValue (xp->d,
			     xp->vinfo.visual, 
			     xp->cmap,
			     &color, &aawhite))
    {
	XftDrawDestroy (aadraw);
	aadraw = 0;
	return 0;
    }

    for (i = 0; i != p->objects; i++, curTrap ++) {
	curTrap->top = XDoubleToFixed (y);
	curTrap->bottom = XDoubleToFixed (y + size);
	curTrap->left.p1.x = XDoubleToFixed (x - skew);
	curTrap->left.p1.y = XDoubleToFixed (y);
	curTrap->left.p2.x = XDoubleToFixed (x + skew - size);
	curTrap->left.p2.y = XDoubleToFixed (y + size);
	
	curTrap->right.p1.x = XDoubleToFixed (x - skew + size);
	curTrap->right.p1.y = XDoubleToFixed (y);
	curTrap->right.p2.x = XDoubleToFixed (x + skew);
	curTrap->right.p2.y = XDoubleToFixed (y + size);
	
	skew--;
	if (skew < 0) skew = size;

	y += size;
	rows++;
	if (y + size > HEIGHT || rows == MAXROWS) {
	    rows = 0;
	    y = 0;
	    x += 2 * size;
	    if (x + size > WIDTH) {
		x = size;
	    }
	}
    }

    
    SetFillStyle(xp, p);
    return reps;
}
Ejemplo n.º 15
0
void
XRenderCompositeDoublePoly (Display		    *dpy,
			    int			    op,
			    Picture		    src,
			    Picture		    dst,
			    _Xconst XRenderPictFormat	*maskFormat,
			    int			    xSrc,
			    int			    ySrc,
			    int			    xDst,
			    int			    yDst,
			    _Xconst XPointDouble    *fpoints,
			    int			    npoints,
			    int			    winding)
{
    Edge	    *edges;
    XTrapezoid	    *traps;
    int		    i, nedges, ntraps;
    XFixed	    x, y, prevx = 0, prevy = 0, firstx = 0, firsty = 0;
    XFixed	    top = 0, bottom = 0;	/* GCCism */

    edges = (Edge *) Xmalloc (npoints * sizeof (Edge) +
			      (npoints * npoints * sizeof (XTrapezoid)));
    if (!edges)
	return;
    traps = (XTrapezoid *) (edges + npoints);
    nedges = 0;
    for (i = 0; i <= npoints; i++)
    {
	if (i == npoints)
	{
	    x = firstx;
	    y = firsty;
	}
	else
	{
	    x = XDoubleToFixed (fpoints[i].x);
	    y = XDoubleToFixed (fpoints[i].y);
	}
	if (i)
	{
	    if (y < top)
		top = y;
	    else if (y > bottom)
		bottom = y;
	    if (prevy < y)
	    {
		edges[nedges].edge.p1.x = prevx;
		edges[nedges].edge.p1.y = prevy;
		edges[nedges].edge.p2.x = x;
		edges[nedges].edge.p2.y = y;
		edges[nedges].clockWise = True;
		nedges++;
	    }
	    else if (prevy > y)
	    {
		edges[nedges].edge.p1.x = x;
		edges[nedges].edge.p1.y = y;
		edges[nedges].edge.p2.x = prevx;
		edges[nedges].edge.p2.y = prevy;
		edges[nedges].clockWise = False;
		nedges++;
	    }
	    /* drop horizontal edges */
	}
	else
	{
	    top = y;
	    bottom = y;
	    firstx = x;
	    firsty = y;
	}
	prevx = x;
	prevy = y;
    }
    ntraps = XRenderComputeTrapezoids (edges, nedges, winding, traps);
    /* XXX adjust xSrc/xDst */
    XRenderCompositeTrapezoids (dpy, op, src, dst, maskFormat, xSrc, ySrc, traps, ntraps);
    Xfree (edges);
}
Ejemplo n.º 16
0
void Thumbnail::onResize()
{
    Image* oldImage = _image;

    if (_image)
    {
        XftDrawDestroy(_xftDraw);
        XFreeGC(_dpy, _gc);
    }

    _image = new Image(_dpy, _width, _height);
    _gc = XCreateGC(_dpy, _image->pixmap(), 0, 0);
    XSetGraphicsExposures(_dpy, _gc, false);
    _xftDraw = XftDrawCreate(_dpy, _image->pixmap(), XTools::rgbaVisual()->visual,
                             DefaultColormap(_dpy, DefaultScreen(_dpy)));


    XWindowAttributes attrs;
    XGetWindowAttributes(_dpy, _clientWindow, &attrs);

    _clientWidth = attrs.width;
    _clientHeight= attrs.height;

#ifdef MAEMO4
    _clientDecoX = attrs.x;
    _clientDecoY = attrs.y;
#endif

    int borderWidth = Settings::instance()->borderWidth();
    int headerHeight = Resources::instance()->headerMiddle()->height();


    int oldClientScaledWidth = _clientScaledWidth;
    int oldClientScaledHeight= _clientScaledHeight;

    _clientScaledWidth = _width - 2 * borderWidth;
    _clientScaledHeight = _height - headerHeight - borderWidth;

    double scale = _clientScaledWidth;
    scale /= _clientWidth;

    _clientDecoXScaled = (int)round(scale * _clientDecoX);
    _clientDecoYScaled = (int)round(scale * _clientDecoY);

    _clientOffsetX = borderWidth;
    _clientOffsetY = headerHeight;

    XTransform xform = {{
            { XDoubleToFixed(1.0/scale), XDoubleToFixed(0), XDoubleToFixed(0) },
            { XDoubleToFixed(0), XDoubleToFixed(1.0/scale), XDoubleToFixed(0) },
            { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) },
        }
    };


    XRenderSetPictureTransform(_dpy, _clientPict, &xform);


    if (_minimized && oldImage != 0)
    {
        // Workaround for corner case: if this function is called when
        // client is minimized, we need to rescale cached pixmap, because
        // can't grab new picture from window
        // Yes, this function MAY be called when client is minimised - for
        // example when thumbnail needs to be resized because number of
        // windows changed


        Image* temp = new Image(_dpy, _clientScaledWidth, _clientScaledHeight, 32);


        XTransform xform = {{
                { XDoubleToFixed(((double)oldClientScaledWidth)/_clientScaledWidth), XDoubleToFixed(0), XDoubleToFixed(0) },
                { XDoubleToFixed(0), XDoubleToFixed(((double)oldClientScaledHeight)/_clientScaledHeight), XDoubleToFixed(0) },
                { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) }
            }
        };

        XRenderSetPictureTransform(_dpy, oldImage->picture(), &xform);
        XRenderComposite(_dpy, PictOpSrc,
                         oldImage->picture(), 0, temp->picture(),
                         _clientOffsetX*_clientScaledWidth/oldClientScaledWidth,
                         _clientOffsetY*_clientScaledHeight/oldClientScaledHeight,
                         0, 0,
                         0, 0,
                         _clientScaledWidth, _clientScaledHeight
                        );


        XCopyArea(_dpy, temp->pixmap(), _image->pixmap(), _gc,
                  0, 0,
                  _clientScaledWidth, _clientScaledHeight,
                  _clientOffsetX, _clientOffsetY
                 );

        delete temp;
    }

    _previewValid = false;


    delete oldImage;


    redraw();
}
Ejemplo n.º 17
0
void PreviewCursor::load(const QString &name, const QString &theme)
{
    Display *dpy = QPaintDevice::x11AppDisplay();

    if(m_pict)
        XRenderFreePicture(dpy, m_pict);
    if(m_handle)
        XFreeCursor(dpy, m_handle);
    m_pict = 0;
    m_handle = 0;
    m_width = m_height = 0;

    // Load the preview cursor image
    XcursorImage *image = XcursorLibraryLoadImage(name.latin1(), theme.latin1(), previewSize);

    // If the theme doesn't have this cursor, load the default cursor for now
    if(!image)
        image = XcursorLibraryLoadImage("left_ptr", theme.latin1(), previewSize);

    // TODO The old classic X cursors
    if(!image)
        return;

    // Auto-crop the image (some cursor themes use a fixed image size
    //   for all cursors, and doing this results in correctly centered images)
    cropCursorImage(image);

    m_pict = createPicture(image);
    m_width = image->width;
    m_height = image->height;

    // Scale the image if its height is greater than 2x the requested size
    if(m_height > previewSize * 2.0)
    {
        double factor = double(previewSize * 2.0 / m_height);
        XTransform xform = {{{XDoubleToFixed(1.0), XDoubleToFixed(0), XDoubleToFixed(0)},
                             {XDoubleToFixed(0), XDoubleToFixed(1.0), XDoubleToFixed(0)},
                             {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(factor)}}};
        XRenderSetPictureTransform(dpy, m_pict, &xform);
        m_width = int(m_width * factor);
        m_height = int(m_height * factor);
    }

    // We don't need this image anymore
    XcursorImageDestroy(image);

    // Load the actual cursor we will use
    int size = XcursorGetDefaultSize(dpy);
    XcursorImages *images = XcursorLibraryLoadImages(name.latin1(), theme.latin1(), size);

    if(images)
    {
        m_handle = XcursorImagesLoadCursor(dpy, images);
        XcursorImagesDestroy(images);
    }
    else
    {
        images = XcursorLibraryLoadImages("left_ptr", theme.latin1(), size);
        m_handle = XcursorImagesLoadCursor(dpy, images);
        XcursorImagesDestroy(images);
    }
}