From 79f65d040d72f778f66f8eefdaffb6acd9799a38 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Tue, 10 May 2005 07:59:48 +0000 Subject: Merge of the newly developped postscript code (still not fully functional). --- generic/Window.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 147 insertions(+), 22 deletions(-) (limited to 'generic/Window.c') diff --git a/generic/Window.c b/generic/Window.c index 4486af9..de12103 100644 --- a/generic/Window.c +++ b/generic/Window.c @@ -321,6 +321,54 @@ Query(ZnItem item, return TCL_OK; } +/* + * Compute the transformation to be used and the origin + * of the window (upper left point in item coordinates). + */ +static ZnTransfo * +ComputeTransfoAndOrigin(ZnItem item, + ZnPoint *origin) +{ + WindowItem wind = (WindowItem) item; + ZnTransfo *t; + + /* + * The connected item support anchors, this is checked by configure. + */ + if (item->connected_item != ZN_NO_ITEM) { + ZnTransfo inv; + + item->connected_item->class->GetAnchor(item->connected_item, + wind->connection_anchor, + origin); + + /* GetAnchor return a position in device coordinates not in + * the item coordinate space. To compute the icon origin + * (upper left corner), we must apply the inverse transform + * to the ref point before calling anchor2origin. + */ + ZnTransfoInvert(item->transfo, &inv); + ZnTransformPoint(&inv, origin, origin); + /* + * The relevant transform in case of an attachment is the item + * transform alone. This is case of local coordinate space where + * only the translation is a function of the whole transform + * stack, scale and rotation are reset. + */ + t = item->transfo; + } + else { + origin->x = origin->y = 0; + t = item->wi->current_transfo; + } + + ZnAnchor2Origin(origin, (ZnReal) wind->real_width, (ZnReal) wind->real_height, + wind->anchor, origin); + //origin->x = ZnNearestInt(origin->x); + //origin->y = ZnNearestInt(origin->y); + + return t; +} /* ********************************************************************************** @@ -333,8 +381,10 @@ static void ComputeCoordinates(ZnItem item, ZnBool force) { - ZnWInfo *wi = item->wi; - WindowItem wind = (WindowItem) item; + ZnWInfo *wi = item->wi; + WindowItem wind = (WindowItem) item; + ZnPoint origin; + ZnTransfo *t; ZnResetBBox(&item->item_bounding_box); @@ -357,23 +407,8 @@ ComputeCoordinates(ZnItem item, } } - /* - * The connected item support anchors, this is checked by - * configure. - */ - if (item->connected_item != ZN_NO_ITEM) { - item->connected_item->class->GetAnchor(item->connected_item, - wind->connection_anchor, - &wind->pos_dev); - } - else { - ZnPoint pos; - pos.x = pos.y = 0.0; - ZnTransformPoint(wi->current_transfo, &pos, &wind->pos_dev); - } - - ZnAnchor2Origin(&wind->pos_dev, (ZnReal) wind->real_width, (ZnReal) wind->real_height, - wind->anchor, &wind->pos_dev); + t = ComputeTransfoAndOrigin(item, &origin); + ZnTransformPoint(wi->current_transfo, &origin, &wind->pos_dev); wind->pos_dev.x = ZnNearestInt(wind->pos_dev.x); wind->pos_dev.y = ZnNearestInt(wind->pos_dev.y); @@ -533,10 +568,100 @@ Pick(ZnItem item, * ********************************************************************************** */ -static void -PostScript(ZnItem item, - ZnBool prepass) +#ifdef X_GetImage +static int +xerrorhandler(ClientData client_data, + XErrorEvent *e) { + return 0; +} +#endif + +static int +PostScript(ZnItem item, + ZnBool prepass, + ZnBBox *area) +{ + ZnWInfo *wi = item->wi; + WindowItem wind = (WindowItem) item; + char path[256]; + XImage *ximage; + int result; + ZnPoint origin; + Tcl_DString buffer1, buffer2; +#ifdef X_GetImage + Tk_ErrorHandler handle; +#endif + + sprintf(path, "\n%%%% %s item (%s, %d x %d)\n%.15g %.15g translate\n", + Tk_Class(wind->win), Tk_PathName(wind->win), wind->real_width, wind->real_height, + wind->pos_dev.x, wind->pos_dev.y); + Tcl_AppendResult(wi->interp, path, NULL); + + ComputeTransfoAndOrigin(item, &origin); + + sprintf(path, "/InitialTransform load setmatrix\n" + "%.15g %.15g translate\n" + "1 -1 scale\n", + wind->pos_dev.x, wind->pos_dev.y + wind->real_height); + Tcl_AppendResult(wi->interp, path, NULL); + + /* first try if the widget has its own "postscript" command. If it + * exists, this will produce much better postscript than + * when a pixmap is used. + */ + Tcl_DStringInit(&buffer1); + Tcl_DStringInit(&buffer2); + Tcl_DStringGetResult(wi->interp, &buffer2); + sprintf(path, "%s postscript -prolog 0\n", Tk_PathName(wind->win)); + result = Tcl_Eval(wi->interp, path); + Tcl_DStringGetResult(wi->interp, &buffer1); + Tcl_DStringResult(wi->interp, &buffer2); + Tcl_DStringFree(&buffer2); + + if (result == TCL_OK) { + Tcl_AppendResult(wi->interp, "50 dict begin\nsave\ngsave\n", NULL); + sprintf (path, "0 %d moveto %d 0 rlineto 0 -%d rlineto -%d", + wind->real_height, wind->real_width, wind->real_height, wind->real_width); + Tcl_AppendResult(wi->interp, path, NULL); + Tcl_AppendResult(wi->interp, " 0 rlineto closepath\n", + "1.000 1.000 1.000 setrgbcolor AdjustColor\nfill\ngrestore\n", + Tcl_DStringValue(&buffer1), "\nrestore\nend\n\n\n", NULL); + Tcl_DStringFree(&buffer1); + + return result; + } + Tcl_DStringFree(&buffer1); + + /* + * If the window is off the screen it will generate an BadMatch/XError + * We catch any BadMatch errors here + */ +#ifdef X_GetImage + handle = Tk_CreateErrorHandler(wi->dpy, BadMatch, X_GetImage, -1, + xerrorhandler, (ClientData) wind->win); +#endif + + /* + * Generate an XImage from the window. We can then read pixel + * values out of the XImage. + */ + ximage = XGetImage(wi->dpy, Tk_WindowId(wind->win), 0, 0, (unsigned int) wind->real_width, + (unsigned int) wind->real_height, AllPlanes, ZPixmap); + +#ifdef X_GetImage + Tk_DeleteErrorHandler(handle); +#endif + + if (ximage == NULL) { + return TCL_OK; + } + + result = ZnPostscriptXImage(wi->interp, wind->win, wi->ps_info, ximage, + 0, 0, wind->real_width, wind->real_height); + XDestroyImage(ximage); + + return result; } -- cgit v1.1