/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ /* ** This file contains a couple of routines which might be useful ** in a cross platform way for dealing with the calculations ** involved in table printing. */ #include "xlate_i.h" PRIVATE XP_Bool too_big(MWContext* cx, int size) { return size >= (cx->prInfo->page_height/8)*7; } /* ** Called by the FE_Display* functions with the Y span of the item to be ** displayed. Used to find page breaks and to reject items which are ** not on the current page. ** ** Returns: ** TRUE means display the item ** FALSE means do not display the item ** ** Requires: ** cx->prInfo to point to a record which contains the following ** information: ** ** page_topy: DOC Y coord of top of this page. ** page_break: During layout, initialize this to ** page_topy+page_height; ** page_height: The physical height of a piece of paper, ** minus top and bottom margins. ** phase: XL__PHASE ** ** If invoked with XP_LayoutForPrint and XP_DrawForPrint, this ** will be done automatically. */ PUBLIC XP_Bool XP_CheckElementSpan(MWContext*cx, int top, int height) { int bottom; /* ** During load phase, or if this doesn't appear to be a print ** related call, we do nothing. */ if (cx->prInfo == NULL || cx->prInfo->phase == 0) return TRUE; if (cx->prInfo->phase == XL_LOADING_PHASE) return FALSE; bottom = top + height - 1; /* ** Layout phase is used purely to compute the page breaks for each page. ** we always return FALSE, but look carefully at items which span the ** page boundry and pick for the actual page break the y minimum of ** "acceptable" items which span the physical page boundry. */ if (cx->prInfo->phase == XL_LAYOUT_PHASE) { if (!too_big(cx, height) && top >= cx->prInfo->page_topy && top < cx->prInfo->page_topy + cx->prInfo->page_height && bottom >= cx->prInfo->page_topy + cx->prInfo->page_height) { /* ** This item won't fit on this page, and is small enough to consider ** breaking a page for. */ if (top < cx->prInfo->page_break) { cx->prInfo->page_break = top; } } return FALSE; } /* ** Which leaves only the actual generation phase. */ /* ** Trivial reject of items which aren't on the page at all */ if (bottom < cx->prInfo->page_topy || top > cx->prInfo->page_break) { return FALSE; } /* ** Complete acceptance of items which fall entirely on the current page */ if (top >= cx->prInfo->page_topy && bottom <= cx->prInfo->page_break) { return TRUE; } /* ** Also print items which overhang the soft boundry, but not the hard ** page boundry. */ if (bottom < cx->prInfo->page_topy + cx->prInfo->page_height) { return TRUE; } /* ** It straddles the page break. If it's big, then print it, and let it ** get chopped off. If it is small, it will display on the next page. */ return too_big(cx, height); } /* ** Call to set up the page counting fields in the printinfo structure */ PUBLIC void XP_InitializePrintInfo(MWContext *cx) { if (cx->prInfo == NULL) { PrintInfo *p; p = XP_NEW_ZAP(PrintInfo); if (!p) return; cx->prInfo = p; } cx->prInfo->n_pages = 0; cx->prInfo->phase = XL_DRAW_PHASE; } PUBLIC void XP_CleanupPrintInfo(MWContext *cx) { PrintInfo *p = cx->prInfo; if (p) { if (p->pages) { free(p->pages); p->pages = NULL; } free(p); cx->prInfo = NULL; } } PUBLIC void XP_LayoutForPrint(MWContext *cx, int32 doc_height) { int32 y; int saveit; saveit = cx->prInfo->phase; cx->prInfo->phase = XL_LAYOUT_PHASE; y = 0; while (y < doc_height) { cx->prInfo->page_topy = y; cx->prInfo->page_break = y + cx->prInfo->page_height; LO_RefreshArea(cx, 0, y, cx->prInfo->page_width, cx->prInfo->page_height); if (cx->prInfo->n_pages >= cx->prInfo->pt_size) { cx->prInfo->pt_size += 100; cx->prInfo->pages = (PageBreaks*)realloc( cx->prInfo->pages, cx->prInfo->pt_size * sizeof (PageBreaks)); if ( !cx->prInfo->pages ) { extern int MK_OUT_OF_MEMORY; cx->prInfo->n_pages = MK_OUT_OF_MEMORY; return; } } cx->prInfo->pages[cx->prInfo->n_pages].y_top = y; cx->prInfo->pages[cx->prInfo->n_pages].y_break = cx->prInfo->page_break-1; cx->prInfo->n_pages++; y = cx->prInfo->page_break; } cx->prInfo->phase = saveit; } PUBLIC void XP_DrawForPrint(MWContext *cx, int page) { int32 t; int saveit; saveit = cx->prInfo->phase; cx->prInfo->phase = XL_DRAW_PHASE; t = cx->prInfo->pages[page].y_top; cx->prInfo->page_topy = t; cx->prInfo->page_break = cx->prInfo->pages[page].y_break; LO_RefreshArea(cx, 0, t, cx->prInfo->page_width, cx->prInfo->page_height); cx->prInfo->phase = saveit; }