⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imagerenderer.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    assert(inRect->width == fromRect->width);    assert(inRect->height == fromRect->height);    if (isNull()) return;    if (!cached)	cache();    if (alpha) {	gdk_gc_set_clip_mask(context->gc, alpha);        gdk_gc_set_clip_origin(context->gc, inRect->x - fromRect->x, inRect->y - fromRect->y);    }    int x, y, sw, sh, sx, sy;    if (!context->clip  || !alpha) {	// no clip or clip but not alpha --> draw directly	x = inRect->x;	y = inRect->y;	sx = fromRect->x;	sy = fromRect->y;	sw = fromRect->width;	sh = fromRect->height;    	gdk_draw_drawable(context->drawable, context->gc, pixmap, sx, sy, x, y, sw, sh);    } else {	// gdk clipping doesn't work when alpha is set --> manual clipping	GdkRegion* dst_region = gdk_region_rectangle(inRect);	gdk_region_intersect(dst_region, context->clip);	GdkRectangle* areas = 0;	gint n_areas = 0;	gdk_region_get_rectangles(dst_region, &areas, &n_areas);	if (n_areas>0) {	    int i;	    for (i=0;i<n_areas;i++) {		x = areas[i].x;		y = areas[i].y;	    		sx = fromRect->x + (x - inRect->x); // source offsets of the image rendering 		sy = fromRect->y + (y - inRect->y); // ie. how many pixels were skipped because of clip		sw = areas[i].width; 		sh = areas[i].height; 		gdk_draw_drawable(context->drawable, context->gc, pixmap, sx, sy, x, y, sw, sh);	    }	}		if (areas) 	    g_free(areas);  // Gdk API doesn't say whether areas allocated regardless of the result or not	gdk_region_destroy(dst_region);    }    if (alpha) {        gdk_gc_set_clip_mask(context->gc, NULL);        gdk_gc_set_clip_origin(context->gc, 0, 0);	gdk_gc_set_clip_region(context->gc, context->clip);    }    if (animate_id) {	static_cast<GdkXftContext*>(context)->regionExpiresAt(&timeout_moment, inRect);    }}void ImageRenderer::stopAnimation(){    removeAnimateTimeout();}void ImageRenderer::tileInRect(GdkRectangle* r, int sx, int sy, CGContextRef context){    assert(r);    assert(context);    if (isNull()) return;    int x, y, w,h;        int sw = wantedSize.width;    int sh = wantedSize.height;    x = r->x;    y = r->y;    w = r->width;    h = r->height;    if (!tileCached)	tileCache();    if (!alpha) {        // special case without alpha, we can use tiling acceleration         // (don't know if this makes a difference) 	// assume gdk clipping works.        gdk_gc_set_tile(context->gc, pixmap);        gdk_gc_set_fill(context->gc, GDK_TILED);                // start copy  from (sx,sy), destination (x,y)         // tile origin is relative to dest. drawable                 gdk_gc_set_ts_origin(context->gc, x - sx, y - sy);        gdk_draw_rectangle(context->drawable, context->gc, TRUE, x, y, w, h);        gdk_gc_set_fill(context->gc, GDK_SOLID);    } else {	// with alpha, do tiling by hand        gdk_gc_set_clip_mask(context->gc, alpha);        // remaining width, height         int rw,rh;        // current x, .. y.  current source x, .. y, .. width, .. height         int cx, cy, csx, csy, csw,csh;                cy = y;        rh = h;        csy = sy;                csh = MIN(sh - sy, h);        while ( csh > 0 ) {            cx = x;            csx = sx;            csw = MIN(sw - sx, w);            // draw row with height of csh pixels, width of w             rw = w;                    while (csw > 0) {                // draw csw x csh pixels                 gdk_gc_set_clip_origin(context->gc, cx - csx, cy - csy);                gdk_draw_drawable(context->drawable,                                  context->gc,                                  pixmap,                                  csx,                                  csy,                                  cx,                                  cy,                                  csw,                                  csh);                csx = 0;                cx += csw;                rw -= csw;                csw = MIN(rw, sw);            }            csy = 0;            cy += csh;            rh -= csh;            csh = MIN(rh, sh);        }	//restore old clip region                gdk_gc_set_clip_mask(context->gc, NULL);	gdk_gc_set_clip_origin(context->gc, 0, 0); // assume that clip origin is always 0,0	gdk_gc_set_clip_region(context->gc, context->clip);    }    if (animate_id) {	static_cast<GdkXftContext*>(context)->regionExpiresAt(&timeout_moment, r);    }}bool ImageRenderer::isNull(){    if (!pixbuf && !anim) return true;    return false;}void ImageRenderer::increaseUseCount(){}void ImageRenderer::decreaseUseCount(){}void ImageRenderer::flushRasterCache(){    invalidate();}void ImageRenderer::animate(){    bool need_update = gdk_pixbuf_animation_iter_advance(iter, NULL);        if (need_update) {	invalidate();	pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(iter);    }}void ImageRenderer::installAnimateTimeout(){    removeAnimateTimeout();    gint timeout = gdk_pixbuf_animation_iter_get_delay_time(iter); // milliseconds    if (timeout) {	animate_id = g_timeout_add(timeout,				   (GSourceFunc)::anim_timeout,				   this);	g_get_current_time(&timeout_moment);	g_time_val_add(&timeout_moment, (timeout*1000)); // microseconds    }    }void ImageRenderer::removeAnimateTimeout(){    if (animate_id != 0) g_source_remove(animate_id);    animate_id = 0;}void ImageRenderer::loaderClosed(){    if (!anim && !pixbuf)	return;    if (gdk_pixbuf_animation_is_static_image(anim)) {	g_object_unref(anim);	anim = 0;	return;    }        iter = gdk_pixbuf_animation_get_iter(anim, NULL);    if (gdk_pixbuf_animation_iter_get_delay_time(iter) <= 0) {	g_object_unref(iter);	g_object_unref(anim);	anim = 0;	iter = 0;	return;    }    invalidate();    g_object_unref(pixbuf);    pixbuf = 0;    installAnimateTimeout();}void ImageRenderer::sizePrepared(int width, int height){    if (wantedSize.width == -1 && wantedSize.height == -1) {	fillGdkRectangle(&wantedSize, 0, 0, width, height);	return;    }    if (wantedSize.width == width && wantedSize.height == height)	return;    gdk_pixbuf_loader_set_size(loader, wantedSize.width, wantedSize.height);}void ImageRenderer::areaPrepared(){    if (!anim) {	anim = gdk_pixbuf_loader_get_animation(loader);	if (anim) 	    g_object_ref(anim);	if (pixbuf) 	    g_object_unref(pixbuf);	pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);	if (pixbuf)	    g_object_ref(pixbuf);    }}void ImageRenderer::areaUpdated(int x, int y, int w, int h){    invalidate();			      }ImageRenderer* ImageRenderer::copy(){    ImageRenderer* r = new ImageRenderer(*this);    return r;}void ImageRenderer::animateTimeout(){    animate_id = 0;    animate();    installAnimateTimeout();}GdkPixbuf* ImageRenderer::handle() const{    if (iter) 	return gdk_pixbuf_animation_iter_get_pixbuf(iter);    return pixbuf;}extern "C"{staticvoidarea_prepared(GdkPixbufLoader *loader, gpointer user_data){    ImageRenderer* d = static_cast<ImageRenderer*>(user_data);    d->areaPrepared();}staticvoidarea_updated(GdkPixbufLoader *loader,	     gint arg1,	     gint arg2,	     gint arg3,	     gint arg4,	     gpointer user_data){    ImageRenderer* d = static_cast<ImageRenderer*>(user_data);    d->areaUpdated(arg1,arg2,arg3,arg4);}staticvoidclosed(GdkPixbufLoader *loader,gpointer user_data){    ImageRenderer* d = static_cast<ImageRenderer*>(user_data);    d->loaderClosed();}staticvoidsize_prepared(GdkPixbufLoader *loader,	      gint width,	      gint height,	      gpointer user_data){    ImageRenderer* d = static_cast<ImageRenderer*>(user_data);    d->sizePrepared(width, height);}staticgbooleananim_timeout(gpointer user_data){    ImageRenderer* d = static_cast<ImageRenderer*>(user_data);    d->animateTimeout();    return FALSE;}} // extern "C"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -