48 TGHtmlElement *TGHtml::TokenByIndex(
int N,
int )
53 if (N == 0)
return fPFirst;
55 if (N > fNToken / 2) {
57 for (p = fPLast, n = fNToken; p; p = p->fPPrev) {
58 if (p->fType != Html_Block) {
59 if (p->fElId == N)
break;
65 for (p = fPFirst; p; p = p->fPNext) {
66 if (p->fType != Html_Block) {
68 if (N == p->fElId)
break;
79 int TGHtml::TokenNumber(TGHtmlElement *p)
97 void TGHtml::MaxIndex(TGHtmlElement *p,
int *pIndex,
int isLast)
104 *pIndex = p->fCount - isLast;
108 if (p->fStyle.fFlags & STY_Preformatted) {
109 *pIndex = p->fCount - isLast;
132 void TGHtml::FindIndexInBlock(TGHtmlBlock *pBlock,
int x,
133 TGHtmlElement **ppToken,
int *pIndex)
141 font = GetFont(p->fStyle.fFont);
142 if (x <= pBlock->fLeft) {
146 }
else if (x >= pBlock->fRight) {
149 while (p && p->fType != Html_Block) {
154 if (p && p->fType == Html_Text) {
155 *pIndex = p->fCount - 1;
159 if (pBlock->fN == 0) {
163 n = font->MeasureChars(pBlock->fZ, pBlock->fN, x - pBlock->fLeft, 0, &len);
166 while (p && n >= 0) {
172 *pIndex = p->fCount - 1;
179 if (p->fStyle.fFlags & STY_Preformatted) {
183 *pIndex = p->fCount - 1;
197 if (p) p = p->fPNext;
209 void TGHtml::IndexToBlockIndex(SHtmlIndex_t sIndex,
210 TGHtmlBlock **ppBlock,
int *piIndex)
215 if (sIndex.fP == 0) {
220 p = sIndex.fP->fPPrev;
221 while (p && p->fType != Html_Block) {
227 if (p->fStyle.fFlags & STY_Preformatted) {
239 *ppBlock = (TGHtmlBlock *) p;
243 for (p = sIndex.fP; p && p->fType != Html_Block; p = p->fPNext) {}
244 *ppBlock = (TGHtmlBlock *) p;
251 int TGHtml::IndexMod(TGHtmlElement **pp,
int *ip,
char *cp)
254 int i, x, cnt, ccnt[2], cflag[2];
256 if (pp == 0 || !*pp)
return -1;
257 ccnt[0] = ccnt[1] = cflag[0] = cflag[1] = 0;
259 while (*cp && x < 2) {
262 while (i < 45 && isdigit(cp[i])) {
269 if (cnt < 0)
return -1;
272 case '+':
if (i == 1) ccnt[x] = 1;
else ccnt[x] = cnt;
break;
273 case '-':
if (i == 1) ccnt[x] = -1;
else ccnt[x] = -cnt;
break;
274 case '=': ccnt[x] = 0; cflag[x] = 1;
break;
281 for (i = 0; i < ccnt[0] && (*pp)->fPNext; ++i) {
283 while ((*pp)->fType == Html_Block && (*pp)->fPNext) {
287 }
else if (ccnt[0] < 0) {
288 for (i = 0; ccnt[0] < i && (*pp)->fPPrev; --i) {
291 while ((*pp)->fType == Html_Block && (*pp)->fPPrev) {
297 for (i = 0; i < ccnt[1]; ++i) (*ip)++;
298 }
else if (ccnt[1] < 0) {
299 for (i = 0; i > ccnt[1]; --i) (*ip)--;
342 int TGHtml::DecodeBaseIndex(
const char *baseIx,
343 TGHtmlElement **ppToken,
int *pIndex)
346 TGHtmlElement *p = 0;
348 TGHtmlBlock *pNearby;
351 char buf[200], *base = buf, *suffix, *ep;
353 strlcpy(buf, baseIx,
sizeof(buf));
355 while (isspace((
unsigned char)*base)) base++;
357 while (*ep && !isspace((
unsigned char)*ep)) ep++;
360 if ((suffix = strchr(base,
':'))) *suffix = 0;
363 case '1':
case '2':
case '3':
case '4':
case '5':
364 case '6':
case '7':
case '8':
case '9':
case '0':
366 n = sscanf(base,
"%d.%d", &x, &y);
368 p = *ppToken = TokenByIndex(x, 0);
373 for (i = 1; isdigit(base[i]); ++i) {}
376 }
else if (strcmp(&base[i],
".last") == 0) {
377 MaxIndex(p, pIndex, 1);
378 }
else if (strcmp(&base[i],
".end") == 0) {
379 MaxIndex(p, pIndex, 0);
382 if (n == 1 && p && p->IsMarkup() && base[i] ==
'.' &&
383 p->MarkupArg(fZBase + i + 1, 0)) {
393 if (strcmp(base,
"begin") == 0) {
394 p = *ppToken = fPFirst;
402 if (strcmp(base,
"end") == 0) {
403 p = *ppToken = fPLast;
404 MaxIndex(p, pIndex, 0);
411 if (strcmp(base,
"last") == 0) {
412 p = *ppToken = fPLast;
413 MaxIndex(p, pIndex, 1);
420 if (strcmp(base,
"sel.first") == 0) {
421 *ppToken = fSelBegin.fP;
422 *pIndex = fSelBegin.fI;
423 }
else if (strcmp(base,
"sel.last") == 0) {
424 *ppToken = fSelEnd.fP;
425 *pIndex = fSelEnd.fI;
426 }
else if (strcmp(base,
"sel.end") == 0) {
427 *ppToken = fSelEnd.fP;
428 *pIndex = fSelEnd.fI + 1;
435 if (strcmp(baseIx,
"insert") == 0) {
446 if (DomIdLookup(
"id", base + 1, ppToken)) rc = 1;
451 n = sscanf(base,
"@%d,%d", &x, &y);
461 for (pBlock = fFirstBlock; pBlock; pBlock = pBlock->fBNext) {
463 if (pBlock->fN == 0) {
464 switch (pBlock->fPNext->fType) {
480 if (pBlock->fTop <= y && pBlock->fBottom >= y) {
481 if (pBlock->fLeft > x) {
482 if (pBlock->fLeft - x < dist) {
483 dist = pBlock->fLeft - x;
486 }
else if (pBlock->fRight < x) {
487 if (x - pBlock->fRight < dist) {
488 dist = x - pBlock->fRight;
492 FindIndexInBlock(pBlock, x, ppToken, pIndex);
499 if (pBlock->fBottom < y) {
500 distY = y - pBlock->fBottom;
502 distY = pBlock->fTop - y;
504 if (pBlock->fLeft > x) {
505 distX = pBlock->fLeft - x;
506 }
else if (pBlock->fRight < x) {
507 distX = x - pBlock->fRight;
511 if (distX + 4*distY < dist) {
512 dist = distX + 4*distY;
520 FindIndexInBlock(pNearby, x, ppToken, pIndex);
529 if (suffix) IndexMod(ppToken, pIndex, suffix + 1);
538 int TGHtml::GetIndex(
const char *zIndex,
539 TGHtmlElement **ppToken,
int *pIndex)
541 return DecodeBaseIndex(zIndex, ppToken, pIndex);