void XRefDefs::Matches(const char* s, XMatchResult* r, bool all) { const int32 n = fDefs.CountItems(); const char* end = s + strlen(s); MatchResult match; do { // match that starts at lowest position const char* start1 = end; XRefDef* def1 = NULL; Pattern* pat1 = NULL; int32 len1 = 0; for (int32 i = 0; i < n; i ++) { const char* start; int32 len; XRefDef* def = fDefs.ItemAt(i); Pattern* pat = def->Matches(s, &start, &len); if (pat && start <= start1) { if (start == start1 && len <= len1) continue; start1 = start; len1 = len; pat1 = pat; def1 = def; } } if (def1) { bool found = pat1->Matches(start1, &match); bool cont; ASSERT(found); (void)found; if (pat1->IsLink()) { cont = r->MatchLink(def1, &match); } else { cont = r->MatchDest(def1, &match); } if (!cont) break; // update for next iteration s = start1 + len1; } else { if (all) { do { s ++; } while (!BEGINS_CHAR(*s)); } else { break; } } } while (*s); }
bool LocalLink::MatchLink(XRefDef* def, MatchResult* result) { if (result->CountResults() >= 2) { BString label; result->GetString(1, &label); if (fDests->Find(def, label.String(), &fDestPage, &fDestBounds)) { result->Start(1); fContainsLink = true; fStartPos = result->Start(1) - fUtf8->String(); const char* p = result->Start(1) + result->Length(1); do { p --; } while (!BEGINS_CHAR(*p)); fEndPos = p - fUtf8->String(); return false; } else { REPORT(kWarning, fLinkPage, "Destination for link '%s' not found!", label.String()); } } return true; }
NetListItem::NetListItem(event_type type, const char* text, const BFont* font, uint32 level, bool expanded) : BListItem(level, expanded) { font_height height; font->GetHeight(&height); fFontAscent = height.ascent; fLineHeight = static_cast<int>(height.ascent + height.descent + height.leading); fText = static_cast<char*>(malloc(strlen(text) + 1)); strcpy(fText, text); fLineInfo.count = 1; fLineInfo.lines = (line_info*)malloc(sizeof(line_info)); fLineInfo.lines[0].numChars = 0; fLineInfo.lines[0].numWrapPoints = 0; fLineInfo.lines[0].byteNum = (int32*)malloc(sizeof(int32)); fLineInfo.lines[0].byteNum[0] = 0; for(int32 byteNum = 0; fText[byteNum] != 0; byteNum++) { if(BEGINS_CHAR(fText[byteNum])) { fLineInfo.lines[fLineInfo.count - 1].numChars++; if(WrapChar(fText[byteNum])) fLineInfo.lines[fLineInfo.count - 1].numWrapPoints++; if(fText[byteNum] == '\n') { // Don't count '\n' as a character fLineInfo.lines[fLineInfo.count - 1].numChars--; fLineInfo.count++; fLineInfo.lines = (line_info*)realloc(fLineInfo.lines, fLineInfo.count * sizeof(line_info)); fLineInfo.lines[fLineInfo.count - 1].numChars = 0; fLineInfo.lines[fLineInfo.count - 1].numWrapPoints = 0; fLineInfo.lines[fLineInfo.count - 1].byteNum = (int32*)malloc(sizeof(int32)); fLineInfo.lines[fLineInfo.count - 1].byteNum[0] = byteNum + 1; } } } // First pass finished, now know how many characters in each line for(int lineNum = 0; lineNum < fLineInfo.count; lineNum++) { fLineInfo.lines[lineNum].cumulativeWidth = (float*)malloc(fLineInfo.lines[lineNum].numChars * sizeof(float)); fLineInfo.lines[lineNum].byteNum = (int32*)realloc(fLineInfo.lines[lineNum].byteNum, fLineInfo.lines[lineNum].numChars * sizeof(int32)); fLineInfo.lines[lineNum].wrapPoints = (int32*)malloc(fLineInfo.lines[lineNum].numWrapPoints * sizeof(int32)); // Get escapements float* tmpEscapements = new float[fLineInfo.lines[lineNum].numChars]; font->GetEscapements(&fText[fLineInfo.lines[lineNum].byteNum[0]], fLineInfo.lines[lineNum].numChars, tmpEscapements); // Loop over that line to fill in details int charNum = -1; int wrapNum = -1; float cumulWidth = 0; for(int byteNum = fLineInfo.lines[lineNum].byteNum[0]; fText[byteNum] != '\n' && fText[byteNum] != 0; byteNum++) { if(BEGINS_CHAR(fText[byteNum])) { charNum++; fLineInfo.lines[lineNum].byteNum[charNum] = byteNum; cumulWidth += tmpEscapements[charNum]; fLineInfo.lines[lineNum].cumulativeWidth[charNum] = cumulWidth; if(WrapChar(fText[byteNum])) { wrapNum++; fLineInfo.lines[lineNum].wrapPoints[wrapNum] = charNum; } } } } fType = type; }
void NetListItem::CalcWordWrap(const float wrapWidth) { int currentLine = 0; fLineLen[currentLine] = 0; fStartChar[currentLine] = 0; for(int lineNum = 0; lineNum < fLineInfo.count; lineNum++) { // Set start character fStartChar[currentLine] = fLineInfo.lines[lineNum].byteNum[0]; int lineChar = 0; int nextWrap = 0; float cumWrapWidth = wrapWidth; if(fLineInfo.lines[lineNum].numChars > 0) { while(cumWrapWidth < fLineInfo.lines[lineNum].cumulativeWidth[fLineInfo.lines[lineNum].numChars - 1]) { bool midWordWrap = false; if(nextWrap < fLineInfo.lines[lineNum].numWrapPoints) { if(cumWrapWidth < fLineInfo.lines[lineNum].cumulativeWidth[fLineInfo.lines[lineNum].wrapPoints[nextWrap]]) midWordWrap = true; } else { midWordWrap = true; } if(midWordWrap) { int wrapChar = lineChar + 1; while(cumWrapWidth > fLineInfo.lines[lineNum].cumulativeWidth[wrapChar]) wrapChar++; if(wrapChar > lineChar + 1) wrapChar--; // Wrap after wrapChar fLineLen[currentLine] = fLineInfo.lines[lineNum].byteNum[wrapChar + 1] - fStartChar[currentLine]; lineChar = wrapChar + 1; cumWrapWidth = fLineInfo.lines[lineNum].cumulativeWidth[lineChar - 1] + wrapWidth; currentLine++; fLineLen[currentLine] = 0; fStartChar[currentLine] = fLineInfo.lines[lineNum].byteNum[lineChar]; } else { if(nextWrap + 1 < fLineInfo.lines[lineNum].numWrapPoints) { while(cumWrapWidth > fLineInfo.lines[lineNum].cumulativeWidth[fLineInfo.lines[lineNum].wrapPoints[nextWrap + 1]]) { nextWrap++; if(nextWrap + 1 >= fLineInfo.lines[lineNum].numWrapPoints) break; } } // Wrap after nextWrap fLineLen[currentLine] = fLineInfo.lines[lineNum].byteNum[fLineInfo.lines[lineNum].wrapPoints[nextWrap] + 1] - fStartChar[currentLine]; lineChar = fLineInfo.lines[lineNum].wrapPoints[nextWrap] + 1; cumWrapWidth = fLineInfo.lines[lineNum].cumulativeWidth[lineChar - 1] + wrapWidth; nextWrap++; currentLine++; fLineLen[currentLine] = 0; fStartChar[currentLine] = fLineInfo.lines[lineNum].byteNum[lineChar]; } } // Final wrapped line of this source line fLineLen[currentLine] = fLineInfo.lines[lineNum].byteNum[fLineInfo.lines[lineNum].numChars - 1] - fStartChar[currentLine] + 1; while(! BEGINS_CHAR(fText[fStartChar[currentLine] + fLineLen[currentLine]])) fLineLen[currentLine]++; currentLine++; } else { // No characters in this line fLineLen[currentLine] = 0; currentLine++; } } fLineLen[currentLine] = 0; fStartChar[currentLine] = -1; SetHeight(fLineHeight * currentLine + 4); }