#include "parse.h" void frame_disp_all(Frame *f) { frame_disp_area(f, 0, 0, f->r_w, f->r_h); } void frame_scroll(Frame *f, int dx, int dy) { int scr_y, scr_x; scr_x = f->scr_x + dx; scr_y = f->scr_y + dy; if (scr_x > f->formatted_width - f->width) scr_x = f->formatted_width - f->width; if (scr_x < 0) scr_x = 0; if (scr_y > f->formatted_height - f->height) scr_y = f->formatted_height - f->height; if (scr_y < 0) scr_y = 0; if (scr_x != f->scr_x || scr_y != f->scr_y) { frame_set_pos(f, scr_x, scr_y); frame_expose(f, 0, 0, f->r_w, f->r_h); } } void frame_set_pos(Frame *f, int scr_x, int scr_y) { int dx = f->scr_x - scr_x; int dy = f->scr_y - scr_y; f->scr_x = scr_x; f->scr_y = scr_y; if (abs(dx) >= f->r_w || abs(dy) >= f->r_h) { frame_disp_area(f,0,0,f->r_w,f->r_h); } else if (dy > 0) { if (dx > 0) { XCopyArea(f->dpy, f->backup, f->backup, f->gc, 0, 0, f->r_w - dx, f->r_h - dy, dx, dy); frame_disp_area(f,0,0,f->r_w,dy); frame_disp_area(f,0,dy,dx,f->r_h-dy); } else if (dx < 0) { XCopyArea(f->dpy, f->backup, f->backup, f->gc, -dx, 0, f->r_w + dx, f->r_h - dy, 0, dy); frame_disp_area(f,0,0,f->r_w,dy); frame_disp_area(f,f->r_w+dx,dy,-dx,f->r_h-dy); } else { /* dx == 0 */ XCopyArea(f->dpy, f->backup, f->backup, f->gc, 0, 0, f->r_w, f->r_h - dy, 0, dy); frame_disp_area(f,0,0,f->r_w,dy); } } else if (dy < 0) { if (dx > 0) { XCopyArea(f->dpy, f->backup, f->backup, f->gc, 0, -dy, f->r_w - dx, f->r_h + dy, dx, 0); frame_disp_area(f,0,f->r_h+dy,f->r_w,-dy); frame_disp_area(f,0,0,dx,f->r_h+dy); } else if (dx < 0) { XCopyArea(f->dpy, f->backup, f->backup, f->gc, -dx, -dy, f->r_w + dx, f->r_h + dy, 0, 0); frame_disp_area(f,0,f->r_h+dy,f->r_w,-dy); frame_disp_area(f,f->r_w+dx,0,-dx,f->r_h+dy); } else { /* dx == 0 */ XCopyArea(f->dpy, f->backup, f->backup, f->gc, 0, -dy, f->r_w, f->r_h + dy, 0, 0); frame_disp_area(f,0,f->r_h+dy,f->r_w,-dy); } } else { /* dy == 0 */ if (dx > 0) { XCopyArea(f->dpy, f->backup, f->backup, f->gc, 0, 0, f->r_w - dx, f->r_h, dx, 0); frame_disp_area(f,0,0,dx,f->r_h); } else if (dx < 0) { XCopyArea(f->dpy, f->backup, f->backup, f->gc, -dx, 0, f->r_w + dx, f->r_h, 0, 0); frame_disp_area(f,f->r_w+dx,0,-dx,f->r_h); } } frame_check_area(f); } #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) #endif void frame_check_area(Frame *f) { int x1, y1; HTMLObj *p; if (!f->body) return; p = f->body->next; f->disp_start = NULL; f->disp_end = NULL; while (p != f->body) { y1 = p->y - p->ascent - f->scr_y + f->off_y; x1 = p->x + p->lbearing - f->scr_x + f->off_x; if (y1 < 0) { if (0 > y1 + p->ascent + p->descent) goto next; } else { if (y1 > f->r_h) goto next; } if (x1 < 0) { if (0 > (p->x + p->rbearing - f->scr_x + f->off_x)) goto next; } else { if (x1 > f->r_w) goto next; } if (!f->disp_start) f->disp_start = p; f->disp_end = p; #if 0 goto cont; #endif next: #if 0 if (f->disp_end) if (f->disp_end->y != p->y) break; cont: #endif p = p->next; } if (f->disp_end) f->disp_end = f->disp_end->next; return; } void frame_disp_area(Frame *f, int x, int y, int w, int h) { HTMLObj *p; int x1, y1, w2, h2; if (!f->body) return; p = f->body->next; if (f->bg_image && f->bg_image->pixmap != None) { XSetTile(f->dpy, f->gc, f->bg_image->pixmap); XSetTSOrigin(f->dpy, f->gc, f->off_x - f->scr_x, f->off_y -f->scr_y); XSetFillStyle(f->dpy, f->gc, FillTiled); XFillRectangle(f->dpy, f->backup, f->gc, x, y, w, h); XSetFillStyle(f->dpy, f->gc, FillSolid); } else { XSetForeground(f->dpy, f->gc, f->background); XFillRectangle(f->dpy, f->backup, f->gc, x, y, w, h); } while (p != f->body) { #if 1 y1 = p->y - p->ascent - f->scr_y + f->off_y; x1 = p->x + p->lbearing - f->scr_x + f->off_x; if (y1 < y) { if (y > y1 + p->ascent + p->descent) goto next; y1 = y - y1; h2 = p->height - y1; } else { if (y1 > y + h) goto next; h2 = MIN(h - (y1 - y), p->height); y1 = 0; } if (x1 < x) { if (x > (p->x + p->rbearing - f->scr_x + f->off_x)) goto next; x1 = x - x1; w2 = p->width - x1; } else { if (x1 > x + w) goto next; w2 = MIN(w-(x1 - x), p->width); x1 = 0; } #endif htmlobj_draw(f->dpy, f->backup, f->gc, f->off_x - f->scr_x, f->off_y - f->scr_y , p, x1, y1, w2, h2); next: p = p->next; } return; } void frame_disp_obj(Frame *f, HTMLObj *p) { int x1, y1, w2, h2, x2, y2; if (p->type == HTMLOBJ_NONE) return; y1 = p->y - p->ascent - f->scr_y + f->off_y; x1 = p->x + p->lbearing - f->scr_x + f->off_x; if (y1 < 0) { if (0 > y1 + p->ascent + p->descent) goto next; y1 = - y1; h2 = p->height - y1; } else { if (y1 > f->r_h) goto next; h2 = MIN(f->r_h - y1, p->height); y1 = 0; } if (x1 < 0) { if (0 > (p->x + p->rbearing - f->scr_x + f->off_x)) goto next; x1 = - x1; w2 = p->width - x1; } else { if (x1 > f->r_w) goto next; w2 = MIN(f->r_w - x1, p->width); x1 = 0; } x2 = p->x + p->lbearing - f->scr_x + f->off_x + x1; y2 = p->y - p->ascent - f->scr_y + f->off_y + y1; if (f->bg_image && f->bg_image->pixmap != None) { XSetTile(f->dpy, f->gc, f->bg_image->pixmap); XSetTSOrigin(f->dpy, f->gc, f->off_x - f->scr_x, f->off_y -f->scr_y); XSetFillStyle(f->dpy, f->gc, FillTiled); XFillRectangle(f->dpy, f->backup, f->gc, x2, y2, w2, h2); XSetFillStyle(f->dpy, f->gc, FillSolid); } else { XSetForeground(f->dpy, f->gc, f->background); XFillRectangle(f->dpy, f->backup, f->gc, x2, y2, w2, h2); } htmlobj_draw(f->dpy, f->backup, f->gc, f->off_x - f->scr_x, f->off_y - f->scr_y , p, x1, y1, w2, h2); frame_expose(f, x2, y2, w2, h2); next: return; } static HTMLHrefInfo * find_url(HTMLObj *o, int x, int y) { HTMLHrefInfo *ret; int x1, y1, x2, y2; if (o->type == HTMLOBJ_BLOCK) { HTMLBlockObj *bo = o->data; HTMLObj *p = bo->obj->next; while (p != bo->obj) { if ((ret = find_url(p, x, y))) return ret; p = p->next; } return NULL; } else { x1 = o->x + o->lbearing; x2 = o->x + o->rbearing; y1 = o->y - o->ascent; y2 = o->y + o->descent; if (x >= x1 && x <= x2 && y >= y1 && y <= y2) return o->link; else return NULL; } } HTMLHrefInfo * frame_get_url(Frame *f, int x, int y) { HTMLHrefInfo *ret; HTMLObj *p = f->disp_start; y -= (-f->scr_y + f->off_y); x -= (-f->scr_x + f->off_x); while (p != f->disp_end) { if ((ret = find_url(p, x, y))) return ret; p = p->next; } return NULL; }