home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
i
/
iv26_w_3.zip
/
EXAMPLES
/
IDRAW
/
SLTEXT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-04
|
7KB
|
250 lines
/*
* Copyright (c) 1987, 1988, 1989 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.
*/
// $Header: sltext.c,v 1.13 89/10/09 14:49:47 linton Exp $
// implements class TextSelection.
#include "ipaint.h"
#include "istring.h"
#include "sltext.h"
#include <InterViews/Graphic/label.h>
#include <InterViews/textbuffer.h>
#include <iostream.h>
// Both ReadTextData and Filter use this big static buffer.
static const int SBUFSIZE = 1000;
static char sbuf[SBUFSIZE];
// TextSelection gets passed its graphic state and text.
TextSelection::TextSelection (const char* orig, int len, Graphic* gs) : (gs) {
Init(orig, len);
}
// TextSelection reads its graphic state and text from a file.
TextSelection::TextSelection (istream& from, State* state) : (nil) {
ReadTextGS(from, state);
int len;
const char* orig = ReadTextData(from, len);
Init(orig, len);
}
// Init copies the original text and appends Labels for each line of
// text to the TextSelection.
void TextSelection::Init (const char* orig, int len) {
int tbufsize = max(len, 1);
tbuf = new char[tbufsize];
memmove(tbuf, orig, len);
text = new TextBuffer(tbuf, len, tbufsize);
lineHt = 0;
int lines = text->Height();
for (int i = 0; i < lines; ++i) {
int bol = text->LineIndex(i);
int eol = text->EndOfLine(bol);
/* need this crock for now because Label(t, 0) is buggy */
if (eol - bol > 0) {
Append(new Label(text->Text(bol, eol), eol - bol));
} else {
Append(new Label(""));
}
}
ReadjustSpacing(GetFont());
}
// Free storage allocated for the text in the TextSelection.
TextSelection::~TextSelection () {
delete text;
delete tbuf;
}
// Copy returns a copy of the TextSelection.
Graphic* TextSelection::Copy () {
return new TextSelection(text->Text(), text->Length(), this);
}
// IsA returns true if the TextSelection is a TextSelection so Editor
// can identify TextSelections and edit them differently.
boolean TextSelection::IsA (ClassId id) {
return id == TEXTSELECTION || Picture::IsA(id);
}
// GetOriginal returns a pointer to the TextSelection's text.
const char* TextSelection::GetOriginal (int& len) {
len = text->Length();
return text->Text();
}
// ShapedBy returns true if the TextSelection intersects a box around
// the given point.
boolean TextSelection::ShapedBy (Coord px, Coord py, float maxdist) {
int slop = round(maxdist / 2);
BoxObj pickpoint(px - slop, py - slop, px + slop, py + slop);
return (LastGraphicIntersecting(pickpoint) != nil);
}
// draw readjusts the spacing between lines of text for a new font if
// necessary and sets fillbg false and pattern solid to draw the text
// like the printer will.
void TextSelection::draw (Canvas* c, Graphic* gs) {
ReadjustSpacing(gs->GetFont());
boolean fillbg = gs->BgFilled();
PPattern* pattern = gs->GetPattern();
gs->SetPattern(psolid);
gs->FillBg(false);
Selection::draw(c, gs);
gs->FillBg(fillbg);
gs->SetPattern(pattern);
}
// drawClipped readjusts the spacing between lines of text for a new
// font if necessary and sets fillbg false and pattern solid to draw
// the text like the printer will.
void TextSelection::drawClipped (Canvas* c, Coord l, Coord b, Coord r, Coord t,
Graphic* gs) {
ReadjustSpacing(gs->GetFont());
boolean fillbg = gs->BgFilled();
PPattern* pattern = gs->GetPattern();
gs->SetPattern(psolid);
gs->FillBg(false);
Selection::drawClipped(c, l, b, r, t, gs);
gs->FillBg(fillbg);
gs->SetPattern(pattern);
}
// ReadjustSpacing recalculates the spacing between lines of text.
void TextSelection::ReadjustSpacing (PFont* font) {
if (font != nil) {
int newHt = ((IFont*) font)->GetLineHt();
if (lineHt != newHt) {
lineHt = newHt;
int vertoffset = -lineHt + 1;
for (First(); !AtEnd(); Next()) {
Graphic* label = GetCurrent();
label->SetTransformer(nil);
label->Translate(0, vertoffset);
vertoffset -= lineHt;
}
}
}
}
// ReadTextData reads and returns the text contained in the PostScript
// representation of the TextSelection.
const char* TextSelection::ReadTextData (istream& from, int& len) {
TextBuffer stext(sbuf, 0, SBUFSIZE);
char nl = '\n';
if (versionnumber >= NONREDUNDANTVERSION) {
Skip(from);
int dot = 0;
char c = ' ';
while (from >> c && c != ']') {
while (c != '(' && from.get(c)) {
}
while (from.get(c) && c != ')') {
if (c == '\\') {
from.get(c);
}
stext.Insert(dot++, &c, 1);
}
stext.Insert(dot++, &nl, 1);
}
stext.Delete(--dot, 1); // buffer must not terminate in '\n'
} else {
int dot = 0;
while (from >> buf && strcmp(buf, startdata) == 0) {
char blank;
from.get(blank);
from.get(buf, BUFSIZE - 1);
int buflen = strlen(buf) + 1;
buf[buflen - 1] = '\n';
stext.Insert(dot, buf, buflen);
dot += buflen;
}
stext.Delete(--dot, 1); // buffer must not terminate in '\n'
}
len = stext.Length();
return stext.Text();
}
// WriteData writes the TextSelection's data and Postscript code to
// draw it.
void TextSelection::WriteData (ostream& to) {
to << "Begin " << startdata << " Text\n";
WriteTextGS(to);
to << startdata << "\n";
to << "[\n";
int lines = text->Height();
for (int i = 0; i < lines; ++i) {
int bol = text->LineIndex(i);
int eol = text->EndOfLine(bol);
const char* string = Filter(text->Text(bol, eol), eol - bol);
to << "(" << string << ")\n";
}
to << "] Text\n";
to << "End\n\n";
}
// Filter escapes embedded special characters that would cause syntax
// errors in a Postscript string.
const char* TextSelection::Filter (const char* string, int len) {
TextBuffer stext(sbuf, 0, SBUFSIZE);
char esc = '\\';
char nul = '\0';
int dot = 0;
for (int i = 0; i < len; i++) {
switch (*string) {
case '(':
case ')':
case '\\':
stext.Insert(dot++, &esc, 1);
// fall through
default:
stext.Insert(dot++, string++, 1);
}
}
stext.Insert(dot++, &nul, 1);
return stext.Text();
}