-qreal ChatLine::layout(qreal tsw, qreal senderw, qreal textw) {
- tsWidth = tsw; senderWidth = senderw; textWidth = textw;
- if(textw <= 0) return minHeight;
- lineLayouts.clear(); LineLayout line;
- int h = 0;
- int offset = 0; int numWords = 0;
- line.y = 0;
- line.start = 0;
- line.height = minHeight; // first line needs room for ts and sender
- for(uint i = 0; i < (uint)words.count(); i++) {
- int lastpos = charPos[words[i].start + words[i].length]; // We use charPos[lastchar + 1], 'coz last char needs to fit
- if(lastpos - offset <= textw) {
- line.height = qMax(line.height, words[i].height);
- line.length = words[i].start + words[i].length - line.start;
- numWords++;
- } else {
- // we need to wrap!
- if(numWords > 0) {
- // ok, we had some words before, so store the layout and start a new line
- h += line.height;
- line.length = words[i-1].start + words[i-1].length - line.start;
- lineLayouts.append(line);
- line.y += line.height;
- line.start = words[i].start;
- line.height = words[i].height;
- offset = charPos[words[i].start];
- }
- numWords = 1;
- // check if the word fits into the current line
- if(lastpos - offset <= textw) {
- line.length = words[i].length;
- } else {
- // we need to break a word in the middle
- int border = (int)textw + offset; // save some additions
- line.start = words[i].start;
- line.length = 1;
- line.height = charHeights[line.start];
- int j = line.start + 1;
- for(int l = 1; l < words[i].length; j++, l++) {
- if(charPos[j+1] < border) {
- line.length++;
- line.height = qMax(line.height, charHeights[j]);
- continue;
- } else {
- h += line.height;
- lineLayouts.append(line);
- line.y += line.height;
- line.start = j;
- line.height = charHeights[j];
- line.length = 1;
- offset = charPos[j];
- border = (int)textw + offset;
- }
- }
- }
- }
- }
- h += line.height;
- if(numWords > 0) {
- lineLayouts.append(line);
- }
- hght = h;
- return hght;