|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: D T
Length: 28500 (0x6f54)
Types: TextFile
Names: »DocViewer.c«
└─⟦8648bda34⟧ Bits:30007244 EUUGD5_II: X11R5
└─⟦87c3ac0e0⟧ »./contrib-3/contrib-3.00«
└─⟦de8ce1454⟧
└─⟦this⟧ »contrib/lib/iv/src/bin/doc/DocViewer.c«
/*
* Copyright (c) 1991 Stanford University
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Stanford not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Stanford makes no representations about
* the suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* DocumentViewer
*/
#include "DocViewer.h"
#include "Application.h"
#include "Command.h"
#include "Document.h"
#include "ItemView.h"
#include "Keymap.h"
#include "Menus.h"
#include "NoPrint.h"
#include "PageBorder.h"
#include "PageButton.h"
#include "TextItem.h"
#include "PagingView.h"
#include "MinipageView.h"
#include "PSFigView.h"
#include "RefView.h"
#include "TabularView.h"
#include "PagenoView.h"
#include "CounterView.h"
#include "LabelView.h"
#include "FloatView.h"
#include "properties.h"
#include <IV-look/button.h>
#include <InterViews/background.h>
#include <InterViews/border.h>
#include <InterViews/box.h>
#include <InterViews/center.h>
#include <InterViews/color.h>
#include <InterViews/composition.h>
#include <InterViews/discretion.h>
#include <InterViews/font.h>
#include <InterViews/glue.h>
#include <InterViews/hit.h>
#include <InterViews/label.h>
#include <InterViews/listener.h>
#include <InterViews/margin.h>
#include <InterViews/patch.h>
#include <InterViews/printer.h>
#include <InterViews/simplecomp.h>
#include <InterViews/world.h>
#include <InterViews/deck.h>
#include <InterViews/page.h>
#include <InterViews/shadow.h>
#include <InterViews/window.h>
#include <OS/math.h>
#include <fstream.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
class ViewerMenuInfo {
public:
char* _name;
DocMenubar* _menubar;
};
class ViewerKeymapInfo {
public:
char* _name;
DocKeymap* _keymap;
};
class ViewerFloatInfo {
public:
Item* _item;
Glyph* _view;
Coord _x;
Coord _y;
long _page;
Coord _repel_left;
Coord _repel_right;
Coord _repel_top;
Coord _repel_bottom;
};
class ViewerPageInfo {
public:
Telltale* _telltale;
char* _label;
};
class ViewerColorInfo {
public:
char* _name;
const Color* _overlay;
const Color* _underlay;
};
#include "list.h"
declareList(ViewerMenuInfo_List,ViewerMenuInfo)
implementList(ViewerMenuInfo_List,ViewerMenuInfo)
declareList(ViewerKeymapInfo_List,ViewerKeymapInfo)
implementList(ViewerKeymapInfo_List,ViewerKeymapInfo)
declareList(ViewerFloatInfo_List,ViewerFloatInfo)
implementList(ViewerFloatInfo_List,ViewerFloatInfo)
declareList(ViewerPageInfo_List,ViewerPageInfo)
implementList(ViewerPageInfo_List,ViewerPageInfo)
declareList(ViewerColorInfo_List,ViewerColorInfo)
implementList(ViewerColorInfo_List,ViewerColorInfo)
DocumentViewer::DocumentViewer (
Application* application, Document* document
) : ApplicationWindow(_top = new Patch(nil)), Handler() {
_application = application;
_document = document;
_document->ref();
World* world = World::current();
const Color* fg = world->foreground();
const Color* bg = world->background();
const Font* font = world->font();
const char* insert_flash = world->property_value(INSERT_FLASH_RATE);
if (insert_flash != nil) {
_insert_flash = long(atof(insert_flash) * 1000000);
} else {
_insert_flash = 0;
}
const char* icon_font = world->property_value(PAGE_ICON_FONT);
if (icon_font != nil && Font::exists(world->display(), icon_font)) {
_icon_font = new Font(icon_font);
} else {
_icon_font = font;
}
_icon_font->ref();
_prev_page = new PageButton(
new HCenter(new Label("-", _icon_font, fg)), fg
);
_prev_page->ref();
_next_page = new PageButton(
new HCenter(new Label("+", _icon_font, fg)), fg
);
_next_page->ref();
_menu_info = new ViewerMenuInfo_List();
_keymap_info = new ViewerKeymapInfo_List();
_page_info = new ViewerPageInfo_List();
_float_info = new ViewerFloatInfo_List();
_color_info = new ViewerColorInfo_List();
_header_patch = new Patch(nil);
_page_patch = new Patch(nil);
_footer_patch = new Patch(new LRBox(_prev_page, _next_page));
_body_patch = new Patch(
new TBBox(
new Margin(
new PageBorder(new Margin(_page_patch, 1, 5, 5, 1), fg),
0, 0, 0, 0, fil, 0, 5, fil, 0, 0, 0, 0
),
_footer_patch
)
);
float leftmargin = _document->document_metric("leftsidemargin");
float rightmargin = _document->document_metric("rightsidemargin");
float bottommargin = _document->document_metric("bottommargin");
float topmargin = _document->document_metric("topmargin");
Listener* listener = new Listener(
new Background(
new TBBox(
new VCenter(_header_patch, 1.0),
new Margin(_body_patch, 5)
), bg
), this
);
listener->key(true);
listener->button(true);
_top->body(listener);
_pages = new Deck();
_view = new PagingView(this, nil, _document->body(), _pages);
_view->item_inserted(0L, _document->body()->item_count());
_view->update();
_page = new Page(_view);
_page_patch->body(
new Margin(_page, leftmargin, rightmargin, bottommargin, topmargin)
);
_starting_page = long(_document->document_metric("startingpage"));
_current_page = -1;
_menubar = nil;
_keymap = nil;
_focus = nil;
focus(_view);
_reshaped = true;
_document->attach(this);
}
DocumentViewer::~DocumentViewer () {
_top->body(nil);
_document->detach(this);
_prev_page->unref();
_next_page->unref();
if (_icon_font != nil) {
_icon_font->unref();
}
while (_color_info->count() > 0) {
ViewerColorInfo& info = _color_info->item(0);
delete info._name;
if (info._overlay != nil) {
info._overlay->unref();
}
if (info._underlay != nil) {
info._underlay->unref();
}
_color_info->remove(0);
}
delete _color_info;
while (_menu_info->count() > 0) {
ViewerMenuInfo& m = _menu_info->item(0);
delete m._name;
if (m._menubar != nil) {
m._menubar->unref();
}
_menu_info->remove(0);
}
delete _menu_info;
while (_keymap_info->count() > 0) {
ViewerKeymapInfo& m = _keymap_info->item(0);
delete m._name;
delete m._keymap;
_keymap_info->remove(0);
}
delete _keymap_info;
while (_float_info->count() > 0) {
ViewerFloatInfo& info = _float_info->item(0);
info._item->unref();
info._view->unref();
_float_info->remove(0);
}
delete _float_info;
while (_page_info->count() > 0) {
ViewerPageInfo& info = _page_info->item(0);
info._telltale->unref();
delete info._label;
_page_info->remove(0);
}
delete _page_info;
_document->unref();
}
Application* DocumentViewer::application () {
return _application;
}
Document* DocumentViewer::document () {
return _document;
}
Glyph* DocumentViewer::view (ItemView* parent, TextItem* text) {
TextView* view = new MinipageView(this, parent, text);
view->item_inserted(0L, text->item_count());
view->update();
return view;
}
Glyph* DocumentViewer::view (ItemView* parent, PSFigItem* psfig) {
PSFigView* view = new PSFigView(this, parent, psfig);
view->graphic_changed();
view->update();
return view;
}
Glyph* DocumentViewer::view (ItemView* parent, TabularItem* tabular) {
TabularView* view = new TabularView(this, parent, tabular);
view->rebuild();
view->update();
return view;
}
Glyph* DocumentViewer::view (ItemView* parent, RefItem* ref) {
RefView* view = new RefView(this, parent, ref);
view->update();
return view;
}
Glyph* DocumentViewer::view (
ItemView* parent, PagenumberItem* pagenumber
) {
PagenumberView* view = new PagenumberView(this, parent, pagenumber);
view->update();
return view;
}
Glyph* DocumentViewer::view (ItemView* parent, FloatItem* f) {
FloatView* view = new FloatView(this, parent, f);
view->update();
return view;
}
Glyph* DocumentViewer::view (ItemView* parent, CounterItem* counter) {
CounterView* view = new CounterView(this, parent, counter);
view->update();
return view;
}
Glyph* DocumentViewer::view (ItemView* parent, LabelItem* label) {
LabelView* view = new LabelView(this, parent, label);
view->update();
return view;
}
void DocumentViewer::event (Event& e) {
switch (e.type()) {
case Event::key:
if (_keymap != nil && _keymap->map(e)) {
break;
}
if (_focus != nil) {
_focus->event(e);
}
break;
case Event::down:
if (e.pointer_button() == Event::middle) {
manipulate(e);
} else if (e.pointer_button() == Event::right) {
menu(e);
}
break;
}
}
boolean DocumentViewer::command (const char* command) {
if (strncmp(command, "viewer", 6) == 0) {
World* world = World::current();
const char* keyword = command + 7;
highlight(keyword, true);
if (strcmp(keyword, "print") == 0) {
const char* name = _document->name();
if (name != nil && strlen(name) > 0) {
char buffer[256];
strcpy(buffer, name);
char* dot = strrchr(buffer, '.');
if (dot != nil) {
*dot = '\0';
}
strcat(buffer, ".");
strcat(
buffer, world->property_value(POSTSCRIPT_FILE_EXTENSION)
);
ofstream out(buffer);
Printer* ps = new Printer(&out);
const Allocation& a = _page_patch->allocation();
ps->prolog(name);
ps->resize(a.left(), a.bottom(), a.right(), a.top());
long current_page = _current_page;
long count = _page_info->count();
for (long i = 0; i < count; ++i) {
ps->page(_page_info->item(i)._label);
page_to(i);
_page_patch->print(ps, a);
}
page_to(current_page);
ps->epilog();
delete ps;
} else {
_application->report(this, "Please save file before printing");
}
} else if (strcmp(keyword, "view") == 0) {
_application->open(new DocumentViewer(_application, _document));
} else if (strcmp(keyword, "new") == 0) {
Document* document = _application->read("");
_application->open(new DocumentViewer(_application, document));
} else if (strcmp(keyword, "open") == 0) {
const char* file_name = _application->choose(
this, "Choose file to open:",
world->property_value(DOCUMENT_FILE_EXTENSION)
);
if (file_name != nil) {
Document* document = _application->read(file_name);
if (document != nil) {
document->name(file_name);
_application->open(
new DocumentViewer(_application, document)
);
} else {
_application->report(
this, "Bad file: possible version mismatch"
);
}
}
} else if (strcmp(keyword, "close") == 0) {
long confirm = _document->touched() ? NotConfirmed : Confirmed;
if (confirm != Confirmed) {
confirm = _application->confirm(
this, "File is modified: Save changes?"
);
}
if (confirm == Confirmed && _document->touched()) {
const char* file_name = _document->name();
if (file_name == nil || strlen(file_name) == 0) {
file_name = _application->choose(
this,
"Choose file for save:",
world->property_value(DOCUMENT_FILE_EXTENSION)
);
}
if (file_name == nil || strlen(file_name) == 0) {
confirm = Cancelled;
} else {
_document->name(file_name);
_application->write(_document, file_name);
}
}
if (confirm != Cancelled) {
_application->close(this);
}
} else if (strcmp(keyword, "save") == 0) {
const char* file_name = _document->name();
if (file_name == nil || strlen(file_name) == 0) {
file_name = _application->choose(
this,
"Choose file for save:",
world->property_value(DOCUMENT_FILE_EXTENSION)
);
}
if (file_name != nil && strlen(file_name) > 0) {
_document->name(file_name);
_application->write(_document, file_name);
}
} else if (strcmp(keyword, "saveas") == 0) {
const char* file_name = _application->choose(
this,
"Choose file for save:",
world->property_value(DOCUMENT_FILE_EXTENSION)
);
if (file_name != nil && strlen(file_name) > 0) {
_document->name(file_name);
_application->write(_document, file_name);
}
} else if (strcmp(keyword, "help") == 0) {
_application->report(this, "Help not implemented");
} else if (strcmp(keyword, "about") == 0) {
char about[100];
sprintf(about, "Doc version %s", world->property_value(VERSION));
_application->report(this, about);
}
highlight(keyword, false);
return false;
} else if (strncmp(command, "menubar", 7) == 0) {
menubar(command + 8);
return false;
} else if (strncmp(command, "keymap", 6) == 0) {
keymap(command + 7);
return false;
} else if (strcmp(command, "page forward") == 0) {
page_to(_current_page + 1);
return false;
} else if (strcmp(command, "page backward") == 0) {
page_to(_current_page - 1);
return false;
} else if (strncmp(command, "page", 4) == 0) {
page_to(atoi(command + 4));
return false;
} else {
return _application->command(command);
}
}
ItemView* DocumentViewer::focus () {
return _focus;
}
void DocumentViewer::focus (ItemView* view) {
if (view != _focus) {
if (_focus != nil) {
_focus->activate(false);
}
_focus = view;
if (_focus != nil) {
_focus->activate(true);
}
}
}
void DocumentViewer::choose (const char* tag, boolean choose) {
if (_menubar != nil) {
_menubar->choose(tag, choose);
}
}
void DocumentViewer::enable (const char* tag, boolean enable) {
if (_menubar != nil) {
_menubar->enable(tag, enable);
}
}
void DocumentViewer::highlight (const char* tag, boolean highlight) {
if (_menubar != nil) {
_menubar->highlight(tag, highlight);
}
World::current()->flush();
}
void DocumentViewer::menubar (const char* name) {
long count = _menu_info->count();
for (long i = 0; i < count; ++i) {
ViewerMenuInfo& m = _menu_info->item(i);
if (strcmp(m._name, name) == 0) {
break;
}
}
if (i == count) {
ViewerMenuInfo m;
m._name = strcpy(new char[strlen(name) + 1], name);
m._menubar = new DocMenubar(this, name);
m._menubar->ref();
_menu_info->append(m);
}
ViewerMenuInfo& m = _menu_info->item(i);
_menubar = m._menubar;
_header_patch->redraw();
_header_patch->body(m._menubar);
_header_patch->reallocate();
_header_patch->redraw();
}
void DocumentViewer::keymap (const char* name) {
long count = _keymap_info->count();
for (long i = 0; i < count; ++i) {
ViewerKeymapInfo& info = _keymap_info->item(i);
if (strcmp(info._name, name) == 0) {
break;
}
}
if (i == count) {
ViewerKeymapInfo info;
info._name = strcpy(new char[strlen(name) + 1], name);
info._keymap = new DocKeymap(this, name);
_keymap_info->append(info);
}
ViewerKeymapInfo& info = _keymap_info->item(i);
_keymap = info._keymap;
}
long DocumentViewer::insert_flash () {
return _insert_flash;
}
void DocumentViewer::highlight_colors (
const char* name, const Color*& overlay, const Color*& underlay
) {
long count = _color_info->count();
for (long i = 0; i < count; ++i) {
ViewerColorInfo& info = _color_info->item(i);
if (strcmp(info._name, name) == 0) {
break;
}
}
if (i == count) {
ViewerColorInfo info;
info._name = strcpy(new char[strlen(name) + 1], name);
World* world = World::current();
const Color* highlight = nil;
const char* hl = world->property_value(name);
if (hl != nil) {
highlight = Color::lookup(world->display(), hl);
}
if (highlight == nil) {
const char* default_hl = world->property_value(HIGHLIGHT_COLOR);
if (default_hl != nil) {
highlight = Color::lookup(world->display(), default_hl);
}
if (highlight == nil) {
highlight = new Color(0.8, 0.8, 0.8, 1.0);
}
}
Resource::ref(highlight);
const Color* fg = world->foreground();
const Color* bg = world->background();
if (highlight->distinguished(fg) && highlight->distinguished(bg)) {
info._underlay = highlight;
info._underlay->ref();
info._overlay = nil;
} else {
info._underlay = nil;
info._overlay = new Color(0.0, 0.0, 0.0, 1.0, Color::Xor);
info._overlay->ref();
}
highlight->unref();
_color_info->append(info);
}
ViewerColorInfo& info = _color_info->item(i);
overlay = info._overlay;
underlay = info._underlay;
}
void DocumentViewer::float_inserted (Item* item) {
ViewerFloatInfo info;
info._item = item;
info._item->ref();
info._view = nil;
info._x = 0;
info._y = 0;
info._page = -3;
info._repel_right = _document->document_metric("floatrepelright");
info._repel_left = _document->document_metric("floatrepelleft");
info._repel_top = _document->document_metric("floatrepeltop");
info._repel_bottom = _document->document_metric("floatrepelbottom");
_float_info->append(info);
_page->append(nil);
_page->show(_float_info->count()-1, false);
_reshaped = true;
}
void DocumentViewer::float_removed (Item* item) {
long count = _float_info->count();
for (long i = 0; i < count; ++i) {
if (_float_info->item(i)._item == item) {
break;
}
}
ViewerFloatInfo& info = _float_info->item(i);
info._item->unref();
Resource::unref(info._view);
_float_info->remove(i);
_page->show(i, false);
_page->remove(i);
_reshaped = true;
}
void DocumentViewer::float_changed (Item* item) {
long count = _float_info->count();
for (long i = 0; i < count; ++i) {
if (_float_info->item(i)._item == item) {
break;
}
}
ViewerFloatInfo& info = _float_info->item(i);
_page->change(i);
_body_patch->change(0);
_body_patch->reallocate();
_reshaped = true;
}
void DocumentViewer::float_adjusted (Item* item, float x, float y, long p) {
World::current()->flush();
long count = _float_info->count();
for (long i = 0; i < count; ++i) {
if (_float_info->item(i)._item == item) {
break;
}
}
ViewerFloatInfo& info = _float_info->item(i);
if (info._view == nil) {
info._view = item->view(nil, this);
info._view->ref();
}
if (info._page != p) {
Glyph* g;
if (p == -1) {
const Color* fg = World::current()->foreground();
const Color* bg = World::current()->background();
g = new NoPrint(
new Shadow(
new Background(new Border(info._view, fg, 1), bg), 4, -4,
new Color(0.0, 0.0, 0.0, 0.5)
)
);
} else {
g = info._view;
}
_page->replace(i, g);
boolean showing = (
p == -2 && _current_page > 0
|| p == -1
|| p == _current_page
);
_page->show(i, showing);
}
if (info._x != x || info._y != y) {
_page->move(i, x, y);
}
_page->change(i);
_body_patch->change(0);
_body_patch->reallocate();
_reshaped = true;
info._x = x;
info._y = y;
info._page = p;
}
long DocumentViewer::float_index (Coord x, Coord y) {
Hit hit(x, y);
_page_patch->repick(0, hit);
if (hit.any()) {
if (hit.target(0) == _page) {
return hit.index(0);
} else {
return -1;
}
} else {
return -1;
}
}
void DocumentViewer::manipulate (Event& e) {
long index = float_index(e.pointer_x(), e.pointer_y());
if (index >= 0) {
ViewerFloatInfo& info = _float_info->item(index);
Coord x = e.pointer_x() - info._x;
Coord y = e.pointer_y() - info._y;
boolean synchronous = !e.shift_is_down();
do {
_document->adjust_float(
info._item,
e.pointer_x() - x, e.pointer_y() - y, info._page
);
if (synchronous) {
_document->notify();
}
e.read();
} while (e.type() != Event::up);
_document->notify();
}
}
void DocumentViewer::menu (Event& e) {
long index = float_index(e.pointer_x(), e.pointer_y());
boolean shift = e.shift_is_down();
if (index >= 0) {
ViewerFloatInfo& info = _float_info->item(index);
long new_page;
if (info._page == -1) {
new_page = shift ? -2 : _current_page;
} else {
new_page = -1;
}
_document->adjust_float(info._item, info._x, info._y, new_page);
_document->notify();
}
}
const char* DocumentViewer::current_page_label () const {
if (_current_page >= 0) {
return _page_info->item(_current_page)._label;
} else {
return "?";
}
}
void DocumentViewer::page_to (long page) {
long page_count = _pages->count()/2;
if (page_count != _page_info->count()) {
const Color* fg = World::current()->foreground();
char label[10];
while (_page_info->count() < page_count) {
ViewerPageInfo info;
sprintf(label, "%d", _page_info->count() + _starting_page + 1);
info._label = strcpy(new char[strlen(label) + 1], label);
info._telltale = new PageButton(
new HCenter(new Label(info._label, _icon_font, fg)), fg
);
info._telltale->ref();
_page_info->append(info);
}
while (_page_info->count() > page_count) {
long count = _page_info->count();
ViewerPageInfo& info = _page_info->item(count - 1);
if (info._telltale != nil) {
info._telltale->unref();
}
delete info._label;
_page_info->remove(count - 1);
}
LRBox* buttons = new LRBox();
buttons->append(nil);
buttons->append(
new Button(new Command(this, "page backward"), _prev_page)
);
buttons->append(
new Button(new Command(this, "page forward"), _next_page)
);
buttons->append(new HGlue(5, 0, 0));
Coord width = _document->document_metric("textwidth");
LRComposition* comp = new LRComposition(
new TBBox(), new SimpleCompositor(), nil, width, true
);
for (long i = 0; i < page_count; ++i) {
ViewerPageInfo& info = _page_info->item(i);
char command [20];
sprintf(command, "page %d", i);
comp->append(
new Button(new Command(this, command), info._telltale)
);
comp->append(
new Discretionary(0, nil, nil, nil, nil)
);
}
comp->repair();
buttons->append(comp);
buttons->append(new HGlue());
_footer_patch->redraw();
_footer_patch->body(buttons);
_body_patch->change(1);
_top->change(1);
_top->reallocate();
}
page = Math::max(0L, page);
page = Math::min(page_count-1, page);
if (page != _current_page) {
_current_page = page;
_pages->flip_to(_current_page * 2);
_view->view_page(_current_page * 2);
for (long i = 0; i < page_count; ++i) {
ViewerPageInfo& info = _page_info->item(i);
info._telltale->choose(i == _current_page);
}
_prev_page->enable(_current_page > 0);
_next_page->enable(_current_page < page_count - 1);
long float_count = _float_info->count();
for (long j = 0; j < float_count; ++j) {
ViewerFloatInfo& info = _float_info->item(j);
boolean showing = (
info._page == -2 && _current_page > 0
|| info._page == -1
|| info._page == _current_page
);
_page->show(j, showing);
}
_page_patch->reallocate();
_page_patch->redraw();
}
}
void DocumentViewer::page_to_view (long index) {
page_to(_view->page_containing(index) / 2);
}
void DocumentViewer::update () {
if (_reshaped) {
_view->reshaped();
_reshaped = false;
page_to(_current_page);
}
_view->view_page(_current_page * 2);
enable("save", _document->touched());
enable("revert", _document->touched());
}
Coord DocumentViewer::top_margin (
long page, Coord l, Coord b, Coord r, Coord t
) {
Coord top = t;
long count = _float_info->count();
for (long i = 0; i < count; ++i) {
ViewerFloatInfo& info = _float_info->item(i);
if (info._page == page/2 || info._page == -2 && page > 0) {
Allotment ax, ay;
_page->allotment(i, Dimension_X, ax);
_page->allotment(i, Dimension_Y, ay);
Coord fl = ax.begin();
Coord fr = ax.end();
Coord fb = ay.begin();
Coord ft = ay.end();
if (fr + info._repel_right > l && fl - info._repel_left < r) {
if ((fb + ft)/2 > (b + t)/2) {
top = Math::min(top, fb - info._repel_bottom);
}
}
}
}
return t - top;
}
Coord DocumentViewer::bottom_margin (
long page, Coord l, Coord b, Coord r, Coord t
) {
Coord bottom = b;
long count = _float_info->count();
for (long i = 0; i < count; ++i) {
ViewerFloatInfo& info = _float_info->item(i);
if (info._page == page/2 || info._page == -2 && page > 0) {
Allotment ax, ay;
_page->allotment(i, Dimension_X, ax);
_page->allotment(i, Dimension_Y, ay);
Coord fl = ax.begin();
Coord fr = ax.end();
Coord fb = ay.begin();
Coord ft = ay.end();
if (fr + info._repel_right > l && fl - info._repel_left < r) {
if ((fb + ft)/2 <= (b + t)/2) {
bottom = Math::max(bottom, ft + info._repel_top);
}
}
}
}
return bottom - b;
}