📄 utilobj.cpp
字号:
if(!(str_data[r1] = (char**)malloc(pw * sizeof(char*)))) break;
for(c1 = 0; c1 < pw; c1++) {
tx = src->GetTextPtr(r1, c1);
str_data[r1][c1] = tx && *tx && *tx[0] ? strdup(*tx) : 0L;
}
}
drc.right = pw-1; drc.bottom = ph-1;
}
}
StrData::~StrData()
{
int r, c, w, h;
w = drc.right-drc.left; h = drc.bottom-drc.top;
if(str_data) for (r = 0; r <= h; r++) {
if(str_data[r]) {
for(c = 0; c <= w; c++) if(str_data[r][c]) free(str_data[r][c]);
free(str_data[r]);
}
}
if(str_data) free(str_data);
}
bool
StrData::GetSize(int *uw, int *uh)
{
if(uw) *uw = pw; if(uh) *uh = ph;
return true;
}
void
StrData::RestoreData(DataObj *dest)
{
int r1, c1, r2, c2;
if(!dest || !str_data) return;
for (r1 = 0, r2 = drc.top; r2 <= drc.bottom; r1++, r2++) {
if(str_data[r1]) {
for(c1 = 0, c2 = drc.left; c2 <= drc.right; c1++, c2++)
dest->SetText(r2, c2, str_data[r1][c1]);
}
}
return;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// The notary class handles different types of supervision and indexing
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
notary::notary()
{
gObs = 0L;
goStack = 0L;
NextPopGO = NextPushGO = NextRegGO = 0L;
}
notary::~notary()
{
FreeStack();
}
unsigned long
notary::RegisterGO(GraphObj *go)
{
int i, j;
if(!go) return 0L;
if(!gObs) {
gObs = (GraphObj ***)calloc(0x2000L, sizeof(GraphObj **));
gObs[0] = (GraphObj **)calloc(0x2000L, sizeof(GraphObj *));
if(gObs && gObs[0]) {
gObs[0][0] = go;
return 1L;
}
return 0L;
}
i = (int)(NextRegGO >> 13);
j = (int)(NextRegGO & 0x1fff)+1;
if(j >=0x2000){
i++; j = 0;
}
if(gObs[i] && gObs[i][j] && gObs[i][j] == go) {
NextRegGO = ((i << 13) | j);
return (unsigned long)i*0x2000L+j+1;
}
if(gObs && gObs[0]) {
for(i = 0; i < 0x2000; i++) {
for(j = 0; j < 0x2000L; j++) {
if(gObs[i][j] == go) {
NextRegGO = ((i << 13) | j);
return (unsigned long)i*0x2000L+j+1;
}
if(!gObs[i][j]) {
gObs[i][j] = go;
NextRegGO = ((i << 13) | j);
return (unsigned long)i*0x2000L+j+1;
}
}
if(i < 0x1fffL && !gObs[i+1])
gObs[i+1] = (GraphObj **)calloc(0x2000L, sizeof(GraphObj *));
if(i < 0x1fffL && !gObs[i+1]) return 0L;
}
}
return 0L;
}
void
notary::AddRegGO(GraphObj *go)
{
int i, j;
if(!go) return;
if(!gObs) {
gObs = (GraphObj ***)calloc(0x2000L, sizeof(GraphObj **));
gObs[0] = (GraphObj **)calloc(0x2000L, sizeof(GraphObj *));
if(gObs && gObs[0]) {
gObs[0][0] = go;
return;
}
return;
}
i = (int)(NextRegGO >> 13);
j = (int)(NextRegGO & 0x1fff)+1;
if(j >=0x2000){
i++;
j = 0;
}
if(!gObs[i]) gObs[i] = (GraphObj **)calloc(0x2000L, sizeof(GraphObj *));
if(gObs[i] && !gObs[i][j]) {
gObs[i][j] = go;
NextRegGO = ((i << 13) | j);
}
else RegisterGO(go);
}
bool
notary::PushGO(unsigned long id, GraphObj *go)
{
int i, j;
NextPopGO = 0L;
if(!go) return true;
go->Id = id;
if(!goStack) {
goStack = (GraphObj ***)calloc(8192, sizeof(GraphObj **));
goStack[0] = (GraphObj **)calloc(8192, sizeof(GraphObj *));
if(goStack && goStack[0]) {
goStack[0][0] = go;
return true;
}
return false;
}
i = (int)(NextPushGO >> 13);
j = (int)(NextPushGO & 0x1fff)+1;
if(j >=0x2000){
i++;
j = 0;
}
if(!goStack || !goStack[0]) return false;
if(goStack[i] && !goStack[i][j]) {
goStack[i][j] = go;
NextPushGO = ((i << 13) | j);
return true;
}
for(i = 0; i < 0x2000; i++) {
for(j = 0; j < 0x2000; j++) {
if(!goStack[i][j]) {
goStack[i][j] = go;
NextPushGO = ((i << 13) | j);
return true;
}
}
if(i < 0x1fff && !goStack[i+1] && !(goStack[i+1] =
(GraphObj **)calloc(0x2000, sizeof(GraphObj *)))) return false;
}
return false;
}
GraphObj *
notary::PopGO(unsigned long id)
{
int i, j;
GraphObj *go;
NextPushGO = 0L;
if(!id || !goStack || !goStack[0]) return 0L;
i = (int)(NextPopGO >> 13);
j = (int)(NextPopGO & 0x1fff)+1;
if(j >=0x2000){
i++;
j = 0;
}
if(goStack[i] && goStack[i][j] && goStack[i][j]->Id == id) {
go = goStack[i][j];
goStack[i][j] = 0L;
go->Id = 0L;
NextPopGO = ((i << 13) | j);
return go;
}
for(i = 0; i < 0x2000; i++) {
for(j = 0; j < 0x2000; j++) {
if(goStack[i][j] && goStack[i][j]->Id == id) {
go = goStack[i][j];
goStack[i][j] = 0L;
go->Id = 0L;
NextPopGO = ((i << 13) | j);
return go;
}
}
if(i < 0x1fff && !goStack[i+1]) return 0L;
}
return 0L;
}
void
notary::FreeStack()
{
int i, j, k;
if(gObs) {
for(i = 0; gObs[i] && i <8192; i++) free(gObs[i]);
free(gObs);
gObs = 0L;
}
if(goStack) {
for(i = 0; goStack[i] && i <8192; i++){
for(j = k = 0; j < 8192; j++){
if(goStack[i][j]) {
goStack[i][j]->Id = 0L;
DeleteGO(goStack[i][j]);
k++;
}
}
free(goStack[i]);
}
free(goStack);
if(k){
sprintf(TmpTxt,"%d objects deleted\nby notary", k);
ErrorBox(TmpTxt);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Calculate continuous index to a range given by an ASCII string
// string examples include "a1:a12" or "a1:a4;a12:a24"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AccRange::AccRange(char *asc)
{
int i, j, l;
if(asc && *asc && (l=strlen(asc)) >1){
txt = (char *)malloc(l+2);
for(i = j = 0; i< (int)strlen(asc); i++)
if(asc[i] > 32) txt[j++] = asc[i];
txt[j] = 0;
}
else txt = 0L;
x1 = y1 = x2 = y2 = 0;
}
AccRange::~AccRange()
{
if(txt) free(txt);
}
int
AccRange::CountItems()
{
int RetVal;
RetVal = 0;
if(txt && Reset()) do {
RetVal += ((x2-x1+1)*(y2-y1+1));
} while((curridx < (int)strlen(txt)) && Parse(curridx));
return RetVal;
}
bool
AccRange::GetFirst(int *x, int *y)
{
if(txt && Reset()) {
if(x && y) {*x = x1; *y = y1;}
return true;
}
return false;
}
bool
AccRange::GetNext(int *x, int *y)
{
if(txt && x && y) {
if(cx <= x2) {*x = cx; *y = cy; cx++; return true;}
else {
cx = x1; cy++;
if(cy <= y2) return GetNext(x, y);
else if(txt[curridx]){
if(Parse(curridx)) return GetNext(x, y);
return false;
}
}
}
return false;
}
bool
AccRange::NextRow(int *y)
{
if(cy <= y2) {
*y = cy; cy++; return true;
}
else if(txt[curridx] && Parse(curridx)) return NextRow(y);
return false;
}
bool
AccRange::NextCol(int *x)
{
if(cx <= x2) {
*x = cx; cx++; return true;
}
else if(txt[curridx] && Parse(curridx)) return NextCol(x);
return false;
}
bool
AccRange::IsInRange(int x, int y)
{
if(txt && Reset()) do {
if(x >= x1 && x <= x2 && y >= y1 && y <= y2) return true;
} while((curridx < (int)strlen(txt)) && Parse(curridx));
return false;
}
bool
AccRange::BoundRec(RECT *rec)
{
if(txt && Reset()){
SetMinMaxRect(rec, x1, y1, x2, y2);
while((curridx < (int)strlen(txt)) && Parse(curridx)) {
UpdateMinMaxRect(rec, x1, y1); UpdateMinMaxRect(rec, x2, y2);
}
Reset();
return true;
}
return false;
}
bool
AccRange::Reset()
{
curridx = 0;
return Parse(curridx);
}
bool
AccRange::Parse(int start)
{
int i, l, step, *v;
i = start;
if(!txt) return false;
if(txt[i] == ';' || txt[i] == ',') i++;
if(!txt[i]) return false;
step = x1 = y1 = x2 = y2 = 0;
v = &x1;
for (l=strlen(txt)+1 ; i < l; i++) {
if(txt[i] == '$') i++;
switch(step) {
case 0:
case 2:
if((txt[i] >= 'a') && (txt[i] <= 'z')){
*v *= 26;
*v += (txt[i]-'a'+1);
}
else if((txt[i] >= 'A') && (txt[i] <= 'Z')){
*v *= 26;
*v += (txt[i]-'A'+1);
}
else if((txt[i] >= '0') && (txt[i] <= '9')){
v = step == 0 ? &y1 : &y2;
*v = txt[i]-'0';
step++;
}
else return false;
break;
case 1:
case 3:
if((txt[i] >= '0') && (txt[i] <= '9')){
*v *= 10;
*v += (txt[i]-'0');
}
else if((txt[i] >= 'a') && (txt[i] <= 'z') ||
(txt[i] >= 'A') && (txt[i] <= 'Z')){
if(step == 1) v = &x2;
else return false;
*v = txt[i] >='a' && txt[i] <= 'z' ?
txt[i]-'a' : txt[i]-'A';
step++;
}
else if(step == 1 && (txt[i] == ':')) {
v = &x2;
step++;
}
else if((txt[i] == ';') || (txt[i] == ',') || (txt[i] == 0)) {
if(step == 1) { //one single cell selected
x2 = x1; y2 = y1;
}
if(x2<x1) Swap(x1,x2); if(y2<y1) Swap(y1,y2);
if(y1 >=0) y1--; if(y2 >=0) y2--;
if(x1 >=0) x1--; if(x2 >=0) x2--;
curridx = i;
cx = x1; cy = y1;
return true;
}
break;
}
}
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Default data vault
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Default::Default()
{
dUnits = cUnits = 0;
strcpy(DecPoint, "."); strcpy(ColSep, ",");
Line_0.width = .4; Line_1.width = .04, Line_2.width = 0.016;
Line_0.patlength = 6.0; Line_1.patlength = 0.6; Line_2.patlength = 0.24;
Line_0.color = Line_1.color = Line_2.color = 0x00000000L; //black
Line_0.pattern = Line_1.pattern = Line_2.pattern = 0L; //solid line
FillLine_0.width = FillLine_1.width = FillLine_2.width = 0.0;
FillLine_0.patlength = 6.0; FillLine_1.patlength = 0.6; FillLine_2.patlength = 0.24;
Line_0.color = Line_1.color = Line_2.color = 0x00000000L; //black
Line_0.pattern = Line_1.pattern = Line_2.pattern = 0L; //solid line
Fill_0.type = Fill_1.type = Fill_2.type = FILL_NONE;
Fill_0.color = Fill_1.color = Fill_2.color = 0x00ffffffL; //white background
Fill_0.scale = Fill_1.scale = Fill_2.scale = 1.0; //size = 100%
Fill_0.hatch = &FillLine_0; Fill_1.hatch = &FillLine_1; Fill_2.hatch = &FillLine_2;
Fill_0.color2 = Fill_1.color2 = Fill_2.color2 = 0x00ffffffL; //white background
OutLine_0.width = .2; OutLine_1.width = .1; OutLine_2.width = 0.008;
OutLine_0.patlength = 6.0; OutLine_1.patlength = 0.6; OutLine_2.patlength = 0.24;
OutLine_0.color = OutLine_1.color = OutLine_2.color = 0x00000000L;
OutLine_0.pattern = OutLine_1.pattern = OutLine_2.pattern = 0L;
pl = pgl = 0L; pg = 0L; pg_fl = 0L; rrect_rad = 0L;
cdisp = 0L; min4log = 0.000001; ss_txt = 0.9;
axis_color = 0x0L;
svgAttr = svgScript = currPath = IniFile = 0L;
File1 = File2 = File3 = File4 = File5 = File6 = 0L;
}
Default::~Default()
{
if(svgAttr) free(svgAttr); if(svgScript) free(svgScript);
if(currPath) free(currPath); if(IniFile) free(IniFile);
svgAttr = svgScript = currPath = 0L;
if(pl) free(pl); if(pgl) free(pgl);
if(pg_fl) free(pg_fl); if(pg) free(pg);
if(rrect_rad) free(rrect_rad);
if(File1) free(File1); if(File2) free(File2);
if(File3) free(File3); if(File4) free(File4);
if(File5) free(File5); if(File6) free(File6);
}
void
Default::SetDisp(anyOutput *o)
{
if(o && o != cdisp) {
Undo.SetDisp(o);
cdisp = o;
}
}
double
Default::GetSize(int select)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -