mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 20:16:54 +03:00
[project @ 2004-11-20 00:02:56 by bursa]
Improvements to overflow and scrolling: scrollbars now have most of the usual RISC OS behaviour. Better rendering of dotted and dashed borders. svn path=/import/netsurf/; revision=1363
This commit is contained in:
parent
e87e37ca80
commit
a31f6306f9
@ -242,6 +242,17 @@ SaveText:Webpage
|
||||
SaveObject:Object
|
||||
SaveLink:Link
|
||||
|
||||
ScrollUp:Click the arrow to scroll up
|
||||
ScrollPUp:Click to scroll up one page
|
||||
ScrollV:Drag the bar to scroll vertically
|
||||
ScrollPDown:Click to scroll down one page
|
||||
ScrollDown:Click the arrow to scroll down
|
||||
ScrollLeft:Click the arrow to scroll left
|
||||
ScrollPLeft:Click to scroll left one page
|
||||
ScrollH:Drag the bar to scroll horizontally
|
||||
ScrollPRight:Click to scroll right one page
|
||||
ScrollRight:Click the arrow to scroll right
|
||||
|
||||
# Interactive help
|
||||
HelpToolbar0:Schaltet zurück auf die zuvor dargestellte Seite.|MDer Inhalt wird dabei nicht aktualisiert.
|
||||
HelpToolbar1:Schaltet vorwärts auf die nächste Seite.|MDer Inhalt wird dabei nicht aktualisiert.
|
||||
|
@ -242,6 +242,17 @@ SaveText:Webpage
|
||||
SaveObject:Object
|
||||
SaveLink:Link
|
||||
|
||||
ScrollUp:Click the arrow to scroll up
|
||||
ScrollPUp:Click to scroll up one page
|
||||
ScrollV:Drag the bar to scroll vertically
|
||||
ScrollPDown:Click to scroll down one page
|
||||
ScrollDown:Click the arrow to scroll down
|
||||
ScrollLeft:Click the arrow to scroll left
|
||||
ScrollPLeft:Click to scroll left one page
|
||||
ScrollH:Drag the bar to scroll horizontally
|
||||
ScrollPRight:Click to scroll right one page
|
||||
ScrollRight:Click the arrow to scroll right
|
||||
|
||||
# Interactive help
|
||||
HelpToolbar0:\Tback button.|M\Straverse back one page in the history tree.|MDoes not resubmit form information.
|
||||
HelpToolbar1:\Tforward button.|M\Straverse forward one page in the history tree.|MDoes not resubmit form information.
|
||||
|
@ -242,6 +242,17 @@ SaveText:PageWeb
|
||||
SaveObject:Objet
|
||||
SaveLink:Lien
|
||||
|
||||
ScrollUp:Click the arrow to scroll up
|
||||
ScrollPUp:Click to scroll up one page
|
||||
ScrollV:Drag the bar to scroll vertically
|
||||
ScrollPDown:Click to scroll down one page
|
||||
ScrollDown:Click the arrow to scroll down
|
||||
ScrollLeft:Click the arrow to scroll left
|
||||
ScrollPLeft:Click to scroll left one page
|
||||
ScrollH:Drag the bar to scroll horizontally
|
||||
ScrollPRight:Click to scroll right one page
|
||||
ScrollRight:Click the arrow to scroll right
|
||||
|
||||
# Interactive help
|
||||
HelpToolbar0:\Tle bouton de retour.|M\Srevenir d'une page en arrière dans l'historique.|MNe renvoie pas l'information de formulaire.
|
||||
HelpToolbar1:\Tle bouton d'avance.|M\Savancer d'une page dans l'historique.|MNe renvoie pas l'information de formulaire.
|
||||
|
@ -56,6 +56,9 @@ static void browser_window_mouse_click_html(struct browser_window *bw,
|
||||
browser_mouse_click click, int x, int y);
|
||||
static void browser_window_mouse_drag_html(struct browser_window *bw,
|
||||
int x, int y);
|
||||
static const char *browser_window_scrollbar_click(struct browser_window *bw,
|
||||
browser_mouse_click click, struct box *box,
|
||||
int box_x, int box_y, int x, int y);
|
||||
static void browser_radio_set(struct content *content,
|
||||
struct form_control *radio);
|
||||
static void browser_redraw_box(struct content *c, struct box *box);
|
||||
@ -631,7 +634,9 @@ void browser_window_mouse_click_html(struct browser_window *bw,
|
||||
gui_pointer_shape pointer = GUI_POINTER_DEFAULT;
|
||||
int box_x = 0, box_y = 0;
|
||||
int gadget_box_x = 0, gadget_box_y = 0;
|
||||
int scroll_box_x = 0, scroll_box_y = 0;
|
||||
struct box *gadget_box = 0;
|
||||
struct box *scroll_box = 0;
|
||||
struct content *c = bw->current_content;
|
||||
struct box *box;
|
||||
struct content *content = c;
|
||||
@ -681,24 +686,26 @@ void browser_window_mouse_click_html(struct browser_window *bw,
|
||||
if (box->style && box->style->cursor != CSS_CURSOR_UNKNOWN)
|
||||
pointer = get_pointer_shape(box->style->cursor);
|
||||
|
||||
if ((box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK ||
|
||||
box->type == BOX_FLOAT_LEFT ||
|
||||
box->type == BOX_FLOAT_RIGHT) &&
|
||||
box->style &&
|
||||
box->style->overflow == CSS_OVERFLOW_SCROLL) {
|
||||
if (box_x + box->padding[LEFT] + box->width < x) {
|
||||
/* vertical scrollbar */
|
||||
bw->drag_type = DRAGGING_VSCROLL;
|
||||
bw->scrolling_box = box;
|
||||
bw->scrolling_last_x = x;
|
||||
bw->scrolling_last_y = y;
|
||||
}
|
||||
if (box->style && box->type != BOX_BR &&
|
||||
box->type != BOX_INLINE &&
|
||||
(box->style->overflow == CSS_OVERFLOW_SCROLL ||
|
||||
box->style->overflow == CSS_OVERFLOW_AUTO) &&
|
||||
((box_vscrollbar_present(box) &&
|
||||
box_x + box->scroll_x + box->padding[LEFT] +
|
||||
box->width < x) ||
|
||||
(box_hscrollbar_present(box) &&
|
||||
box_y + box->scroll_y + box->padding[TOP] +
|
||||
box->height < y))) {
|
||||
scroll_box = box;
|
||||
scroll_box_x = box_x + box->scroll_x;
|
||||
scroll_box_y = box_y + box->scroll_y;
|
||||
}
|
||||
}
|
||||
|
||||
if (bw->drag_type == DRAGGING_VSCROLL ||
|
||||
bw->drag_type == DRAGGING_HSCROLL) {
|
||||
status = messages_get("Scrollbar");
|
||||
if (scroll_box) {
|
||||
status = browser_window_scrollbar_click(bw, click, scroll_box,
|
||||
scroll_box_x, scroll_box_y,
|
||||
x - scroll_box_x, y - scroll_box_y);
|
||||
|
||||
} else if (gadget) {
|
||||
switch (gadget->type) {
|
||||
@ -728,7 +735,8 @@ void browser_window_mouse_click_html(struct browser_window *bw,
|
||||
/* drop through */
|
||||
case GADGET_SUBMIT:
|
||||
if (gadget->form) {
|
||||
res = url_join(gadget->form->action, base_url, &url);
|
||||
res = url_join(gadget->form->action, base_url,
|
||||
&url);
|
||||
snprintf(status_buffer, sizeof status_buffer,
|
||||
messages_get("FormSubmit"),
|
||||
(res == URL_FUNC_OK) ? url :
|
||||
@ -830,32 +838,165 @@ void browser_window_mouse_click_html(struct browser_window *bw,
|
||||
void browser_window_mouse_drag_html(struct browser_window *bw,
|
||||
int x, int y)
|
||||
{
|
||||
int scroll_y;
|
||||
int scroll_x, scroll_y;
|
||||
struct box *box;
|
||||
|
||||
if (bw->drag_type == DRAGGING_VSCROLL) {
|
||||
box = bw->scrolling_box;
|
||||
assert(box);
|
||||
if (y == bw->scrolling_last_y)
|
||||
return;
|
||||
|
||||
scroll_y = box->scroll_y + (y - bw->scrolling_last_y);
|
||||
bw->scrolling_last_y = y;
|
||||
|
||||
scroll_y = bw->scrolling_start_scroll_y +
|
||||
(float) (y - bw->scrolling_start_y) /
|
||||
(float) bw->scrolling_well_height *
|
||||
(float) (box->descendant_y1 -
|
||||
box->descendant_y0);
|
||||
if (scroll_y < box->descendant_y0)
|
||||
scroll_y = box->descendant_y0;
|
||||
else if (box->descendant_y1 - box->height < scroll_y)
|
||||
scroll_y = box->descendant_y1 - box->height;
|
||||
|
||||
if (scroll_y == box->scroll_y)
|
||||
return;
|
||||
box->scroll_y = scroll_y;
|
||||
browser_redraw_box(bw->current_content, bw->scrolling_box);
|
||||
|
||||
} else if (bw->drag_type == DRAGGING_HSCROLL) {
|
||||
box = bw->scrolling_box;
|
||||
assert(box);
|
||||
scroll_x = bw->scrolling_start_scroll_x +
|
||||
(float) (x - bw->scrolling_start_x) /
|
||||
(float) bw->scrolling_well_width *
|
||||
(float) (box->descendant_x1 -
|
||||
box->descendant_x0);
|
||||
if (scroll_x < box->descendant_x0)
|
||||
scroll_x = box->descendant_x0;
|
||||
else if (box->descendant_x1 - box->width < scroll_x)
|
||||
scroll_x = box->descendant_x1 - box->width;
|
||||
if (scroll_x == box->scroll_x)
|
||||
return;
|
||||
box->scroll_x = scroll_x;
|
||||
browser_redraw_box(bw->current_content, bw->scrolling_box);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle mouse clicks in a box scrollbar.
|
||||
*
|
||||
* \param bw browser window
|
||||
* \param click type of mouse click
|
||||
* \param box scrolling box
|
||||
* \param box_x position of box in global document coordinates
|
||||
* \param box_y position of box in global document coordinates
|
||||
* \param x coordinate of click relative to box position
|
||||
* \param y coordinate of click relative to box position
|
||||
* \return status bar message
|
||||
*/
|
||||
|
||||
const char *browser_window_scrollbar_click(struct browser_window *bw,
|
||||
browser_mouse_click click, struct box *box,
|
||||
int box_x, int box_y, int x, int y)
|
||||
{
|
||||
const int w = SCROLLBAR_WIDTH;
|
||||
bool vscroll, hscroll;
|
||||
int well_height, bar_top, bar_height;
|
||||
int well_width, bar_left, bar_width;
|
||||
const char *status = 0;
|
||||
bool vert;
|
||||
int z, scroll, bar_start, bar_size, well_size, page;
|
||||
|
||||
box_scrollbar_dimensions(box,
|
||||
box->padding[LEFT] + box->width + box->padding[RIGHT],
|
||||
box->padding[TOP] + box->height + box->padding[BOTTOM],
|
||||
w,
|
||||
&vscroll, &hscroll,
|
||||
&well_height, &bar_top, &bar_height,
|
||||
&well_width, &bar_left, &bar_width);
|
||||
|
||||
/* store some data for scroll drags */
|
||||
bw->scrolling_box = box;
|
||||
bw->scrolling_start_x = box_x + x;
|
||||
bw->scrolling_start_y = box_y + y;
|
||||
bw->scrolling_start_scroll_x = box->scroll_x;
|
||||
bw->scrolling_start_scroll_y = box->scroll_y;
|
||||
bw->scrolling_well_width = well_width;
|
||||
bw->scrolling_well_height = well_height;
|
||||
|
||||
/* determine which scrollbar was clicked */
|
||||
if (box_vscrollbar_present(box) &&
|
||||
box->padding[LEFT] + box->width < x) {
|
||||
vert = true;
|
||||
z = y;
|
||||
scroll = box->scroll_y;
|
||||
well_size = well_height;
|
||||
bar_start = bar_top;
|
||||
bar_size = bar_height;
|
||||
page = box->height;
|
||||
} else {
|
||||
vert = false;
|
||||
z = x;
|
||||
scroll = box->scroll_x;
|
||||
well_size = well_width;
|
||||
bar_start = bar_left;
|
||||
bar_size = bar_width;
|
||||
page = box->width;
|
||||
}
|
||||
|
||||
/* find icon in scrollbar and calculate scroll */
|
||||
if (z < w) {
|
||||
status = messages_get(vert ? "ScrollUp" : "ScrollLeft");
|
||||
if (click == BROWSER_MOUSE_CLICK_1)
|
||||
scroll -= 16;
|
||||
else if (click == BROWSER_MOUSE_CLICK_2)
|
||||
scroll += 16;
|
||||
} else if (z < w + bar_start + w / 4) {
|
||||
status = messages_get(vert ? "ScrollPUp" : "ScrollPLeft");
|
||||
if (click == BROWSER_MOUSE_CLICK_1)
|
||||
scroll -= page;
|
||||
else if (click == BROWSER_MOUSE_CLICK_2)
|
||||
scroll += page;
|
||||
} else if (z < w + bar_start + bar_size - w / 4) {
|
||||
status = messages_get(vert ? "ScrollV" : "ScrollH");
|
||||
if (click == BROWSER_MOUSE_CLICK_1)
|
||||
bw->drag_type = vert ? DRAGGING_VSCROLL :
|
||||
DRAGGING_HSCROLL;
|
||||
} else if (z < w + well_size) {
|
||||
status = messages_get(vert ? "ScrollPDown" : "ScrollPRight");
|
||||
if (click == BROWSER_MOUSE_CLICK_1)
|
||||
scroll += page;
|
||||
else if (click == BROWSER_MOUSE_CLICK_2)
|
||||
scroll -= page;
|
||||
} else {
|
||||
status = messages_get(vert ? "ScrollDown" : "ScrollRight");
|
||||
if (click == BROWSER_MOUSE_CLICK_1)
|
||||
scroll += 16;
|
||||
else if (click == BROWSER_MOUSE_CLICK_2)
|
||||
scroll -= 16;
|
||||
}
|
||||
|
||||
/* update box and redraw */
|
||||
if (vert) {
|
||||
if (scroll < box->descendant_y0)
|
||||
scroll = box->descendant_y0;
|
||||
else if (box->descendant_y1 - box->height < scroll)
|
||||
scroll = box->descendant_y1 - box->height;
|
||||
if (scroll != box->scroll_y) {
|
||||
box->scroll_y = scroll;
|
||||
browser_redraw_box(bw->current_content, box);
|
||||
}
|
||||
} else {
|
||||
if (scroll < box->descendant_x0)
|
||||
scroll = box->descendant_x0;
|
||||
else if (box->descendant_x1 - box->width < scroll)
|
||||
scroll = box->descendant_x1 - box->width;
|
||||
if (scroll != box->scroll_x) {
|
||||
box->scroll_x = scroll;
|
||||
browser_redraw_box(bw->current_content, box);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a radio form control and clear the others in the group.
|
||||
*
|
||||
@ -868,8 +1009,9 @@ void browser_radio_set(struct content *content,
|
||||
{
|
||||
struct form_control *control;
|
||||
|
||||
/* some sanity checking */
|
||||
if (content == NULL || radio == NULL || radio->form == NULL)
|
||||
assert(content);
|
||||
assert(radio);
|
||||
if (!radio->form)
|
||||
return;
|
||||
|
||||
if (radio->selected)
|
||||
|
@ -58,9 +58,15 @@ struct browser_window {
|
||||
|
||||
/** Box currently being scrolled, or 0. */
|
||||
struct box *scrolling_box;
|
||||
/** Mouse position last scroll movement. */
|
||||
int scrolling_last_x;
|
||||
int scrolling_last_y;
|
||||
/** Mouse position at start of current scroll drag. */
|
||||
int scrolling_start_x;
|
||||
int scrolling_start_y;
|
||||
/** Scroll offsets at start of current scroll draw. */
|
||||
int scrolling_start_scroll_x;
|
||||
int scrolling_start_scroll_y;
|
||||
/** Well dimensions for current scroll drag. */
|
||||
int scrolling_well_width;
|
||||
int scrolling_well_height;
|
||||
|
||||
/** Referer for current fetch, or 0. */
|
||||
char *referer;
|
||||
|
@ -24,7 +24,7 @@ struct font_data;
|
||||
struct plotter_table {
|
||||
bool (*clg)(colour c);
|
||||
bool (*rectangle)(int x0, int y0, int width, int height,
|
||||
colour c, bool dotted);
|
||||
int line_width, colour c, bool dotted, bool dashed);
|
||||
bool (*line)(int x0, int y0, int x1, int y1, int width,
|
||||
colour c, bool dotted, bool dashed);
|
||||
bool (*polygon)(int *p, unsigned int n, colour fill);
|
||||
|
@ -3064,8 +3064,7 @@ siblings:
|
||||
|
||||
bool box_contains_point(struct box *box, int x, int y)
|
||||
{
|
||||
if (box->style && (box->style->overflow == CSS_OVERFLOW_HIDDEN ||
|
||||
box->style->overflow == CSS_OVERFLOW_SCROLL)) {
|
||||
if (box->style && box->style->overflow != CSS_OVERFLOW_VISIBLE) {
|
||||
if (box->x <= x &&
|
||||
x < box->x + box->padding[LEFT] + box->width +
|
||||
box->padding[RIGHT] &&
|
||||
|
10
render/box.h
10
render/box.h
@ -249,4 +249,14 @@ struct box *box_at_point(struct box *box, int x, int y,
|
||||
struct box *box_object_at_point(struct content *c, int x, int y);
|
||||
struct box *box_find_by_id(struct box *box, const char *id);
|
||||
|
||||
bool box_vscrollbar_present(const struct box *box);
|
||||
bool box_hscrollbar_present(const struct box *box);
|
||||
void box_scrollbar_dimensions(const struct box *box,
|
||||
int padding_width, int padding_height, int w,
|
||||
bool *vscroll, bool *hscroll,
|
||||
int *well_height,
|
||||
int *bar_top, int *bar_height,
|
||||
int *well_width,
|
||||
int *bar_left, int *bar_width);
|
||||
|
||||
#endif
|
||||
|
@ -43,7 +43,8 @@ static bool html_redraw_file(int x, int y, int width, int height,
|
||||
static bool html_redraw_background(int x, int y,
|
||||
struct box *box, float scale, colour background_colour);
|
||||
static bool html_redraw_scrollbars(struct box *box, float scale,
|
||||
int x, int y, int padding_width, int padding_height);
|
||||
int x, int y, int padding_width, int padding_height,
|
||||
colour background_colour);
|
||||
|
||||
bool html_redraw_debug = false;
|
||||
|
||||
@ -161,10 +162,10 @@ bool html_redraw_box(struct box *box,
|
||||
/* dotted debug outlines */
|
||||
if (html_redraw_debug) {
|
||||
if (!plot.rectangle(x, y, padding_width, padding_height,
|
||||
0x0000ff, true))
|
||||
1, 0x0000ff, true, false))
|
||||
return false;
|
||||
if (!plot.rectangle(x + padding_left, y + padding_top,
|
||||
width, height, 0xff0000, true))
|
||||
width, height, 1, 0xff0000, true, false))
|
||||
return false;
|
||||
if (!plot.rectangle(x - (box->border[LEFT] +
|
||||
box->margin[LEFT]) * scale,
|
||||
@ -176,7 +177,7 @@ bool html_redraw_box(struct box *box,
|
||||
padding_height + (box->border[TOP] +
|
||||
box->margin[TOP] + box->border[BOTTOM] +
|
||||
box->margin[BOTTOM]) * scale,
|
||||
0x00ffff, true))
|
||||
1, 0x00ffff, true, false))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -259,14 +260,6 @@ bool html_redraw_box(struct box *box,
|
||||
if (!plot.clip(x0, y0, x1, y1))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* scrollbars */
|
||||
if (box->style->overflow == CSS_OVERFLOW_SCROLL) {
|
||||
if (!html_redraw_scrollbars(box, scale, x, y,
|
||||
padding_width, padding_height))
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (box->object) {
|
||||
@ -350,6 +343,15 @@ bool html_redraw_box(struct box *box,
|
||||
return false;
|
||||
}
|
||||
|
||||
/* scrollbars */
|
||||
if (box->style && box->type != BOX_BR && box->type != BOX_INLINE &&
|
||||
(box->style->overflow == CSS_OVERFLOW_SCROLL ||
|
||||
box->style->overflow == CSS_OVERFLOW_AUTO))
|
||||
if (!html_redraw_scrollbars(box, scale, x, y,
|
||||
padding_width, padding_height,
|
||||
current_background_color))
|
||||
return false;
|
||||
|
||||
if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK ||
|
||||
box->type == BOX_TABLE_CELL || box->object)
|
||||
if (!plot.clip(clip_x0, clip_y0, clip_x1, clip_y1))
|
||||
@ -750,27 +752,186 @@ bool html_redraw_background(int x, int y,
|
||||
*/
|
||||
|
||||
bool html_redraw_scrollbars(struct box *box, float scale,
|
||||
int x, int y, int padding_width, int padding_height)
|
||||
int x, int y, int padding_width, int padding_height,
|
||||
colour background_colour)
|
||||
{
|
||||
int w = SCROLLBAR_WIDTH * scale;
|
||||
const int w = SCROLLBAR_WIDTH * scale;
|
||||
bool vscroll, hscroll;
|
||||
int well_height, bar_top, bar_height;
|
||||
int well_width, bar_left, bar_width;
|
||||
const colour vcolour = box->style->border[RIGHT].color;
|
||||
const colour hcolour = box->style->border[BOTTOM].color;
|
||||
|
||||
/* vertical scrollbar */
|
||||
if (box->descendant_y0 < box->descendant_y1) {
|
||||
int bar_top = (float) padding_height * (float) box->scroll_y /
|
||||
(float) (box->descendant_y1 -
|
||||
box->descendant_y0);
|
||||
int bar_height = (float) padding_height * (float) box->height /
|
||||
(float) (box->descendant_y1 -
|
||||
box->descendant_y0);
|
||||
box_scrollbar_dimensions(box, padding_width, padding_height, w,
|
||||
&vscroll, &hscroll,
|
||||
&well_height, &bar_top, &bar_height,
|
||||
&well_width, &bar_left, &bar_width);
|
||||
|
||||
#define TRIANGLE(x0, y0, x1, y1, x2, y2, c) \
|
||||
if (!plot.line(x0, y0, x1, y1, scale, c, false, false)) \
|
||||
return false; \
|
||||
if (!plot.line(x0, y0, x2, y2, scale, c, false, false)) \
|
||||
return false; \
|
||||
if (!plot.line(x1, y1, x2, y2, scale, c, false, false)) \
|
||||
return false;
|
||||
|
||||
/* fill scrollbar well(s) with background colour */
|
||||
if (vscroll)
|
||||
if (!plot.fill(x + padding_width - w, y,
|
||||
x + padding_width, y + padding_height,
|
||||
0x777777))
|
||||
background_colour))
|
||||
return false;
|
||||
if (!plot.fill(x + padding_width - w + 4, y + bar_top,
|
||||
x + padding_width - 4, y + bar_top + bar_height,
|
||||
0xbbbbbb))
|
||||
if (hscroll)
|
||||
if (!plot.fill(x, y + padding_height - w,
|
||||
x + padding_width, y + padding_height,
|
||||
background_colour))
|
||||
return false;
|
||||
|
||||
/* vertical scrollbar */
|
||||
if (vscroll) {
|
||||
/* left line */
|
||||
if (!plot.line(x + padding_width - w, y,
|
||||
x + padding_width - w, y + padding_height,
|
||||
scale, vcolour, false, false))
|
||||
return false;
|
||||
/* up arrow */
|
||||
TRIANGLE(x + padding_width - w / 2, y + w / 4,
|
||||
x + padding_width - w * 3 / 4, y + w * 3 / 4,
|
||||
x + padding_width - w / 4, y + w * 3 / 4,
|
||||
vcolour);
|
||||
/* separator */
|
||||
if (!plot.line(x + padding_width - w, y + w,
|
||||
x + padding_width, y + w,
|
||||
scale, vcolour, false, false))
|
||||
return false;
|
||||
/* bar */
|
||||
if (!plot.rectangle(x + padding_width - w * 3 / 4,
|
||||
y + w + bar_top + w / 4,
|
||||
w / 2, bar_height - w / 2,
|
||||
scale, vcolour, false, false))
|
||||
return false;
|
||||
/* separator */
|
||||
if (!plot.line(x + padding_width - w, y + w + well_height,
|
||||
x + padding_width, y + w + well_height,
|
||||
scale, vcolour, false, false))
|
||||
return false;
|
||||
/* down arrow */
|
||||
TRIANGLE(x + padding_width - w / 2,
|
||||
y + w + well_height + w * 3 / 4,
|
||||
x + padding_width - w * 3 / 4,
|
||||
y + w + well_height + w / 4,
|
||||
x + padding_width - w / 4,
|
||||
y + w + well_height + w / 4,
|
||||
vcolour);
|
||||
}
|
||||
|
||||
/* horizontal scrollbar */
|
||||
if (hscroll) {
|
||||
/* top line */
|
||||
if (!plot.line(x, y + padding_height - w,
|
||||
x + well_width + w + w, y + padding_height - w,
|
||||
scale, hcolour, false, false))
|
||||
return false;
|
||||
/* left arrow */
|
||||
TRIANGLE(x + w / 4, y + padding_height - w / 2,
|
||||
x + w * 3 / 4, y + padding_height - w * 3 / 4,
|
||||
x + w * 3 / 4, y + padding_height - w / 4,
|
||||
hcolour);
|
||||
/* separator */
|
||||
if (!plot.line(x + w, y + padding_height - w,
|
||||
x + w, y + padding_height,
|
||||
scale, hcolour, false, false))
|
||||
return false;
|
||||
/* bar */
|
||||
if (!plot.rectangle(x + w + bar_left + w / 4,
|
||||
y + padding_height - w * 3 / 4,
|
||||
bar_width - w / 2, w / 2,
|
||||
scale, hcolour, false, false))
|
||||
return false;
|
||||
/* separator */
|
||||
if (!plot.line(x + w + well_width, y + padding_height - w,
|
||||
x + w + well_width, y + padding_height,
|
||||
scale, hcolour, false, false))
|
||||
return false;
|
||||
/* right arrow */
|
||||
TRIANGLE(x + w + well_width + w * 3 / 4,
|
||||
y + padding_height - w / 2,
|
||||
x + w + well_width + w / 4,
|
||||
y + padding_height - w * 3 / 4,
|
||||
x + w + well_width + w / 4,
|
||||
y + padding_height - w / 4,
|
||||
hcolour);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if a box has a vertical scrollbar.
|
||||
*
|
||||
* \param box scrolling box
|
||||
* \return the box has a vertical scrollbar
|
||||
*/
|
||||
|
||||
bool box_vscrollbar_present(const struct box * const box)
|
||||
{
|
||||
return box->descendant_y0 < -box->border[TOP] ||
|
||||
box->padding[TOP] + box->height + box->padding[BOTTOM] +
|
||||
box->border[BOTTOM] < box->descendant_y1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if a box has a horizontal scrollbar.
|
||||
*
|
||||
* \param box scrolling box
|
||||
* \return the box has a horizontal scrollbar
|
||||
*/
|
||||
|
||||
bool box_hscrollbar_present(const struct box * const box)
|
||||
{
|
||||
return box->descendant_x0 < -box->border[LEFT] ||
|
||||
box->padding[LEFT] + box->width + box->padding[RIGHT] +
|
||||
box->border[RIGHT] < box->descendant_x1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate scrollbar dimensions and positions for a box.
|
||||
*
|
||||
* \param box scrolling box
|
||||
* \param padding_width scaled width of padding box
|
||||
* \param padding_height scaled height of padding box
|
||||
* \param w scaled scrollbar width
|
||||
* \param vscroll updated to vertical scrollbar present
|
||||
* \param hscroll updated to horizontal scrollbar present
|
||||
* \param well_height updated to vertical well height
|
||||
* \param bar_top updated to top position of vertical scrollbar
|
||||
* \param bar_height updated to height of vertical scrollbar
|
||||
* \param well_width updated to horizontal well width
|
||||
* \param bar_left updated to left position of horizontal scrollbar
|
||||
* \param bar_width updated to width of horizontal scrollbar
|
||||
*/
|
||||
|
||||
void box_scrollbar_dimensions(const struct box * const box,
|
||||
const int padding_width, const int padding_height, const int w,
|
||||
bool * const vscroll, bool * const hscroll,
|
||||
int * const well_height,
|
||||
int * const bar_top, int * const bar_height,
|
||||
int * const well_width,
|
||||
int * const bar_left, int * const bar_width)
|
||||
{
|
||||
*vscroll = box_vscrollbar_present(box);
|
||||
*hscroll = box_hscrollbar_present(box);
|
||||
*well_height = padding_height - w - w;
|
||||
*bar_top = (float) *well_height * (float) box->scroll_y /
|
||||
(float) (box->descendant_y1 - box->descendant_y0);
|
||||
*bar_height = (float) *well_height * (float) box->height /
|
||||
(float) (box->descendant_y1 - box->descendant_y0);
|
||||
*well_width = padding_width - w - w - (*vscroll ? w : 0);
|
||||
*bar_left = (float) *well_width * (float) box->scroll_x /
|
||||
(float) (box->descendant_x1 - box->descendant_x0);
|
||||
*bar_width = (float) *well_width * (float) box->width /
|
||||
(float) (box->descendant_x1 - box->descendant_x0);
|
||||
}
|
||||
|
@ -355,10 +355,12 @@ void layout_block_find_dimensions(int available_width, struct box *box)
|
||||
box->width = layout_solve_width(available_width, width, margin,
|
||||
padding, border);
|
||||
|
||||
if (style->overflow == CSS_OVERFLOW_SCROLL) {
|
||||
/* make space for vertical scrollbar */
|
||||
if (style->overflow == CSS_OVERFLOW_SCROLL ||
|
||||
style->overflow == CSS_OVERFLOW_AUTO) {
|
||||
/* make space for scrollbars */
|
||||
box->width -= SCROLLBAR_WIDTH;
|
||||
box->padding[RIGHT] += SCROLLBAR_WIDTH;
|
||||
box->padding[BOTTOM] += SCROLLBAR_WIDTH;
|
||||
}
|
||||
|
||||
if (box->object && box->object->type == CONTENT_HTML &&
|
||||
@ -423,7 +425,8 @@ int layout_solve_width(int available_width, int width,
|
||||
void layout_float_find_dimensions(int available_width,
|
||||
struct css_style *style, struct box *box)
|
||||
{
|
||||
int scrollbar_width = style->overflow == CSS_OVERFLOW_SCROLL ?
|
||||
int scrollbar_width = (style->overflow == CSS_OVERFLOW_SCROLL ||
|
||||
style->overflow == CSS_OVERFLOW_AUTO) ?
|
||||
SCROLLBAR_WIDTH : 0;
|
||||
|
||||
layout_find_dimensions(available_width, style,
|
||||
@ -461,6 +464,7 @@ void layout_float_find_dimensions(int available_width,
|
||||
}
|
||||
|
||||
box->padding[RIGHT] += scrollbar_width;
|
||||
box->padding[BOTTOM] += scrollbar_width;
|
||||
|
||||
if (box->object) {
|
||||
/* floating replaced element, see 10.3.6 and 10.6.2 */
|
||||
|
@ -22,9 +22,11 @@
|
||||
|
||||
static bool ro_plot_clg(colour c);
|
||||
static bool ro_plot_rectangle(int x0, int y0, int width, int height,
|
||||
colour c, bool dotted);
|
||||
int line_width, colour c, bool dotted, bool dashed);
|
||||
static bool ro_plot_line(int x0, int y0, int x1, int y1, int width,
|
||||
colour c, bool dotted, bool dashed);
|
||||
static bool ro_plot_path(const draw_path * const path, int width,
|
||||
colour c, bool dotted, bool dashed);
|
||||
static bool ro_plot_polygon(int *p, unsigned int n, colour fill);
|
||||
static bool ro_plot_fill(int x0, int y0, int x1, int y1, colour c);
|
||||
static bool ro_plot_clip(int clip_x0, int clip_y0,
|
||||
@ -88,82 +90,74 @@ bool ro_plot_clg(colour c)
|
||||
|
||||
|
||||
bool ro_plot_rectangle(int x0, int y0, int width, int height,
|
||||
colour c, bool dotted)
|
||||
int line_width, colour c, bool dotted, bool dashed)
|
||||
{
|
||||
os_plot_code plot_code = (dotted ? os_PLOT_DOTTED : os_PLOT_SOLID) |
|
||||
os_PLOT_BY;
|
||||
os_error *error;
|
||||
const int path[] = { draw_MOVE_TO,
|
||||
(ro_plot_origin_x + x0 * 2) * 256,
|
||||
(ro_plot_origin_y - y0 * 2 - 1) * 256,
|
||||
draw_LINE_TO,
|
||||
(ro_plot_origin_x + (x0 + width) * 2) * 256,
|
||||
(ro_plot_origin_y - y0 * 2 - 1) * 256,
|
||||
draw_LINE_TO,
|
||||
(ro_plot_origin_x + (x0 + width) * 2) * 256,
|
||||
(ro_plot_origin_y - (y0 + height) * 2 - 1) * 256,
|
||||
draw_LINE_TO,
|
||||
(ro_plot_origin_x + x0 * 2) * 256,
|
||||
(ro_plot_origin_y - (y0 + height) * 2 - 1) * 256,
|
||||
draw_CLOSE_LINE,
|
||||
(ro_plot_origin_x + x0 * 2) * 256,
|
||||
(ro_plot_origin_y - y0 * 2 - 1) * 256,
|
||||
draw_END_PATH };
|
||||
|
||||
error = xcolourtrans_set_gcol(c << 8, 0, os_ACTION_OVERWRITE, 0, 0);
|
||||
if (error) {
|
||||
LOG(("xcolourtrans_set_gcol: 0x%x: %s",
|
||||
error->errnum, error->errmess));
|
||||
return false;
|
||||
}
|
||||
error = xos_plot(os_MOVE_TO,
|
||||
ro_plot_origin_x + x0 * 2,
|
||||
ro_plot_origin_y - y0 * 2);
|
||||
if (error) {
|
||||
LOG(("xos_plot: 0x%x: %s", error->errnum, error->errmess));
|
||||
return false;
|
||||
}
|
||||
error = xos_plot(plot_code, width * 2, 0);
|
||||
if (error) {
|
||||
LOG(("xos_plot: 0x%x: %s", error->errnum, error->errmess));
|
||||
return false;
|
||||
}
|
||||
error = xos_plot(plot_code, 0, -height * 2);
|
||||
if (error) {
|
||||
LOG(("xos_plot: 0x%x: %s", error->errnum, error->errmess));
|
||||
return false;
|
||||
}
|
||||
error = xos_plot(plot_code, -width * 2, 0);
|
||||
if (error) {
|
||||
LOG(("xos_plot: 0x%x: %s", error->errnum, error->errmess));
|
||||
return false;
|
||||
}
|
||||
error = xos_plot(plot_code, 0, height * 2);
|
||||
if (error) {
|
||||
LOG(("xos_plot: 0x%x: %s", error->errnum, error->errmess));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ro_plot_path((const draw_path *) path, line_width, c,
|
||||
dotted, dashed);
|
||||
}
|
||||
|
||||
|
||||
static int path[] = { draw_MOVE_TO, 0, 0, draw_LINE_TO, 0, 0,
|
||||
draw_END_PATH, 0 };
|
||||
static const draw_line_style line_style = { draw_JOIN_MITRED,
|
||||
draw_CAP_BUTT, draw_CAP_BUTT, 0, 0x7fffffff,
|
||||
0, 0, 0, 0 };
|
||||
static const int dash_pattern_dotted[] = { 0, 1, 512 };
|
||||
static const int dash_pattern_dashed[] = { 0, 1, 2048 };
|
||||
|
||||
bool ro_plot_line(int x0, int y0, int x1, int y1, int width,
|
||||
colour c, bool dotted, bool dashed)
|
||||
{
|
||||
const draw_dash_pattern *dash_pattern;
|
||||
const int path[] = { draw_MOVE_TO,
|
||||
(ro_plot_origin_x + x0 * 2) * 256,
|
||||
(ro_plot_origin_y - y0 * 2 - 1) * 256,
|
||||
draw_LINE_TO,
|
||||
(ro_plot_origin_x + x1 * 2) * 256,
|
||||
(ro_plot_origin_y - y1 * 2 - 1) * 256,
|
||||
draw_END_PATH };
|
||||
|
||||
return ro_plot_path((const draw_path *) path, width, c, dotted, dashed);
|
||||
}
|
||||
|
||||
|
||||
bool ro_plot_path(const draw_path * const path, int width,
|
||||
colour c, bool dotted, bool dashed)
|
||||
{
|
||||
static const draw_line_style line_style = { draw_JOIN_MITRED,
|
||||
draw_CAP_BUTT, draw_CAP_BUTT, 0, 0x7fffffff,
|
||||
0, 0, 0, 0 };
|
||||
draw_dash_pattern dash = { 0, 1, { 512 } };
|
||||
const draw_dash_pattern *dash_pattern = 0;
|
||||
os_error *error;
|
||||
|
||||
if (dotted)
|
||||
dash_pattern = (const draw_dash_pattern *) &dash_pattern_dotted;
|
||||
else if (dashed)
|
||||
dash_pattern = (const draw_dash_pattern *) &dash_pattern_dashed;
|
||||
else
|
||||
dash_pattern = NULL;
|
||||
if (width < 1)
|
||||
width = 1;
|
||||
|
||||
if (dotted) {
|
||||
dash.elements[0] = 512 * width;
|
||||
dash_pattern = ‐
|
||||
} else if (dashed) {
|
||||
dash.elements[0] = 1536 * width;
|
||||
dash_pattern = ‐
|
||||
}
|
||||
|
||||
path[1] = (ro_plot_origin_x + x0 * 2) * 256;
|
||||
path[2] = (ro_plot_origin_y - y0 * 2 - 1) * 256;
|
||||
path[4] = (ro_plot_origin_x + x1 * 2) * 256;
|
||||
path[5] = (ro_plot_origin_y - y1 * 2 - 1) * 256;
|
||||
error = xcolourtrans_set_gcol(c << 8, 0, os_ACTION_OVERWRITE, 0, 0);
|
||||
if (error) {
|
||||
LOG(("xcolourtrans_set_gcol: 0x%x: %s",
|
||||
error->errnum, error->errmess));
|
||||
return false;
|
||||
}
|
||||
error = xdraw_stroke((draw_path *) path, 0, 0, 0, width * 2 * 256,
|
||||
|
||||
error = xdraw_stroke(path, 0, 0, 0, width * 2 * 256,
|
||||
&line_style, dash_pattern);
|
||||
if (error) {
|
||||
LOG(("xdraw_stroke: 0x%x: %s",
|
||||
|
Loading…
Reference in New Issue
Block a user