📄 drawparams.cpp
字号:
int h = _fontHeight; bool rotate = dp->rotated(); int width = (rotate ? r.height() : r.width()) -4; int height = (rotate ? r.width() : r.height()); int lines = height / h; // stop if we have no space available if (lines<1) return false; // calculate free space in first line (<unused>) int pos = dp->position(f); if (pos == DrawParams::Default) { switch(f%4) { case 0: pos = DrawParams::TopLeft; break; case 1: pos = DrawParams::TopRight; break; case 2: pos = DrawParams::BottomRight; break; case 3: pos = DrawParams::BottomLeft; break; } } int unused = 0; bool isBottom = false; bool isCenter = false; bool isRight = false; int* used = 0; switch(pos) { case DrawParams::TopLeft: used = &_usedTopLeft; if (_usedTopLeft == 0) { if (_usedTopCenter) unused = (width - _usedTopCenter)/2; else unused = width - _usedTopRight; } break; case DrawParams::TopCenter: isCenter = true; used = &_usedTopCenter; if (_usedTopCenter == 0) { if (_usedTopLeft > _usedTopRight) unused = width - 2 * _usedTopLeft; else unused = width - 2 * _usedTopRight; } break; case DrawParams::TopRight: isRight = true; used = &_usedTopRight; if (_usedTopRight == 0) { if (_usedTopCenter) unused = (width - _usedTopCenter)/2; else unused = width - _usedTopLeft; } break; case DrawParams::BottomLeft: isBottom = true; used = &_usedBottomLeft; if (_usedBottomLeft == 0) { if (_usedBottomCenter) unused = (width - _usedBottomCenter)/2; else unused = width - _usedBottomRight; } break; case DrawParams::BottomCenter: isCenter = true; isBottom = true; used = &_usedBottomCenter; if (_usedBottomCenter == 0) { if (_usedBottomLeft > _usedBottomRight) unused = width - 2 * _usedBottomLeft; else unused = width - 2 * _usedBottomRight; } break; case DrawParams::BottomRight: isRight = true; isBottom = true; used = &_usedBottomRight; if (_usedBottomRight == 0) { if (_usedBottomCenter) unused = (width - _usedBottomCenter)/2; else unused = width - _usedBottomLeft; } break; } if (isBottom) { if ((_usedTopLeft >0) || (_usedTopCenter >0) || (_usedTopRight >0)) lines--; } else if (!isBottom) { if ((_usedBottomLeft >0) || (_usedBottomCenter >0) || (_usedBottomRight >0)) lines--; } if (lines<1) return false; int y = isBottom ? height - h : 0; if (unused < 0) unused = 0; if (unused == 0) { // no space available in last line at this position y = isBottom ? (y-h) : (y+h); lines--; if (lines<1) return false; // new line: reset used space if (isBottom) _usedBottomLeft = _usedBottomCenter = _usedBottomRight = 0; else _usedTopLeft = _usedTopCenter = _usedTopRight = 0; unused = width; } // stop as soon as possible when there's no space for "..." static int dotW = 0; if (!dotW) dotW = _fm->width("..."); if (width < dotW) return false; // get text and pixmap now, only if we need to, because it is possible // that they are calculated on demand (and this can take some time) QString name = dp->text(f); if (name.isEmpty()) return 0; QPixmap pix = dp->pixmap(f); // check if pixmap can be drawn int pixW = pix.width(); int pixH = pix.height(); int pixY = 0; bool pixDrawn = true; if (pixW>0) { pixW += 2; // X distance from pix if ((width < pixW + dotW) || (height < pixH)) { // don't draw pixW = 0; } else pixDrawn = false; } // width of text and pixmap to be drawn int w = pixW + _fm->width(name); if (0) kdDebug(90100) << " For '" << name << "': Unused " << unused << ", StrW " << w << ", Width " << width << endl; // if we have limited space at 1st line: // use it only if whole name does fit in last line... if ((unused < width) && (w > unused)) { y = isBottom ? (y-h) : (y+h); lines--; if (lines<1) return false; // new line: reset used space if (isBottom) _usedBottomLeft = _usedBottomCenter = _usedBottomRight = 0; else _usedTopLeft = _usedTopCenter = _usedTopRight = 0; } p->save(); p->setPen( (qGray(dp->backColor().rgb())>100) ? Qt::black : Qt::white); p->setFont(dp->font()); if (rotate) { //p->translate(r.x()+2, r.y()+r.height()); p->translate(r.x(), r.y()+r.height()-2); p->rotate(270); } else p->translate(r.x()+2, r.y()); // adjust available lines according to maxLines int max = dp->maxLines(f); if ((max > 0) && (lines>max)) lines = max; /* loop over name parts to break up string depending on available width. * every char category change is supposed a possible break, * with the exception Uppercase=>Lowercase. * It's good enough for numbers, Symbols... * * If the text is to be written at the bottom, we start with the * end of the string (so everything is reverted) */ QString remaining; int origLines = lines; while (lines>0) { if (w>width && lines>1) { int lastBreakPos = name.length(), lastWidth = w; int len = name.length(); QChar::Category caOld, ca; if (!isBottom) { // start with comparing categories of last 2 chars caOld = name[len-1].category(); while (len>2) { len--; ca = name[len-1].category(); if (ca != caOld) { // "Aa" has no break between... if (ca == QChar::Letter_Uppercase && caOld == QChar::Letter_Lowercase) { caOld = ca; continue; } caOld = ca; lastBreakPos = len; w = pixW + _fm->width(name, len); lastWidth = w; if (w <= width) break; } } w = lastWidth; remaining = name.mid(lastBreakPos); // remove space on break point if (name[lastBreakPos-1].category() == QChar::Separator_Space) name = name.left(lastBreakPos-1); else name = name.left(lastBreakPos); } else { // bottom int l = len; caOld = name[l-len].category(); while (len>2) { len--; ca = name[l-len].category(); if (ca != caOld) { // "Aa" has no break between... if (caOld == QChar::Letter_Uppercase && ca == QChar::Letter_Lowercase) { caOld = ca; continue; } caOld = ca; lastBreakPos = len; w = pixW + _fm->width(name.right(len)); lastWidth = w; if (w <= width) break; } } w = lastWidth; remaining = name.left(l-lastBreakPos); // remove space on break point if (name[l-lastBreakPos].category() == QChar::Separator_Space) name = name.right(lastBreakPos-1); else name = name.right(lastBreakPos); } } else remaining = QString::null; /* truncate and add ... if needed */ if (w>width) { int len = name.length(); w += dotW; while (len>2 && (w > width)) { len--; w = pixW + _fm->width(name, len) + dotW; } // stop drawing: we cannot draw 2 chars + "..." if (w>width) break; name = name.left(len) + "..."; } int x = 0; if (isCenter) x = (width - w)/2; else if (isRight) x = width - w; if (!pixDrawn) { pixY = y+(h-pixH)/2; // default: center vertically if (pixH > h) pixY = isBottom ? y-(pixH-h) : y; p->drawPixmap( x, pixY, pix); // for distance to next text pixY = isBottom ? (pixY - h - 2) : (pixY + pixH + 2); pixDrawn = true; } if (0) kdDebug(90100) << " Drawing '" << name << "' at " << x+pixW << "/" << y << endl; p->drawText( x+pixW, y, width - pixW, h, Qt::AlignLeft, name); y = isBottom ? (y-h) : (y+h); lines--; if (remaining.isEmpty()) break; name = remaining; w = pixW + _fm->width(name); } // make sure the pix stays visible if (pixDrawn && (pixY>0)) { if (isBottom && (pixY<y)) y = pixY; if (!isBottom && (pixY>y)) y = pixY; } if (origLines > lines) { // if only 1 line written, don't reset _used* vars if (lines - origLines >1) { if (isBottom) _usedBottomLeft = _usedBottomCenter = _usedBottomRight = 0; else _usedTopLeft = _usedTopCenter = _usedTopRight = 0; } // take back one line y = isBottom ? (y+h) : (y-h); if (used) *used = w; } // update free space if (!isBottom) { if (rotate) _rect.setRect(r.x()+y, r.y(), r.width()-y, r.height()); else _rect.setRect(r.x(), r.y()+y, r.width(), r.height()-y); } else { if (rotate) _rect.setRect(r.x(), r.y(), y+h, r.height()); else _rect.setRect(r.x(), r.y(), r.width(), y+h); } p->restore(); return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -