Esempio n. 1
0
double compute_area(XTrapezoid *trap)
{
    double x1 = compute_x_at(trap->top, trap->left.p1, trap->left.p2);
    double x2 = compute_x_at(trap->top, trap->right.p1, trap->right.p2);
    double x3 = compute_x_at(trap->bottom, trap->left.p1, trap->left.p2);
    double x4 = compute_x_at(trap->bottom, trap->right.p1, trap->right.p2);

    double top = XFixedToDouble(trap->top);
    double bottom = XFixedToDouble(trap->bottom);
    double h = bottom - top;

    double top_base = x2 - x1;
    double bottom_base = x4 - x3;

    if ((top_base < 0 && bottom_base > 0)
        || (top_base > 0 && bottom_base < 0)) {
        double y0 = top_base*h/(top_base - bottom_base) + top;
        double area = qAbs(top_base * (y0 - top) / 2.);
        area += qAbs(bottom_base * (bottom - y0) /2.);
        return area;
    }


    return 0.5 * h * qAbs(top_base + bottom_base);
}
Esempio n. 2
0
static void dump_edges(const QList<const QEdge *> &et)
{
    for (int x = 0; x < et.size(); ++x) {
        qDebug() << "edge#" << x << et.at(x) << "("
                 << XFixedToDouble(et.at(x)->p1.x)
                 << XFixedToDouble(et.at(x)->p1.y)
                 << ") ("
                 << XFixedToDouble(et.at(x)->p2.x)
                 << XFixedToDouble(et.at(x)->p2.y)
                 << ") b: " << et.at(x)->b << "m:" << et.at(x)->m;
    }
}
Esempio n. 3
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();
    }
Esempio n. 4
0
static inline bool compareIntersections(const QIntersectionPoint &i1, const QIntersectionPoint &i2)
{
    if (qAbs(i1.x - i2.x) > 0.01) { // x != other.x in 99% of the cases
        return i1.x < i2.x;
    } else {
        qreal x1 = (i1.edge->p1.x != i1.edge->p2.x) ?
                   ((currentY+1 - i1.edge->b)*i1.edge->m) : XFixedToDouble(i1.edge->p1.x);
        qreal x2 = (i2.edge->p1.x != i2.edge->p2.x) ?
                   ((currentY+1 - i2.edge->b)*i2.edge->m) : XFixedToDouble(i2.edge->p1.x);
//         qDebug() << ">>>" << currentY << i1.edge << i2.edge << x1 << x2;
        return x1 < x2;
    }
}
Esempio n. 5
0
static void dump_trap(const XTrapezoid &t)
{
    qDebug() << "trap# t=" << t.top/65536.0 << "b=" << t.bottom/65536.0  << "h="
             << XFixedToDouble(t.bottom - t.top) << "\tleft p1: ("
             << XFixedToDouble(t.left.p1.x) << ","<< XFixedToDouble(t.left.p1.y)
             << ")" << "\tleft p2: (" << XFixedToDouble(t.left.p2.x) << ","
             << XFixedToDouble(t.left.p2.y) << ")" << "\n\t\t\t\tright p1:("
             << XFixedToDouble(t.right.p1.x) << "," << XFixedToDouble(t.right.p1.y) << ")"
             << "\tright p2:(" << XFixedToDouble(t.right.p2.x) << ","
             << XFixedToDouble(t.right.p2.y) << ")";
}
Esempio n. 6
0
static Bool transform_point (XTransform *transform, double *xp, double *yp) {
    double  vector[3];
    double  result[3];
    int     i, j;
    double  v;

    vector[0] = *xp;
    vector[1] = *yp;
    vector[2] = 1;
    for (j = 0; j < 3; j++)
    {
      v = 0;
      for (i = 0; i < 3; i++) {
          v += (XFixedToDouble (transform->matrix[j][i]) * vector[i]);
      }
      if (v > 32767 || v < -32767) {
          return False;
      }
      result[j] = v;
    }
    if (!result[2]) {
      return False;
    }
    for (j = 0; j < 2; j++) {
      vector[j] = result[j] / result[2];
    }
    *xp = vector[0];
    *yp = vector[1];
    return True;
}
Esempio n. 7
0
static INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix)
{
   if (!trans)
      return FALSE;

   matrix[0] = XFixedToDouble(trans->matrix[0][0]);
   matrix[3] = XFixedToDouble(trans->matrix[0][1]);
   matrix[6] = XFixedToDouble(trans->matrix[0][2]);

   matrix[1] = XFixedToDouble(trans->matrix[1][0]);
   matrix[4] = XFixedToDouble(trans->matrix[1][1]);
   matrix[7] = XFixedToDouble(trans->matrix[1][2]);

   matrix[2] = XFixedToDouble(trans->matrix[2][0]);
   matrix[5] = XFixedToDouble(trans->matrix[2][1]);
   matrix[8] = XFixedToDouble(trans->matrix[2][2]);

   return TRUE;
}
Esempio n. 8
0
static double compute_x_at(XFixed y, XPointFixed p1, XPointFixed p2)
{
    double d = XFixedToDouble(p2.x - p1.x);
    return
        XFixedToDouble(p1.x) + d*XFixedToDouble(y - p1.y)/XFixedToDouble(p2.y - p1.y);
}
Esempio n. 9
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");
}
Esempio n. 10
0
static double
XRenderComputeXIntercept (XLineFixed *l, double inverse_slope)
{
    return XFixedToDouble (l->p1.x) - inverse_slope * XFixedToDouble (l->p1.y);
}
Esempio n. 11
0
static double
XRenderComputeInverseSlope (XLineFixed *l)
{
    return (XFixedToDouble (l->p2.x - l->p1.x) / 
	    XFixedToDouble (l->p2.y - l->p1.y));
}
Esempio n. 12
0
int
apply_transform (Display *display,
                 Window root,
                 RRCrtc crtcnum,
                 const char *input_name)
{
    int ret;

    ret = EXIT_SUCCESS;

    if (ret != EXIT_FAILURE) {
        XRRScreenConfiguration *sconf;
        XRRScreenResources *res;
        XRRCrtcInfo *crtc;
        XRRCrtcTransformAttributes *transform;
        Status status;
        double amx[3][3];
        double sina, cosa;
        double hscale, vscale, hoffs, voffs;
        XRRScreenSize *ssize;
        int nsizes;
        Rotation srot;

        res = XRRGetScreenResourcesCurrent (display, root);
        sconf = XRRGetScreenInfo (display, root);
        ssize = XRRConfigSizes(sconf, &nsizes) + XRRConfigCurrentConfiguration (sconf, &srot);
        crtc = XRRGetCrtcInfo (display, res, crtcnum);

        if (verbose) {
            fprintf (stderr, "Screen: (%u, %u) 0x%02x\n", ssize->width, ssize->height, srot);
            fprintf (stderr, "CRTC: (%i, %i) (%u, %u) 0x%02x\n", crtc->x, crtc->y, crtc->width, crtc->height, crtc->rotation);
        }

        switch (srot) {
        case RR_Rotate_0:
        case RR_Rotate_180:
            hscale = (double)crtc->width/(double)ssize->width;
            vscale = (double)crtc->height/(double)ssize->height;
            break;
        case RR_Rotate_90:
        case RR_Rotate_270:
            hscale = (double)crtc->width/(double)ssize->height;
            vscale = (double)crtc->height/(double)ssize->width;
            break;
        default:
            ret = EXIT_FAILURE;
            fprintf (stderr, "The screen rotation/reflection 0x%02x is not supported yet. Sorry.\n", srot);
        }

        switch (crtc->rotation) {
        case RR_Rotate_0:
            sina = 0;
            cosa = 1;
            hoffs = 0;
            voffs = 0;
            break;
        case RR_Rotate_90:
            sina = 1;
            cosa = 0;
            hoffs = 1;
            voffs = 0;
            break;
        case RR_Rotate_180:
            sina = 0;
            cosa = -1;
            hoffs = 1;
            voffs = 1;
            break;
        case RR_Rotate_270:
            sina = -1;
            cosa = 0;
            hoffs = 0;
            voffs = 1;
            break;
        default:
            ret = EXIT_FAILURE;
            fprintf (stderr, "The rotation/reflection 0x%02x is not supported yet. Sorry.\n", crtc->rotation);
        }

        if (ret != EXIT_FAILURE) {
            amx[0][0] = cosa*hscale;
            amx[0][1] = -sina*hscale;
            amx[0][2] = hoffs*hscale + crtc->x/ssize->width;
            amx[1][0] = sina*vscale;
            amx[1][1] = cosa*vscale;
            amx[1][2] = voffs*vscale + crtc->y/ssize->height;
            amx[2][0] = 0;
            amx[2][1] = 0;
            amx[2][2] = 1;

            status = XRRGetCrtcTransform (display, crtcnum, &transform);
            if (!status) {
                fprintf (stderr, "Unable to get the current transformation\n");
                ret = EXIT_FAILURE;
            }
        }

        if (ret != EXIT_FAILURE) {
            static char strmx[3][3][8];
            static const char *args[11];
            double mx[3][3];
            int i, j;

            for (j = 0; j < 3; j++) {
                for (i = 0; i < 3; i++) {
                    XFixed fv = transform->currentTransform.matrix[j][i];
                    mx[j][i] = XFixedToDouble (fv);
                }
            }

            args[0] = input_name;
            args[1] = "Coordinate Transformation Matrix";
            for (j = 0; j < 3; j++) {
                for (i = 0; i < 3; i++) {
                    double v = mx[0][i]*amx[j][0] + mx[1][i]*amx[j][1] + mx[2][i]*amx[j][2];
                    snprintf (strmx[j][i], 8, "%8.6f", v);
                    args[2 + i + j*3] = strmx[j][i];
                }
            }
            if (verbose) {
                fprintf (stderr, "Debug: set-float-prop");
                for (i = 0; i < 11; i++) {
                    fprintf (stderr, " %s", args[i]);
                }
                fprintf (stderr, "\n");
            }
            ret = set_float_prop(display, 11, args, "set-float-prop", ": error calling function, please report a bug.");
            XFree (transform);
        }
        XRRFreeCrtcInfo (crtc);
        XRRFreeScreenResources (res);
        XRRFreeScreenConfigInfo (sconf);
    }

    return ret;
}