|
|
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: P T
Length: 11127 (0x2b77)
Types: TextFile
Names: »PSFigItem.c«
└─⟦8648bda34⟧ Bits:30007244 EUUGD5_II: X11R5
└─⟦87c3ac0e0⟧ »./contrib-3/contrib-3.00«
└─⟦de8ce1454⟧
└─⟦this⟧ »contrib/lib/iv/src/bin/doc/PSFigItem.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.
*/
/*
* PSFigItem
*/
#include "PSFigItem.h"
#include "Document.h"
#include "PSFigView.h"
#include "PPM_Image.h"
#include "PGM_Image.h"
#include "IdrawImage.h"
#include "DocViewer.h"
#include "properties.h"
#include <InterViews/border.h>
#include <InterViews/box.h>
#include <InterViews/center.h>
#include <InterViews/fixedspan.h>
#include <InterViews/label.h>
#include <InterViews/margin.h>
#include <InterViews/target.h>
#include <InterViews/tformsetter.h>
#include <InterViews/transformer.h>
#include <InterViews/world.h>
#include <OS/math.h>
#include <strstream.h>
#include <stdio.h>
#include <string.h>
static void read_header (
FILE* file, char* creator,
float& left, float& bottom, float& right, float& top
) {
char line[1000];
boolean done = false;
boolean creator_known = false;
boolean bb_known = false;
int l, b, r, t;
while (!done && fgets(line, 1000, file) != NULL) {
if (sscanf(line, "%%%%Creator: %s", creator) == 1) {
creator_known = true;
} else if (
sscanf(line, "%%%%BoundingBox: %d %d %d %d", &l, &b, &r, &t) == 4)
{
bb_known = true;
} else if (strcmp(line, "%%EndProlog\n") == 0) {
done = true;
}
}
if (!creator_known) {
strcpy(creator, "idraw");
}
if (bb_known) {
left = float(l);
bottom = float(b);
right = float(r);
top = float(t);
} else {
left = 0;
bottom = 0;
right = 50;
top = 50;
}
}
class PSFigViewInfo {
public:
PSFigView* _view;
Glyph* _draft;
Glyph* _final;
};
#include "list.h"
declareList(PSFigViewInfo_List,PSFigViewInfo)
implementList(PSFigViewInfo_List,PSFigViewInfo)
PSFigItem::PSFigItem (
Document* document, Item* parent, long style, long source
) : Item(document, parent, style, source) {
_parameters = new char[256];
_filename = new char[100];
_creator = new char[100];
_width = 0;
_height = 0;
_hscale = 0;
_vscale = 0;
_hoffset = 0;
_voffset = 0;
_view = nil;
}
PSFigItem::~PSFigItem () {
delete _parameters;
delete _filename;
delete _creator;
if (_view != nil) {
while (_view->count() > 0) {
PSFigViewInfo& view = _view->item(0);
if (view._draft != nil) {
view._draft->unref();
}
if (view._final != nil) {
view._final->unref();
}
_view->remove(0);
}
delete _view;
}
}
void PSFigItem::read (istream& in) {
if (_document != nil) {
_document->read(in, this, _style, _source);
}
}
void PSFigItem::write (ostream& out) {
if (_document != nil) {
_document->write(out, this, _style, _source);
}
}
Glyph* PSFigItem::view (ItemView* parent, DocumentViewer* viewer) {
return viewer->view(parent, this);
}
void PSFigItem::parameters (const char* params) {
strcpy(_parameters, params);
change_graphic();
}
const char* PSFigItem::parameters () {
return _parameters;
}
void PSFigItem::change_graphic () {
_width = 0;
_height = 0;
_hscale = 0;
_vscale = 0;
_hoffset = 0;
_voffset = 0;
_rotate = 0;
istrstream scratch(_parameters);
char keyword[100];
char value[100];
while (scratch.getline(keyword, 100, '=')) {
if (strcmp(keyword, "figure") == 0) {
scratch.getline(_filename, 100, ',');
} else if (strcmp(keyword, "width") == 0) {
scratch.getline(value, 100, ',');
_width = _document->convert_metric(value);
} else if (strcmp(keyword, "height") == 0) {
scratch.getline(value, 100, ',');
_height = _document->convert_metric(value);
} else if (strcmp(keyword, "hoffset") == 0) {
scratch.getline(value, 100, ',');
_hoffset = _document->convert_metric(value);
} else if (strcmp(keyword, "voffset") == 0) {
scratch.getline(value, 100, ',');
_voffset = _document->convert_metric(value);
} else if (strcmp(keyword, "hscale") == 0) {
scratch.getline(value, 100, ',');
_hscale = _document->convert_metric(value);
} else if (strcmp(keyword, "vscale") == 0) {
scratch.getline(value, 100, ',');
_vscale = _document->convert_metric(value);
} else if (strcmp(keyword, "rotate") == 0) {
scratch.getline(value, 100, ',');
_rotate = _document->convert_metric(value);
}
if (scratch.peek() == ',') {
scratch.ignore(1);
}
};
FILE* file = fopen(_filename, "r");
if (file != nil) {
read_header(file, _creator, _left, _bottom, _right, _top);
float x1, y1, x2, y2, x3, y3, x4, y4;
Transformer t;
t.rotate(_rotate);
t.transform(_left, _bottom, x1, y1);
t.transform(_left, _top, x2, y2);
t.transform(_right, _top, x3, y3);
t.transform(_right, _bottom, x4, y4);
_left = Math::min(x1, x2, x3, x4);
_right = Math::max(x1, x2, x3, x4);
_bottom = Math::min(y1, y2, y3, y4);
_top = Math::max(y1, y2, y3, y4);
if (_width != 0) {
_hscale = _width / (_right - _left);
}
if (_height != 0) {
_vscale = _height / (_top - _bottom);
}
if (_hscale == 0 && _vscale != 0) {
_hscale = _vscale;
}
if (_vscale == 0 && _hscale != 0) {
_vscale = _hscale;
}
if (_hscale == 0) {
_hscale = 1.0;
}
if (_vscale == 0) {
_vscale = 1.0;
}
_width = (_right - _left) * _hscale;
_height = (_top - _bottom) * _vscale;
}
if (_view != nil) {
long count = _view->count();
for (long i = 0; i < count; ++i) {
PSFigViewInfo& info = _view->item(i);
if (info._draft != nil) {
info._draft->unref();
info._draft = nil;
}
if (info._final != nil) {
info._final->unref();
info._final = nil;
}
info._view->graphic_changed();
}
}
}
Glyph* PSFigItem::graphic (PSFigViewMode mode, PSFigView* view) {
World* w = World::current();
const Font* font = w->font();
const Color* fg = w->foreground();
const Color* bg = w->background();
boolean idraw_font_metrics = w->property_is_on(IDRAW_FONT_METRICS);
if (_view != nil) {
long count = _view->count();
for (long i = 0; i < count; ++i) {
PSFigViewInfo& info = _view->item(i);
if (info._view == view) {
Glyph* g = (mode == PSDraft) ? info._draft : info._final;
if (g == nil) {
if (mode == PSDraft) {
char params[256];
strcpy(params, _parameters);
Glyph* label = new TBBox(new Label(_creator, font, fg));
char* l = strtok(params, ",");
while (l != nil) {
label->append(new Label(l, font, fg));
l = strtok(nil, ",");
}
g = new Target(
new Border(
new Margin(
new Center(label),
0, fil, 0, 0, fil, 0, 0, fil, 0, 0, fil, 0
),
fg
),
TargetPrimitiveHit
);
} else {
FILE* file = fopen(_filename, "r");
Transformer t;
if (file != nil) {
if (strcmp(_creator, "pgmtops") == 0) {
g = new PGM_Image(file);
} else if (strcmp(_creator, "ppmtops") == 0) {
g = new PPM_Image(file);
} else if (strcmp(_creator, "idraw") == 0) {
g = new IdrawImage(file, idraw_font_metrics);
t.translate(- _left, - _bottom);
}
fclose(file);
}
t.rotate(_rotate);
t.scale(_hscale, _vscale);
g = new Center(new TransformSetter(g, t));
}
g = new FixedSpan(
new FixedSpan(
g, Dimension_X, _width
), Dimension_Y, _height
);
g->ref();
if (mode == PSDraft) {
info._draft = g;
} else {
info._final = g;
}
}
return g;
}
}
}
return nil;
}
void PSFigItem::attach (PSFigView* view) {
if (_view == nil) {
_view = new PSFigViewInfo_List();
}
PSFigViewInfo info;
info._view = view;
info._draft = nil;
info._final = nil;
_view->append(info);
}
void PSFigItem::detach (PSFigView* view) {
if (_view != nil) {
long count = _view->count();
for (long i = 0; i < count; ++i) {
PSFigViewInfo& info = _view->item(i);
if (info._view == view) {
if (info._draft != nil) {
info._draft->unref();
}
if (info._final != nil) {
info._final->unref();
}
_view->remove(i);
break;
}
}
}
}
void PSFigItem::notify () {
if (_view != nil) {
long count = _view->count();
for (long i = 0; i < count; ++i) {
PSFigViewInfo& info = _view->item(i);
info._view->update();
}
}
Item::notify();
}