Пример #1
0
void gui_window_update_extent(struct gui_window *g)
{
	if (!g->bw->current_content)
		return;

	gtk_layout_set_size(g->layout,
		content_get_width(g->bw->current_content) * g->bw->scale,
		content_get_height(g->bw->current_content) * g->bw->scale);
}
Пример #2
0
bool save_as_draw(hlcache_handle *h, const char *path)
{
	pencil_code code;
	char *drawfile_buffer;
	size_t drawfile_size;
	os_error *error;

	ro_save_draw_diagram = pencil_create();
	if (!ro_save_draw_diagram) {
		warn_user("NoMemory", 0);
		return false;
	}

	ro_save_draw_width = content_get_width(h);
	ro_save_draw_height = content_get_height(h);

	plot = ro_save_draw_plotters;
	if (!content_redraw(h, 0, -ro_save_draw_height,
			ro_save_draw_width, ro_save_draw_height,
			INT_MIN, INT_MIN, INT_MAX, INT_MAX,
			1,
			0xFFFFFF))
	{
		pencil_free(ro_save_draw_diagram);
		return false;
	}

	/*pencil_dump(ro_save_draw_diagram);*/

	code = pencil_save_drawfile(ro_save_draw_diagram, "NetSurf",
			&drawfile_buffer, &drawfile_size);
	if (code != pencil_OK) {
		warn_user("SaveError", 0);
		pencil_free(ro_save_draw_diagram);
		return false;
	}
	assert(drawfile_buffer);

	error = xosfile_save_stamped(path, osfile_TYPE_DRAW,
			(byte *) drawfile_buffer, 
			(byte *) drawfile_buffer + drawfile_size);
	if (error) {
		LOG(("xosfile_save_stamped failed: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("SaveError", error->errmess);
		pencil_free(ro_save_draw_diagram);
		return false;
	}

	pencil_free(ro_save_draw_diagram);

	return true;
}
Пример #3
0
bool ro_gui_url_bar_set_site_favicon(struct url_bar *url_bar,
		struct hlcache_handle *h)
{
	content_type		type = CONTENT_NONE;

	if (url_bar == NULL)
		return false;

	if (h != NULL)
		type = content_get_type(h);

	// \TODO -- Maybe test for CONTENT_ICO ???

	if (type == CONTENT_IMAGE) {
		url_bar->favicon_content = h;
		url_bar->favicon_width = content_get_width(h);
		url_bar->favicon_height = content_get_height(h);

		if (url_bar->favicon_width > URLBAR_FAVICON_SIZE)
			url_bar->favicon_width = URLBAR_FAVICON_SIZE;

		if (url_bar->favicon_height > URLBAR_FAVICON_SIZE)
			url_bar->favicon_height = URLBAR_FAVICON_SIZE;

		url_bar->favicon_offset.x = ((url_bar->favicon_extent.x1 -
				url_bar->favicon_extent.x0) -
				(url_bar->favicon_width * 2)) / 2;
		url_bar->favicon_offset.y = ((url_bar->favicon_extent.y1 -
				url_bar->favicon_extent.y0) -
				(url_bar->favicon_height * 2)) / 2;
	} else {
		url_bar->favicon_content = NULL;

		if (url_bar->favicon_type != 0)
			snprintf(url_bar->favicon_sprite,
					URLBAR_FAVICON_NAME_LENGTH,
					"Ssmall_%.3x", url_bar->favicon_type);
		else
			snprintf(url_bar->favicon_sprite,
					URLBAR_FAVICON_NAME_LENGTH,
					"Ssmall_xxx");
	}

		if (!url_bar->hidden)
			xwimp_force_redraw(url_bar->window,
				url_bar->favicon_extent.x0,
				url_bar->favicon_extent.y0,
				url_bar->favicon_extent.x1,
				url_bar->favicon_extent.y1);

	return true;
}
Пример #4
0
void
gui_window_update_extent(struct gui_window *gw)
{
	float scale = gw->bw->scale;

	fbtk_set_scroll_parameters(gw->hscroll, 0,
			content_get_width(gw->bw->current_content) * scale,
			fbtk_get_width(gw->browser), 100);

	fbtk_set_scroll_parameters(gw->vscroll, 0,
			content_get_height(gw->bw->current_content) * scale,
			fbtk_get_height(gw->browser), 100);
}
Пример #5
0
void gui_window_update_extent(struct gui_window *g)
{
	CALLED();
	if (!g->bw->current_content)
		return;

	if (g->view == NULL)
		return;
	if (!g->view->LockLooper())
		return;

	float x_max = content_get_width(g->bw->current_content) * g->bw->scale /* - 1*/;
	float y_max = content_get_height(g->bw->current_content) * g->bw->scale /* - 1*/;
	float x_prop = g->view->Bounds().Width() / x_max;
	float y_prop = g->view->Bounds().Height() / y_max;
	x_max -= g->view->Bounds().Width() + 1;
	y_max -= g->view->Bounds().Height() + 1;
printf("x_max = %f y_max = %f x_prop = %f y_prop = %f\n", x_max, y_max, x_prop, y_prop);
	if (g->view->ScrollBar(B_HORIZONTAL)) {
		g->view->ScrollBar(B_HORIZONTAL)->SetRange(0, x_max);
		g->view->ScrollBar(B_HORIZONTAL)->SetProportion(x_prop);
		g->view->ScrollBar(B_HORIZONTAL)->SetSteps(10, 50);
	}
	if (g->view->ScrollBar(B_VERTICAL)) {
		g->view->ScrollBar(B_VERTICAL)->SetRange(0, y_max);
		g->view->ScrollBar(B_VERTICAL)->SetProportion(y_prop);
		g->view->ScrollBar(B_VERTICAL)->SetSteps(10, 50);
	}

#if 0
	g->view->ResizeTo(
		g->bw->current_content->width * g->bw->scale /* - 1*/,
		g->bw->current_content->height * g->bw->scale /* - 1*/);
#endif

	g->view->UnlockLooper();

#warning WRITEME
#if 0 /* GTK */
	gtk_widget_set_size_request(GTK_WIDGET(g->drawing_area),
			g->bw->current_content->width * g->bw->scale,
			g->bw->current_content->height * g->bw->scale);

	gtk_widget_set_size_request(GTK_WIDGET(g->viewport), 0, 0);
#endif
}
Пример #6
0
/* It seems this method is called when content size got adjusted,
	so that we can adjust scroll info. We also have to call it when tab
	change occurs.
*/
void gui_window_update_extent(struct gui_window *gw)
{

    if( gw->browser->bw->current_content != NULL ) {
        // TODO: store content size!
        if(window_get_active_gui_window(gw->root) == gw) {
            window_set_content_size( gw->root,
                                     content_get_width(gw->browser->bw->current_content),
                                     content_get_height(gw->browser->bw->current_content)
                                   );
            window_update_back_forward(gw->root);
            GRECT area;
            window_get_grect(gw->root, BROWSER_AREA_CONTENT, &area);
            window_schedule_redraw_grect(gw->root, &area);
        }
    }
}
Пример #7
0
/**
 * This function calls print setup, prints page after page until the whole
 * content is printed calls cleaning up afterwise.
 *
 * \param content The content to be printed
 * \param printer The printer interface for the printer to be used
 * \param settings The settings for printing to use
 * \return true if successful, false otherwise
 */
bool print_basic_run(hlcache_handle *content,
		const struct printer *printer,
		struct print_settings *settings)
{
	bool ret = true;

	assert(content != NULL && printer != NULL && settings != NULL);
	
	if (print_set_up(content, printer, settings, NULL))
		return false;

	while (ret && (done_height < content_get_height(printed_content)) ) {
		ret = print_draw_next_page(printer, settings);
	}

	print_cleanup(content, printer, settings);
	
	return ret;
}
Пример #8
0
/**
 * This function prepares the content to be printed. The current browser content
 * is duplicated and resized, printer initialization is called.
 *
 * \param content The content to be printed
 * \param printer The printer interface for the printer to be used
 * \param settings The settings for printing to use
 * \param height updated to the height of the printed content
 * \return true if successful, false otherwise
 */
bool print_set_up(hlcache_handle *content,
		const struct printer *printer, struct print_settings *settings,
		double *height)
{
	printed_content = print_init(content, settings);
	
	if (printed_content == NULL)
		return false;
	
	print_apply_settings(printed_content, settings);

	if (height)
		*height = content_get_height(printed_content);
	
	printer->print_begin(settings);

	done_height = 0;
	
	return true;	
}
Пример #9
0
/**
 * The content is resized to fit page width.
 *
 * \param content The content to be printed
 * \param settings The settings for printing to use
 * \return true if successful, false otherwise
 */
bool print_apply_settings(hlcache_handle *content,
			  struct print_settings *settings)
{
	if (settings == NULL)
		return false;
	
	/* Apply settings - adjust page size etc */

	page_content_width = (settings->page_width - 
			FIXTOFLT(FSUB(settings->margins[MARGINLEFT],
			settings->margins[MARGINRIGHT]))) / settings->scale;
	
	page_content_height = (settings->page_height - 
			FIXTOFLT(FSUB(settings->margins[MARGINTOP],
			settings->margins[MARGINBOTTOM]))) / settings->scale;
	
	content_reformat(content, false, page_content_width, 0);

	LOG("New layout applied.New height = %d ; New width = %d ", content_get_height(content), content_get_width(content));
	
	return true;
}
Пример #10
0
/* queue a window scroll */
static void
widget_scroll_y(struct gui_window *gw, int y, bool abs)
{
	struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser);
	int content_height;
	int height;
	float scale = gw->bw->scale;

	LOG(("window scroll"));
	if (abs) {
		bwidget->pany = y - bwidget->scrolly;
	} else {
		bwidget->pany += y;
	}

	content_height = content_get_height(gw->bw->current_content) * scale;

	height = fbtk_get_height(gw->browser);

	/* dont pan off the top */
	if ((bwidget->scrolly + bwidget->pany) < 0)
		bwidget->pany = -bwidget->scrolly;

	/* do not pan off the bottom of the content */
	if ((bwidget->scrolly + bwidget->pany) > (content_height - height))
		bwidget->pany = (content_height - height) - bwidget->scrolly;

	if (bwidget->pany == 0)
		return;

	bwidget->pan_required = true;

	fbtk_request_redraw(gw->browser);

	fbtk_set_scroll_position(gw->vscroll, bwidget->scrolly + bwidget->pany);
}
Пример #11
0
/**
 * Callback for (i)frame scrollbars.
 */
void browser_window_scroll_callback(void *client_data,
		struct scrollbar_msg_data *scrollbar_data)
{
	struct browser_window *bw = client_data;

	switch(scrollbar_data->msg) {
	case SCROLLBAR_MSG_MOVED:
		if (bw->browser_window_type == BROWSER_WINDOW_IFRAME) {
			html_redraw_a_box(bw->parent->current_content, bw->box);
		} else {
			struct rect rect;

			rect.x0 = scrollbar_get_offset(bw->scroll_x);
			rect.y0 = scrollbar_get_offset(bw->scroll_y);
			rect.x1 = rect.x0 + bw->width;
			rect.y1 = rect.y0 + bw->height;

			browser_window_update_box(bw, &rect);
		}
		break;
	case SCROLLBAR_MSG_SCROLL_START:
	{
		struct rect rect = {
			.x0 = scrollbar_data->x0,
			.y0 = scrollbar_data->y0,
			.x1 = scrollbar_data->x1,
			.y1 = scrollbar_data->y1
		};

		if (scrollbar_is_horizontal(scrollbar_data->scrollbar))
			browser_window_set_drag_type(bw, DRAGGING_SCR_X, &rect);
		else
			browser_window_set_drag_type(bw, DRAGGING_SCR_Y, &rect);
	}
		break;
	case SCROLLBAR_MSG_SCROLL_FINISHED:
		browser_window_set_drag_type(bw, DRAGGING_NONE, NULL);

		browser_window_set_pointer(bw, BROWSER_POINTER_DEFAULT);
		break;
	}
}

/* exported interface, documented in browser.h */
void browser_window_handle_scrollbars(struct browser_window *bw)
{
	hlcache_handle *h = bw->current_content;
	bool scroll_x;
	bool scroll_y;
	int c_width = 0;
	int c_height = 0;

	assert(!bw->window); /* Core-handled windows only */

	if (h != NULL) {
		c_width  = content_get_width(h);
		c_height = content_get_height(h);
	}

	if (bw->scrolling == SCROLLING_YES) {
		scroll_x = true;
		scroll_y = true;
	} else if (bw->scrolling == SCROLLING_AUTO &&
			bw->current_content) {
		int bw_width = bw->width;
		int bw_height = bw->height;

		/* subtract existing scrollbar width */
		bw_width -= bw->scroll_y ? SCROLLBAR_WIDTH : 0;
		bw_height -= bw->scroll_x ? SCROLLBAR_WIDTH : 0;

		scroll_y = (c_height > bw_height) ? true : false;
		scroll_x = (c_width > bw_width) ? true : false;
	} else {
		/* No scrollbars */
		scroll_x = false;
		scroll_y = false;
	}

	if (!scroll_x && bw->scroll_x != NULL) {
		scrollbar_destroy(bw->scroll_x);
		bw->scroll_x = NULL;
	}

	if (!scroll_y && bw->scroll_y != NULL) {
		scrollbar_destroy(bw->scroll_y);
		bw->scroll_y = NULL;
	}

	if (scroll_y) {
		int length = bw->height;
		int visible = bw->height - (scroll_x ? SCROLLBAR_WIDTH : 0);

		if (bw->scroll_y == NULL) {
			/* create vertical scrollbar */
			if (!scrollbar_create(false, length, c_height, visible,
					bw, browser_window_scroll_callback,
					&(bw->scroll_y)))
				return;
		} else {
			/* update vertical scrollbar */
			scrollbar_set_extents(bw->scroll_y, length,
					visible, c_height);
		}
	}

	if (scroll_x) {
		int length = bw->width - (scroll_y ? SCROLLBAR_WIDTH : 0);
		int visible = length;

		if (bw->scroll_x == NULL) {
			/* create horizontal scrollbar */
			if (!scrollbar_create(true, length, c_width, visible,
					bw, browser_window_scroll_callback,
					&(bw->scroll_x)))
				return;
		} else {
			/* update horizontal scrollbar */
			scrollbar_set_extents(bw->scroll_x, length,
					visible, c_width);
		}
	}

	if (scroll_x && scroll_y)
		scrollbar_make_pair(bw->scroll_x, bw->scroll_y);
}
Пример #12
0
/*
	Report scroll event to the browser component.
*/
void browser_scroll( struct gui_window * gw, short mode, int value, bool abs )
{
	LGRECT work;
	int max_y_scroll;
	int max_x_scroll;
	int oldx = gw->browser->scroll.current.x;
	int oldy = gw->browser->scroll.current.y;
	struct s_browser * b = gw->browser;
	LOG((""));

	if( b->bw->current_content != NULL ) {
		browser_get_rect( gw, BR_CONTENT, &work);
		max_y_scroll = (content_get_height( b->bw->current_content ) - work.g_h );
		max_x_scroll = (content_get_width( b->bw->current_content ) - work.g_w);
	} else {
		return;
	}


	switch( mode ) {

		case WA_UPPAGE:
		case WA_UPLINE:
			if( max_y_scroll < 1 )
				return;
			if( abs == false )
				b->scroll.requested.y -= value;
			else
				b->scroll.requested.y = value - b->scroll.current.y;
		break;

		case WA_DNPAGE:
		case WA_DNLINE:
			if( max_y_scroll < 1 )
				return;
			if( abs == false )
				b->scroll.requested.y += value;
			else
				b->scroll.requested.y = value - b->scroll.current.y;
		break;

		case WA_LFPAGE:
		case WA_LFLINE:
			if( max_x_scroll < 1 )
				return;
			if( abs == false )
				b->scroll.requested.x -= value;
			else
				b->scroll.requested.x = value - b->scroll.current.x;
		break;

		case WA_RTPAGE:
		case WA_RTLINE:
			if( max_x_scroll < 1 )
				return;
			if( abs == false )
				b->scroll.requested.x += value;
			else
				b->scroll.requested.x = value - b->scroll.current.x;
		break;

		default: break;
	}

	if( b->scroll.current.y + b->scroll.requested.y < 0 ) {
			b->scroll.requested.y = -b->scroll.current.y;
	}

	if( b->scroll.current.y + b->scroll.requested.y > max_y_scroll  ) {
			b->scroll.requested.y = max_y_scroll - b->scroll.current.y;
	}

	if( b->scroll.current.x + b->scroll.requested.x < 0 ) {
			b->scroll.requested.x = -b->scroll.current.x;
	}

	if( b->scroll.current.x + b->scroll.requested.x > max_x_scroll ) {
			b->scroll.requested.x = max_x_scroll - b->scroll.current.x;
	}

	if( oldy != b->scroll.current.y + b->scroll.requested.y ||
		oldx != b->scroll.current.x + b->scroll.requested.x ) {
		b->scroll.required = true;
	}
}
Пример #13
0
/**
 * Callback for (i)frame scrollbars.
 */
void browser_window_scroll_callback(void *client_data,
		struct scrollbar_msg_data *scrollbar_data)
{
	struct browser_window *bw = client_data;

	switch(scrollbar_data->msg) {
	case SCROLLBAR_MSG_MOVED:
		if (bw->browser_window_type == BROWSER_WINDOW_IFRAME) {
			html_redraw_a_box(bw->parent->current_content, bw->box);
		} else {
			struct rect rect;

			rect.x0 = scrollbar_get_offset(bw->scroll_x);
			rect.y0 = scrollbar_get_offset(bw->scroll_y);
			rect.x1 = rect.x0 + bw->width;
			rect.y1 = rect.y0 + bw->height;

			browser_window_update_box(bw, &rect);
		}
		break;
	case SCROLLBAR_MSG_SCROLL_START:
	{
		struct rect rect = {
			.x0 = scrollbar_data->x0,
			.y0 = scrollbar_data->y0,
			.x1 = scrollbar_data->x1,
			.y1 = scrollbar_data->y1
		};

		if (scrollbar_is_horizontal(scrollbar_data->scrollbar))
			browser_window_set_drag_type(bw, DRAGGING_SCR_X, &rect);
		else
			browser_window_set_drag_type(bw, DRAGGING_SCR_Y, &rect);
	}
		break;
	case SCROLLBAR_MSG_SCROLL_FINISHED:
		browser_window_set_drag_type(bw, DRAGGING_NONE, NULL);

		browser_window_set_pointer(bw, BROWSER_POINTER_DEFAULT);
		break;
	}
}

/* exported interface, documented in browser.h */
void browser_window_handle_scrollbars(struct browser_window *bw)
{
	struct hlcache_handle *h = bw->current_content;
	bool scroll_x;
	bool scroll_y;
	int c_width = 0;
	int c_height = 0;

	assert(!bw->window); /* Core-handled windows only */

	if (h != NULL) {
		c_width  = content_get_width(h);
		c_height = content_get_height(h);
	}

	if (bw->scrolling == BW_SCROLLING_YES) {
		scroll_x = true;
		scroll_y = true;
	} else if (bw->scrolling == BW_SCROLLING_AUTO &&
			bw->current_content) {
		int bw_width = bw->width;
		int bw_height = bw->height;

		/* subtract existing scrollbar width */
		bw_width -= bw->scroll_y ? SCROLLBAR_WIDTH : 0;
		bw_height -= bw->scroll_x ? SCROLLBAR_WIDTH : 0;

		scroll_y = (c_height > bw_height) ? true : false;
		scroll_x = (c_width > bw_width) ? true : false;
	} else {
		/* No scrollbars */
		scroll_x = false;
		scroll_y = false;
	}

	if (!scroll_x && bw->scroll_x != NULL) {
		scrollbar_destroy(bw->scroll_x);
		bw->scroll_x = NULL;
	}

	if (!scroll_y && bw->scroll_y != NULL) {
		scrollbar_destroy(bw->scroll_y);
		bw->scroll_y = NULL;
	}

	if (scroll_y) {
		int length = bw->height;
		int visible = bw->height - (scroll_x ? SCROLLBAR_WIDTH : 0);

		if (bw->scroll_y == NULL) {
			/* create vertical scrollbar */
			if (scrollbar_create(false, length, c_height, visible,
					     bw, browser_window_scroll_callback,
					     &(bw->scroll_y)) != NSERROR_OK) {
				return;
			}
		} else {
			/* update vertical scrollbar */
			scrollbar_set_extents(bw->scroll_y, length,
					visible, c_height);
		}
	}

	if (scroll_x) {
		int length = bw->width - (scroll_y ? SCROLLBAR_WIDTH : 0);
		int visible = length;

		if (bw->scroll_x == NULL) {
			/* create horizontal scrollbar */
			if (scrollbar_create(true, length, c_width, visible,
					     bw, browser_window_scroll_callback,
					     &(bw->scroll_x)) != NSERROR_OK) {
				return;
			}
		} else {
			/* update horizontal scrollbar */
			scrollbar_set_extents(bw->scroll_x, length,
					visible, c_width);
		}
	}

	if (scroll_x && scroll_y)
		scrollbar_make_pair(bw->scroll_x, bw->scroll_y);
}


/* exported function documented in desktop/frames.h */
nserror browser_window_create_iframes(struct browser_window *bw,
		struct content_html_iframe *iframe)
{
	struct browser_window *window;
	struct content_html_iframe *cur;
	struct rect rect;
	int iframes = 0;
	int index;
	nserror ret = NSERROR_OK;

	if (iframe == NULL) {
		return NSERROR_BAD_PARAMETER;
	}

	/* Count iframe list and allocate enough space within the
	 * browser window.
	 */
	for (cur = iframe; cur; cur = cur->next) {
		iframes++;
	}
	bw->iframes = calloc(iframes, sizeof(*bw));
	if (!bw->iframes) {
		return NSERROR_NOMEM;
	}
	bw->iframe_count = iframes;

	index = 0;
	for (cur = iframe; cur; cur = cur->next) {
		window = &(bw->iframes[index++]);

		/* Initialise common parts */
		browser_window_initialise_common(BW_CREATE_NONE,
				window, NULL);

		/* window characteristics */
		window->browser_window_type = BROWSER_WINDOW_IFRAME;
		window->scrolling = cur->scrolling;
		window->border = cur->border;
		window->border_colour = cur->border_colour;
		window->no_resize = true;
		window->margin_width = cur->margin_width;
		window->margin_height = cur->margin_height;
		window->scale = bw->scale;
		if (cur->name != NULL) {
			window->name = strdup(cur->name);
			if (window->name == NULL) {
				free(bw->iframes) ;
				bw->iframes = 0;
				bw->iframe_count = 0;
				return NSERROR_NOMEM;
			}
		}

		/* linking */
		window->box = cur->box;
		window->parent = bw;
		window->box->iframe = window;

		/* iframe dimensions */
		box_bounds(window->box, &rect);

		browser_window_set_position(window, rect.x0, rect.y0);
		browser_window_set_dimensions(window, rect.x1 - rect.x0,
				rect.y1 - rect.y0);
	}

	/* calculate dimensions */
	browser_window_update_extent(bw);
	browser_window_recalculate_iframes(bw);

	index = 0;
	for (cur = iframe; cur; cur = cur->next) {
		window = &(bw->iframes[index++]);
		if (cur->url) {
			/* fetch iframe's content */
			ret = browser_window_navigate(window,
				cur->url,
				hlcache_handle_get_url(bw->current_content),
				BW_NAVIGATE_UNVERIFIABLE,
				NULL,
				NULL,
				bw->current_content);
		}
	}

	return ret;
}


/**
 * Recalculate iframe positions following a resize.
 *
 * \param  bw	    The browser window to reposition iframes for
 */

void browser_window_recalculate_iframes(struct browser_window *bw)
{
	struct browser_window *window;
	int index;

	for (index = 0; index < bw->iframe_count; index++) {
		window = &(bw->iframes[index]);

		if (window != NULL) {
			browser_window_handle_scrollbars(window);
		}
	}
}


/* exported interface documented in desktop/frames.h */
nserror browser_window_create_frameset(struct browser_window *bw,
		struct content_html_frames *frameset)
{
	int row, col, index;
	struct content_html_frames *frame;
	struct browser_window *window;
	hlcache_handle *parent;

	assert(bw && frameset);

	/* 1. Create children */
	assert(bw->children == NULL);
	assert(frameset->cols + frameset->rows != 0);

	bw->children = calloc((frameset->cols * frameset->rows), sizeof(*bw));
	if (!bw->children) {
		return NSERROR_NOMEM;
	}

	bw->cols = frameset->cols;
	bw->rows = frameset->rows;
	for (row = 0; row < bw->rows; row++) {
		for (col = 0; col < bw->cols; col++) {
			index = (row * bw->cols) + col;
			frame = &frameset->children[index];
			window = &bw->children[index];

			/* Initialise common parts */
			browser_window_initialise_common(BW_CREATE_NONE,
					window, NULL);

			/* window characteristics */
			if (frame->children)
				window->browser_window_type =
						BROWSER_WINDOW_FRAMESET;
			else
				window->browser_window_type =
						BROWSER_WINDOW_FRAME;
			window->scrolling = frame->scrolling;
			window->border = frame->border;
			window->border_colour = frame->border_colour;
			window->no_resize = frame->no_resize;
			window->frame_width = frame->width;
			window->frame_height = frame->height;
			window->margin_width = frame->margin_width;
			window->margin_height = frame->margin_height;
			if (frame->name) {
				window->name = strdup(frame->name);
				if (!window->name) {
					free(bw->children);
					bw->children = NULL;
					return NSERROR_NOMEM;
				}
			}

			window->scale = bw->scale;

			/* linking */
			window->parent = bw;

			if (window->name)
				LOG("Created frame '%s'", window->name);
			else
				LOG("Created frame (unnamed)");
		}
	}

	/* 2. Calculate dimensions */
	browser_window_update_extent(bw);
	browser_window_recalculate_frameset(bw);

	/* 3. Recurse for grandchildren */
	for (row = 0; row < bw->rows; row++) {
		for (col = 0; col < bw->cols; col++) {
			index = (row * bw->cols) + col;
			frame = &frameset->children[index];
			window = &bw->children[index];

			if (frame->children)
				browser_window_create_frameset(window, frame);
		}
	}

	/* Use the URL of the first ancestor window containing html content
	 * as the referer */
	for (window = bw; window->parent; window = window->parent) {
		if (window->current_content &&
				content_get_type(window->current_content) ==
				CONTENT_HTML)
			break;
	}

	parent = window->current_content;

	/* 4. Launch content */
	for (row = 0; row < bw->rows; row++) {
		for (col = 0; col < bw->cols; col++) {
			index = (row * bw->cols) + col;
			frame = &frameset->children[index];
			window = &bw->children[index];

			if (frame->url) {
				browser_window_navigate(window,
					frame->url,
					hlcache_handle_get_url(parent),
					BW_NAVIGATE_HISTORY |
					BW_NAVIGATE_UNVERIFIABLE,
					NULL,
					NULL,
					parent);
			}
		}
	}

	return NSERROR_OK;
}
Пример #14
0
bool save_as_draw(hlcache_handle *h, const char *path)
{
	pencil_code code;
	char *drawfile_buffer;
	struct rect clip;
	struct content_redraw_data data;
	size_t drawfile_size;
	os_error *error;
	struct redraw_context ctx = {
		.interactive = false,
		.background_images = true,
		.plot = &ro_save_draw_plotters
	};

	ro_save_draw_diagram = pencil_create();
	if (!ro_save_draw_diagram) {
		warn_user("NoMemory", 0);
		return false;
	}

	ro_save_draw_width = content_get_width(h);
	ro_save_draw_height = content_get_height(h);

	clip.x0 = clip.y0 = INT_MIN;
	clip.x1 = clip.y1 = INT_MAX;

	data.x = 0;
	data.y = -ro_save_draw_height;
	data.width = ro_save_draw_width;
	data.height = ro_save_draw_height;
	data.background_colour = 0xFFFFFF;
	data.scale = 1;
	data.repeat_x = false;
	data.repeat_y = false;

	if (!content_redraw(h, &data, &clip, &ctx)) {
		pencil_free(ro_save_draw_diagram);
		return false;
	}

	/*pencil_dump(ro_save_draw_diagram);*/

	code = pencil_save_drawfile(ro_save_draw_diagram, "NetSurf",
			&drawfile_buffer, &drawfile_size);
	if (code != pencil_OK) {
		warn_user("SaveError", 0);
		pencil_free(ro_save_draw_diagram);
		return false;
	}
	assert(drawfile_buffer);

	error = xosfile_save_stamped(path, osfile_TYPE_DRAW,
			(byte *) drawfile_buffer, 
			(byte *) drawfile_buffer + drawfile_size);
	if (error) {
		LOG("xosfile_save_stamped failed: 0x%x: %s", error->errnum, error->errmess);
		warn_user("SaveError", error->errmess);
		pencil_free(ro_save_draw_diagram);
		return false;
	}

	pencil_free(ro_save_draw_diagram);

	return true;
}

bool ro_save_draw_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style)
{
	pencil_code code;
	const int path[] = { draw_MOVE_TO, x0 * 2, -y0 * 2 - 1,
			     draw_LINE_TO, x1 * 2, -y0 * 2 - 1,
			     draw_LINE_TO, x1 * 2, -y1 * 2 - 1,
			     draw_LINE_TO, x0 * 2, -y1 * 2 - 1,
			     draw_CLOSE_LINE,
			     draw_END_PATH };

        if (style->fill_type != PLOT_OP_TYPE_NONE) { 

		code = pencil_path(ro_save_draw_diagram, 
				   path,
				   sizeof path / sizeof path[0],
				   style->fill_colour << 8, 
				   pencil_TRANSPARENT, 
				   0, 
				   pencil_JOIN_MITRED,
				   pencil_CAP_BUTT, 
				   pencil_CAP_BUTT, 
				   0, 
				   0, 
				   false,
				   pencil_SOLID);
		if (code != pencil_OK)
			return ro_save_draw_error(code);
	}

        if (style->stroke_type != PLOT_OP_TYPE_NONE) { 

		code = pencil_path(ro_save_draw_diagram, 
				   path,
				   sizeof path / sizeof path[0],
				   pencil_TRANSPARENT, 
				   style->stroke_colour << 8, 
				   style->stroke_width, 
				   pencil_JOIN_MITRED,
				   pencil_CAP_BUTT, 
				   pencil_CAP_BUTT, 
				   0, 
				   0, 
				   false,
				   pencil_SOLID);

		if (code != pencil_OK)
			return ro_save_draw_error(code);
	}
	return true;
}
Пример #15
0
static nserror
html_object_callback(hlcache_handle *object,
		     const hlcache_event *event,
		     void *pw)
{
	struct content_html_object *o = pw;
	html_content *c = (html_content *) o->parent;
	int x, y;
	struct box *box;

	assert(c->base.status != CONTENT_STATUS_ERROR);

	box = o->box;
	if (box == NULL && event->type != CONTENT_MSG_ERROR) {
		return NSERROR_OK;
	}

	switch (event->type) {
	case CONTENT_MSG_LOADING:
		if (c->base.status != CONTENT_STATUS_LOADING && c->bw != NULL)
			content_open(object,
					c->bw, &c->base,
					box->object_params);
		break;

	case CONTENT_MSG_READY:
		if (content_can_reformat(object)) {
			/* TODO: avoid knowledge of box internals here */
			content_reformat(object, false,
					box->max_width != UNKNOWN_MAX_WIDTH ?
							box->width : 0,
					box->max_width != UNKNOWN_MAX_WIDTH ?
							box->height : 0);

			/* Adjust parent content for new object size */
			html_object_done(box, object, o->background);
			if (c->base.status == CONTENT_STATUS_READY ||
					c->base.status == CONTENT_STATUS_DONE)
				content__reformat(&c->base, false,
						c->base.available_width,
						c->base.height);
		}
		break;

	case CONTENT_MSG_DONE:
		c->base.active--;
		LOG("%d fetches active", c->base.active);

		html_object_done(box, object, o->background);

		if (c->base.status != CONTENT_STATUS_LOADING &&
				box->flags & REPLACE_DIM) {
			union content_msg_data data;

			if (!box_visible(box))
				break;

			box_coords(box, &x, &y);

			data.redraw.x = x + box->padding[LEFT];
			data.redraw.y = y + box->padding[TOP];
			data.redraw.width = box->width;
			data.redraw.height = box->height;
			data.redraw.full_redraw = true;

			content_broadcast(&c->base, CONTENT_MSG_REDRAW, data);
		}
		break;

	case CONTENT_MSG_ERROR:
		hlcache_handle_release(object);

		o->content = NULL;

		if (box != NULL) {
			c->base.active--;
			LOG("%d fetches active", c->base.active);

			content_add_error(&c->base, "?", 0);
			html_object_failed(box, c, o->background);
		}
		break;

	case CONTENT_MSG_REDRAW:
		if (c->base.status != CONTENT_STATUS_LOADING) {
			union content_msg_data data = event->data;

			if (!box_visible(box))
				break;

			box_coords(box, &x, &y);

			if (object == box->background) {
				/* Redraw request is for background */
				css_fixed hpos = 0, vpos = 0;
				css_unit hunit = CSS_UNIT_PX;
				css_unit vunit = CSS_UNIT_PX;
				int width = box->padding[LEFT] + box->width +
						box->padding[RIGHT];
				int height = box->padding[TOP] + box->height +
						box->padding[BOTTOM];
				int t, h, l, w;

				/* Need to know background-position */
				css_computed_background_position(box->style,
						&hpos, &hunit, &vpos, &vunit);

				w = content_get_width(box->background);
				if (hunit == CSS_UNIT_PCT) {
					l = (width - w) * hpos / INTTOFIX(100);
				} else {
					l = FIXTOINT(nscss_len2px(hpos, hunit,
							box->style));
				}

				h = content_get_height(box->background);
				if (vunit == CSS_UNIT_PCT) {
					t = (height - h) * vpos / INTTOFIX(100);
				} else {
					t = FIXTOINT(nscss_len2px(vpos, vunit,
							box->style));
				}

				/* Redraw area depends on background-repeat */
				switch (css_computed_background_repeat(
						box->style)) {
				case CSS_BACKGROUND_REPEAT_REPEAT:
					data.redraw.x = 0;
					data.redraw.y = 0;
					data.redraw.width = box->width;
					data.redraw.height = box->height;
					break;

				case CSS_BACKGROUND_REPEAT_REPEAT_X:
					data.redraw.x = 0;
					data.redraw.y += t;
					data.redraw.width = box->width;
					break;

				case CSS_BACKGROUND_REPEAT_REPEAT_Y:
					data.redraw.x += l;
					data.redraw.y = 0;
					data.redraw.height = box->height;
					break;

				case CSS_BACKGROUND_REPEAT_NO_REPEAT:
					data.redraw.x += l;
					data.redraw.y += t;
					break;

				default:
					break;
				}

				data.redraw.object_width = box->width;
				data.redraw.object_height = box->height;

				/* Add offset to box */
				data.redraw.x += x;
				data.redraw.y += y;
				data.redraw.object_x += x;
				data.redraw.object_y += y;

				content_broadcast(&c->base,
						CONTENT_MSG_REDRAW, data);
				break;

			} else {
				/* Non-background case */
				if (hlcache_handle_get_content(object) ==
						event->data.redraw.object) {

					int w = content_get_width(object);
					int h = content_get_height(object);

					if (w != 0) {
						data.redraw.x =
							data.redraw.x *
							box->width / w;
						data.redraw.width =
							data.redraw.width *
							box->width / w;
					}

					if (h != 0) {
						data.redraw.y =
							data.redraw.y *
							box->height / h;
						data.redraw.height =
							data.redraw.height *
							box->height / h;
					}

					data.redraw.object_width = box->width;
					data.redraw.object_height = box->height;
				}

				data.redraw.x += x + box->padding[LEFT];
				data.redraw.y += y + box->padding[TOP];
				data.redraw.object_x += x + box->padding[LEFT];
				data.redraw.object_y += y + box->padding[TOP];
			}

			content_broadcast(&c->base, CONTENT_MSG_REDRAW, data);
		}
		break;

	case CONTENT_MSG_REFRESH:
		if (content_get_type(object) == CONTENT_HTML) {
			/* only for HTML objects */
			guit->misc->schedule(event->data.delay * 1000,
					html_object_refresh, o);
		}

		break;

	case CONTENT_MSG_LINK:
		/* Don't care about favicons that aren't on top level content */
		break;

	case CONTENT_MSG_GETCTX:
		*(event->data.jscontext) = NULL;
		break;

	case CONTENT_MSG_SCROLL:
		if (box->scroll_x != NULL)
			scrollbar_set(box->scroll_x, event->data.scroll.x0,
					false);
		if (box->scroll_y != NULL)
			scrollbar_set(box->scroll_y, event->data.scroll.y0,
					false);
		break;

	case CONTENT_MSG_DRAGSAVE:
	{
		union content_msg_data msg_data;
		if (event->data.dragsave.content == NULL)
			msg_data.dragsave.content = object;
		else
			msg_data.dragsave.content =
					event->data.dragsave.content;

		content_broadcast(&c->base, CONTENT_MSG_DRAGSAVE, msg_data);
	}
		break;

	case CONTENT_MSG_SAVELINK:
	case CONTENT_MSG_POINTER:
	case CONTENT_MSG_SELECTMENU:
	case CONTENT_MSG_GADGETCLICK:
		/* These messages are for browser window layer.
		 * we're not interested, so pass them on. */
		content_broadcast(&c->base, event->type, event->data);
		break;

	case CONTENT_MSG_CARET:
	{
		union html_focus_owner focus_owner;
		focus_owner.content = box;

		switch (event->data.caret.type) {
		case CONTENT_CARET_REMOVE:
		case CONTENT_CARET_HIDE:
			html_set_focus(c, HTML_FOCUS_CONTENT, focus_owner,
					true, 0, 0, 0, NULL);
			break;
		case CONTENT_CARET_SET_POS:
			html_set_focus(c, HTML_FOCUS_CONTENT, focus_owner,
					false, event->data.caret.pos.x,
					event->data.caret.pos.y,
					event->data.caret.pos.height,
					event->data.caret.pos.clip);
			break;
		}
	}
		break;

	case CONTENT_MSG_DRAG:
	{
		html_drag_type drag_type = HTML_DRAG_NONE;
		union html_drag_owner drag_owner;
		drag_owner.content = box;

		switch (event->data.drag.type) {
		case CONTENT_DRAG_NONE:
			drag_type = HTML_DRAG_NONE;
			drag_owner.no_owner = true;
			break;
		case CONTENT_DRAG_SCROLL:
			drag_type = HTML_DRAG_CONTENT_SCROLL;
			break;
		case CONTENT_DRAG_SELECTION:
			drag_type = HTML_DRAG_CONTENT_SELECTION;
			break;
		}
		html_set_drag_type(c, drag_type, drag_owner,
				event->data.drag.rect);
	}
		break;

	case CONTENT_MSG_SELECTION:
	{
		html_selection_type sel_type;
		union html_selection_owner sel_owner;

		if (event->data.selection.selection) {
			sel_type = HTML_SELECTION_CONTENT;
			sel_owner.content = box;
		} else {
			sel_type = HTML_SELECTION_NONE;
			sel_owner.none = true;
		}
		html_set_selection(c, sel_type, sel_owner,
				event->data.selection.read_only);
	}
		break;

	default:
		break;
	}

	if (c->base.status == CONTENT_STATUS_READY && c->base.active == 0 &&
			(event->type == CONTENT_MSG_LOADING ||
			event->type == CONTENT_MSG_DONE ||
			event->type == CONTENT_MSG_ERROR)) {
		/* all objects have arrived */
		content__reformat(&c->base, false, c->base.available_width,
				c->base.height);
		content_set_done(&c->base);
	}

	/* If  1) the configuration option to reflow pages while objects are
	 *        fetched is set
	 *     2) an object is newly fetched & converted,
	 *     3) the box's dimensions need to change due to being replaced
	 *     4) the object's parent HTML is ready for reformat,
	 *     5) the time since the previous reformat is more than the
	 *        configured minimum time between reformats
	 * then reformat the page to display newly fetched objects */
	else if (nsoption_bool(incremental_reflow) &&
			event->type == CONTENT_MSG_DONE &&
			box != NULL && !(box->flags & REPLACE_DIM) &&
			(c->base.status == CONTENT_STATUS_READY ||
			 c->base.status == CONTENT_STATUS_DONE) &&
			(wallclock() > c->base.reformat_time)) {
		content__reformat(&c->base, false, c->base.available_width,
				c->base.height);
	}

	return NSERROR_OK;
}