static void updateWindowSvgMatrix(CompWindow *w) { CompMatrix *m; int width, height; SVG_WINDOW(w); width = sw->context->box.extents.x2 - sw->context->box.extents.x1; height = sw->context->box.extents.y2 - sw->context->box.extents.y1; m = &sw->context->texture[0].matrix; *m = sw->context->texture[0].texture.matrix; m->xx *= (float)sw->context->texture[0].width / width; m->yy *= (float)sw->context->texture[0].height / height; m->x0 -= (sw->context->box.extents.x1 * m->xx); m->y0 -= (sw->context->box.extents.y1 * m->yy); m = &sw->context->texture[1].matrix; *m = sw->context->texture[1].texture.matrix; width = sw->context->rect.x2 - sw->context->rect.x1; height = sw->context->rect.y2 - sw->context->rect.y1; m->xx *= (float)sw->context->texture[1].width / width; m->yy *= (float)sw->context->texture[1].height / height; m->x0 -= (sw->context->rect.x1 * m->xx); m->y0 -= (sw->context->rect.y1 * m->yy); }
static bool svgSet (CompAction *action, CompAction::State state, CompOption::Vector &options) { Window xid = CompOption::getIntOptionNamed (options, "window"); CompWindow *w = screen->findWindow (xid); if (w) { decor_point_t p[2]; CompString data; SVG_WINDOW (w); memset (p, 0, sizeof (p)); p[0].gravity = CompOption::getIntOptionNamed (options, "gravity0", GRAVITY_NORTH | GRAVITY_WEST); p[0].x = CompOption::getIntOptionNamed (options, "x0"); p[0].y = CompOption::getIntOptionNamed (options, "y0"); p[1].gravity = CompOption::getIntOptionNamed (options, "gravity1", GRAVITY_SOUTH | GRAVITY_EAST); p[1].x = CompOption::getIntOptionNamed (options, "x1"); p[1].y = CompOption::getIntOptionNamed (options, "y1"); data = CompOption::getStringOptionNamed (options, "data"); sw->setSvg (data, p); } return false; }
static void svgWindowResizeNotify(CompWindow *w, int dx, int dy, int dwidth, int dheight) { SVG_SCREEN(w->screen); SVG_WINDOW(w); if (sw->source) updateWindowSvgContext(w, sw->source); UNWRAP(ss, w->screen, windowResizeNotify); (*w->screen->windowResizeNotify)(w, dx, dy, dwidth, dheight); WRAP(ss, w->screen, windowResizeNotify, svgWindowResizeNotify); }
static void svgFiniWindow(CompPlugin *p, CompWindow *w) { SVG_WINDOW(w); if (sw->source) { rsvg_handle_free(sw->source->svg); free(sw->source); } if (sw->context) { finiSvgTexture(w->screen, &sw->context->texture[0]); free(sw->context); } free(sw); }
static void svgWindowMoveNotify(CompWindow *w, int dx, int dy, Bool immediate) { SVG_SCREEN(w->screen); SVG_WINDOW(w); if (sw->context) { sw->context->box.extents.x1 += dx; sw->context->box.extents.y1 += dy; sw->context->box.extents.x2 += dx; sw->context->box.extents.y2 += dy; updateWindowSvgMatrix(w); } UNWRAP(ss, w->screen, windowMoveNotify); (*w->screen->windowMoveNotify)(w, dx, dy, immediate); WRAP(ss, w->screen, windowMoveNotify, svgWindowMoveNotify); }
static Bool svgSet(CompDisplay *d, CompAction *action, CompActionState state, CompOption *option, int nOption) { CompWindow *w; Window xid; xid = getIntOptionNamed(option, nOption, "window", 0); w = findWindowAtDisplay(d, xid); if (w) { decor_point_t p[2]; char *data; RsvgHandle *svg = NULL; GError *error = NULL; SVG_WINDOW(w); memset(p, 0, sizeof (p)); p[0].gravity = getIntOptionNamed(option, nOption, "gravity0", GRAVITY_NORTH | GRAVITY_WEST); p[0].x = getIntOptionNamed(option, nOption, "x0", 0); p[0].y = getIntOptionNamed(option, nOption, "y0", 0); p[1].gravity = getIntOptionNamed(option, nOption, "gravity1", GRAVITY_SOUTH | GRAVITY_EAST); p[1].x = getIntOptionNamed(option, nOption, "x1", 0); p[1].y = getIntOptionNamed(option, nOption, "y1", 0); data = getStringOptionNamed(option, nOption, "data", 0); if (data) svg = rsvg_handle_new_from_data((guint8 *)data, strlen(data), &error); if (sw->source) { rsvg_handle_free(sw->source->svg); sw->source->svg = svg; } else { sw->source = malloc(sizeof (SvgSource)); if (sw->source) sw->source->svg = svg; } if (sw->source && sw->source->svg) { sw->source->p1 = p[0]; sw->source->p2 = p[1]; sw->source->svg = svg; rsvg_handle_get_dimensions(svg, &sw->source->dimension); updateWindowSvgContext(w, sw->source); } else { if (svg) rsvg_handle_free(svg); if (sw->source) { free(sw->source); sw->source = NULL; } if (sw->context) { finiSvgTexture(w->screen, &sw->context->texture[0]); free(sw->context); sw->context = NULL; } } } return FALSE; }
static void updateWindowSvgContext(CompWindow *w, SvgSource *source) { int x1, y1, x2, y2; SVG_WINDOW(w); if (sw->context) { finiSvgTexture(w->screen, &sw->context->texture[0]); finiSvgTexture(w->screen, &sw->context->texture[1]); } else { sw->context = malloc(sizeof (SvgContext)); if (!sw->context) return; } memset(&sw->context->rect, 0, sizeof (BoxRec)); sw->context->width = 0; sw->context->height = 0; initSvgTexture(w, source, &sw->context->texture[1], 0, 0); sw->context->source = source; sw->context->box.rects = &sw->context->box.extents; sw->context->box.numRects = 1; decor_apply_gravity(source->p1.gravity, source->p1.x, source->p1.y, w->width, w->height, &x1, &y1); decor_apply_gravity(source->p2.gravity, source->p2.x, source->p2.y, w->width, w->height, &x2, &y2); x1 = MAX(x1, 0); y1 = MAX(y1, 0); x2 = MIN(x2, w->width); y2 = MIN(y2, w->height); if (!initSvgTexture(w, source, &sw->context->texture[0], w->width, w->height)) { free(sw->context); sw->context = NULL; } else { renderSvg(w->screen, source, &sw->context->texture[0], 0.0f, 0.0f, 1.0f, 1.0f, w->width, w->height); initSvgTexture(w, source, &sw->context->texture[1], 0, 0); sw->context->box.extents.x1 = x1; sw->context->box.extents.y1 = y1; sw->context->box.extents.x2 = x2; sw->context->box.extents.y2 = y2; sw->context->box.extents.x1 += w->attrib.x; sw->context->box.extents.y1 += w->attrib.y; sw->context->box.extents.x2 += w->attrib.x; sw->context->box.extents.y2 += w->attrib.y; updateWindowSvgMatrix(w); } }
static Bool svgDrawWindow(CompWindow *w, const CompTransform *transform, const FragmentAttrib *attrib, Region region, unsigned int mask) { Bool status; SVG_SCREEN(w->screen); UNWRAP(ss, w->screen, drawWindow); status = (*w->screen->drawWindow)(w, transform, attrib, region, mask); WRAP(ss, w->screen, drawWindow, svgDrawWindow); if (status) { SVG_WINDOW(w); if (mask & PAINT_WINDOW_TRANSFORMED_MASK) region = &infiniteRegion; if (sw->context && region->numRects) { CompTexture *texture = &sw->context->texture[0].texture; CompMatrix *matrix = &sw->context->texture[0].matrix; REGION r; r.rects = &r.extents; r.numRects = 1; r.extents = sw->context->box.extents; if (r.extents.x1 < ss->zoom.x1) r.extents.x1 = ss->zoom.x1; if (r.extents.y1 < ss->zoom.y1) r.extents.y1 = ss->zoom.y1; if (r.extents.x2 > ss->zoom.x2) r.extents.x2 = ss->zoom.x2; if (r.extents.y2 > ss->zoom.y2) r.extents.y2 = ss->zoom.y2; w->vCount = w->indexCount = 0; (*w->screen->addWindowGeometry)(w, matrix, 1, &sw->context->box, region); if (mask & PAINT_WINDOW_TRANSLUCENT_MASK) mask |= PAINT_WINDOW_BLEND_MASK; (*w->screen->drawWindowTexture)(w, texture, attrib, mask); if (r.extents.x1 < r.extents.x2 && r.extents.y1 < r.extents.y2) { float xScale, yScale; float dx, dy; int width, height; int saveFilter; r.extents.x1--; r.extents.y1--; r.extents.x2++; r.extents.y2++; xScale = w->screen->width / (float) (ss->zoom.x2 - ss->zoom.x1); yScale = w->screen->height / (float) (ss->zoom.y2 - ss->zoom.y1); dx = r.extents.x2 - r.extents.x1; dy = r.extents.y2 - r.extents.y1; width = dx * xScale + 0.5f; height = dy * yScale + 0.5f; if (r.extents.x1 != sw->context->rect.x1 || r.extents.y1 != sw->context->rect.y1 || r.extents.x2 != sw->context->rect.x2 || r.extents.y2 != sw->context->rect.y2 || width != sw->context->width || height != sw->context->height) { float x1, y1, x2, y2; sw->context->rect = r.extents; sw->context->width = width; sw->context->height = height; dx = sw->context->box.extents.x2 - sw->context->box.extents.x1; dy = sw->context->box.extents.y2 - sw->context->box.extents.y1; x1 = (r.extents.x1 - sw->context->box.extents.x1) / dx; y1 = (r.extents.y1 - sw->context->box.extents.y1) / dy; x2 = (r.extents.x2 - sw->context->box.extents.x1) / dx; y2 = (r.extents.y2 - sw->context->box.extents.y1) / dy; finiSvgTexture(w->screen, &sw->context->texture[1]); if (initSvgTexture(w, sw->context->source, &sw->context->texture[1], width, height)) { renderSvg(w->screen, sw->context->source, &sw->context->texture[1], x1, y1, x2, y2, width, height); updateWindowSvgMatrix(w); } } texture = &sw->context->texture[1].texture; matrix = &sw->context->texture[1].matrix; w->vCount = w->indexCount = 0; saveFilter = w->screen->filter[SCREEN_TRANS_FILTER]; w->screen->filter[SCREEN_TRANS_FILTER] = COMP_TEXTURE_FILTER_GOOD; (*w->screen->addWindowGeometry)(w, matrix, 1, &r, region); (*w->screen->drawWindowTexture)(w, texture, attrib, mask); w->screen->filter[SCREEN_TRANS_FILTER] = saveFilter; } else if (sw->context->texture[1].width) { finiSvgTexture(w->screen, &sw->context->texture[1]); initSvgTexture(w, sw->source, &sw->context->texture[1], 0, 0); memset(&sw->context->rect, 0, sizeof (BoxRec)); sw->context->width = 0; sw->context->height = 0; } } } return status; }
static Bool svgSet (BananaArgument *arg, int nArg) { CompWindow *w; Window xid; BananaValue *window = getArgNamed ("window", arg, nArg); if (window != NULL) xid = window->i; else xid = 0; w = findWindowAtDisplay (xid); if (w) { decor_point_t p[2]; char *data; RsvgHandle *svg = NULL; GError *error = NULL; SVG_WINDOW (w); memset (p, 0, sizeof (p)); BananaValue *gravity0 = getArgNamed ("gravity0", arg, nArg); if (gravity0 != NULL) p[0].gravity = gravity0->i; else p[0].gravity = GRAVITY_NORTH | GRAVITY_WEST; BananaValue *x0 = getArgNamed ("x0", arg, nArg); if (x0 != NULL) p[0].x = x0->i; else p[0].x = 0; BananaValue *y0 = getArgNamed ("y0", arg, nArg); if (y0 != NULL) p[0].y = y0->i; else p[0].y = 0; BananaValue *gravity1 = getArgNamed ("gravity1", arg, nArg); if (gravity1 != NULL) p[1].gravity = gravity1->i; else p[1].gravity = GRAVITY_SOUTH | GRAVITY_EAST; BananaValue *x1 = getArgNamed ("x1", arg, nArg); if (x0 != NULL) p[1].x = x1->i; else p[1].x = 0; BananaValue *y1 = getArgNamed ("y1", arg, nArg); if (y1 != NULL) p[1].y = y1->i; else p[1].y = 0; BananaValue *b_data = getArgNamed ("data", arg, nArg); if (b_data != NULL) data = b_data->s; else data = NULL; if (data) svg = rsvg_handle_new_from_data ((guint8 *) data, strlen (data), &error); if (sw->source) { rsvg_handle_free (sw->source->svg); sw->source->svg = svg; } else { sw->source = malloc (sizeof (SvgSource)); if (sw->source) sw->source->svg = svg; } if (sw->source && sw->source->svg) { sw->source->p1 = p[0]; sw->source->p2 = p[1]; sw->source->svg = svg; rsvg_handle_get_dimensions (svg, &sw->source->dimension); updateWindowSvgContext (w, sw->source); } else { if (svg) rsvg_handle_free (svg); if (sw->source) { free (sw->source); sw->source = NULL; } if (sw->context) { finiSvgTexture (w->screen, &sw->context->texture[0]); free (sw->context); sw->context = NULL; } } } return FALSE; }