void Text::layout() { if (styled() && !_editMode) { SimpleText::layout(); } else { _doc->setDefaultFont(textStyle().font(spatium())); qreal w = -1.0; qreal x = 0.0; qreal y = 0.0; if (parent() && layoutToParentWidth()) { w = parent()->width(); if (parent()->type() == HBOX || parent()->type() == VBOX || parent()->type() == TBOX) { Box* box = static_cast<Box*>(parent()); x += box->leftMargin() * MScore::DPMM; y += box->topMargin() * MScore::DPMM; w = box->width() - ((box->leftMargin() + box->rightMargin()) * MScore::DPMM); } } QTextOption to = _doc->defaultTextOption(); to.setUseDesignMetrics(true); to.setWrapMode(w <= 0.0 ? QTextOption::NoWrap : QTextOption::WrapAtWordBoundaryOrAnywhere); _doc->setDefaultTextOption(to); if (w < 0.0) w = _doc->idealWidth(); _doc->setTextWidth(w); setbbox(QRectF(QPointF(0.0, 0.0), _doc->size())); if (hasFrame()) layoutFrame(); _doc->setModified(false); textStyle().layout(this); // process alignment #if 0 // TODO TEXT_STYLE_TEXTLINE if ((textStyle().align() & ALIGN_VCENTER) && (textStyle() == TEXT_STYLE_TEXTLINE)) { // special case: vertically centered text with TextLine needs to // take into account the line width TextLineSegment* tls = static_cast<TextLineSegment*>(parent()); TextLine* tl = tls->textLine(); if (tl) { qreal textlineLineWidth = point(tl->lineWidth()); rypos() -= textlineLineWidth * .5; } } #endif rxpos() += x; rypos() += y; } if (parent() && parent()->type() == SEGMENT) { Segment* s = static_cast<Segment*>(parent()); rypos() += s ? s->measure()->system()->staff(staffIdx())->y() : 0.0; } adjustReadPos(); }
void TextLineSegment::draw(QPainter* painter) const { TextLine* tl = textLine(); qreal _spatium = spatium(); qreal textlineLineWidth = tl->lineWidth().val() * _spatium; qreal textlineTextDistance = _spatium * .5; QPointF pp2(pos2()); QColor color; bool normalColor = false; if (selected() && !(score() && score()->printing())) color = MScore::selectColor[0]; else if (!visible()) color = Qt::gray; else { color = curColor(); normalColor = true; } qreal l = 0.0; int sym = subtype() == SEGMENT_MIDDLE ? tl->continueSymbol() : tl->beginSymbol(); if (_text) { SpannerSegmentType st = subtype(); if ( ((st == SEGMENT_SINGLE || st == SEGMENT_BEGIN) && (tl->beginTextPlace() == PLACE_LEFT)) || ((st == SEGMENT_MIDDLE || st == SEGMENT_END) && (tl->continueTextPlace() == PLACE_LEFT)) ) { QRectF bb(_text->bbox()); l = _text->pos().x() + bb.width() + textlineTextDistance; } painter->translate(_text->pos()); painter->setPen(normalColor ? _text->curColor() : color); _text->draw(painter); painter->translate(-_text->pos()); } else if (sym != -1) { const QRectF& bb = symbols[score()->symIdx()][sym].bbox(magS()); qreal h = bb.height() * .5; QPointF o = tl->beginSymbolOffset() * _spatium; painter->setPen(color); symbols[score()->symIdx()][sym].draw(painter, 1.0, QPointF(o.x(), h + o.y())); l = bb.width() + textlineTextDistance; } QPen pen(normalColor ? tl->lineColor() : color, textlineLineWidth); pen.setStyle(tl->lineStyle()); painter->setPen(pen); if (subtype() == SEGMENT_SINGLE || subtype() == SEGMENT_END) { if (tl->endSymbol() != -1) { int sym = tl->endSymbol(); const QRectF& bb = symbols[score()->symIdx()][sym].bbox(magS()); qreal h = bb.height() * .5; QPointF o = tl->endSymbolOffset() * _spatium; pp2.setX(pp2.x() - bb.width() + textlineTextDistance); symbols[score()->symIdx()][sym].draw(painter, 1.0, QPointF(pp2.x() + textlineTextDistance + o.x(), h + o.y())); } } QPointF pp1(l, 0.0); if (tl->beginHook() && tl->beginHookType() == HOOK_45) pp1.rx() += fabs(tl->beginHookHeight().val() * _spatium * .4); if (tl->endHook() && tl->endHookType() == HOOK_45) pp2.rx() -= fabs(tl->endHookHeight().val() * _spatium * .4); painter->drawLine(QLineF(pp1.x(), pp1.y(), pp2.x(), pp2.y())); if (tl->beginHook()) { qreal hh = tl->beginHookHeight().val() * _spatium; if (subtype() == SEGMENT_SINGLE || subtype() == SEGMENT_BEGIN) { if (tl->beginHookType() == HOOK_45) painter->drawLine(QLineF(pp1.x(), pp1.y(), pp1.x() - fabs(hh * .4), pp1.y() + hh)); else painter->drawLine(QLineF(pp1.x(), pp1.y(), pp1.x(), pp1.y() + hh)); } } if (tl->endHook()) { qreal hh = tl->endHookHeight().val() * _spatium; if (subtype() == SEGMENT_SINGLE || subtype() == SEGMENT_END) { if (tl->endHookType() == HOOK_45) painter->drawLine(QLineF(pp2.x(), pp2.y(), pp2.x() + fabs(hh * .4), pp2.y() + hh)); else painter->drawLine(QLineF(pp2.x(), pp2.y(), pp2.x(), pp2.y() + hh)); } } }
void Text::layout() { #if 0 QSizeF pageSize(-1.0, 1000000); setPos(0.0, 0.0); if (parent() && _layoutToParentWidth) { pageSize.setWidth(parent()->width()); if (parent()->type() == HBOX || parent()->type() == VBOX || parent()->type() == TBOX) { Box* box = static_cast<Box*>(parent()); rxpos() += box->leftMargin() * DPMM; rypos() += box->topMargin() * DPMM; // pageSize.setHeight(box->height() - (box->topMargin() + box->bottomMargin()) * DPMM); pageSize.setWidth(box->width() - (box->leftMargin() + box->rightMargin()) * DPMM); } } QTextOption to = _doc->defaultTextOption(); to.setUseDesignMetrics(true); to.setWrapMode(pageSize.width() <= 0.0 ? QTextOption::NoWrap : QTextOption::WrapAtWordBoundaryOrAnywhere); _doc->setDefaultTextOption(to); if (pageSize.width() <= 0.0) _doc->setTextWidth(_doc->idealWidth()); else _doc->setPageSize(pageSize); if (hasFrame()) { frame = QRectF(); for (QTextBlock tb = _doc->begin(); tb.isValid(); tb = tb.next()) { QTextLayout* tl = tb.layout(); int n = tl->lineCount(); for (int i = 0; i < n; ++i) // frame |= tl->lineAt(0).naturalTextRect().translated(tl->position()); frame |= tl->lineAt(0).rect().translated(tl->position()); } if (circle()) { if (frame.width() > frame.height()) { frame.setY(frame.y() + (frame.width() - frame.height()) * -.5); frame.setHeight(frame.width()); } else { frame.setX(frame.x() + (frame.height() - frame.width()) * -.5); frame.setWidth(frame.height()); } } qreal w = (paddingWidth() + frameWidth() * .5) * DPMM; frame.adjust(-w, -w, w, w); w = frameWidth() * DPMM; _bbox = frame.adjusted(-w, -w, w, w); } else { _bbox = QRectF(QPointF(0.0, 0.0), _doc->size()); //_doc->documentLayout()->frameBoundingRect(_doc->rootFrame()); } _doc->setModified(false); style().layout(this); // process alignment if ((style().align() & ALIGN_VCENTER) && (subtype() == TEXT_TEXTLINE)) { // special case: vertically centered text with TextLine needs to // take into account the line width TextLineSegment* tls = (TextLineSegment*)parent(); TextLine* tl = (TextLine*)(tls->line()); qreal textlineLineWidth = point(tl->lineWidth()); rypos() -= textlineLineWidth * .5; } if (parent() == 0) return; if (parent()->type() == SEGMENT) { Segment* s = static_cast<Segment*>(parent()); rypos() += s ? s->measure()->system()->staff(staffIdx())->y() : 0.0; } #endif Font f = style().font(spatium()); qreal asc, desc, leading; qreal w = textMetrics(f.family(), _text, f.size(), &asc, &desc, &leading); // printf("text(%s) asc %f desc %f leading %f w %f\n", qPrintable(_text), asc, desc, leading, w); _lineHeight = asc + desc; _lineSpacing = _lineHeight + leading; _baseLine = asc; setbbox(QRectF(0.0, -asc, w, _lineHeight)); #if 0 if (parent() && _layoutToParentWidth) { qreal wi = parent()->width(); qreal ph = parent()->height(); qreal x; qreal y = pos.y(); if (align() & ALIGN_HCENTER) x = (wi - w) * .5; else if (align() & ALIGN_RIGHT) x = wi - w; else x = 0.0; if (align() & ALIGN_VCENTER) y = (ph - asc) * .5; else if (align() & ALIGN_BOTTOM) y = ph - asc; else y = asc; setPos(x, y + asc); } #endif style().layout(this); // process alignment rypos() += asc; if (parent() && _layoutToParentWidth) { qreal wi = parent()->width(); if (align() & ALIGN_HCENTER) rxpos() = (wi - w) * .5; else if (align() & ALIGN_RIGHT) rxpos() = wi - w; } if ((style().align() & ALIGN_VCENTER) && (subtype() == TEXT_TEXTLINE)) { // special case: vertically centered text with TextLine needs to // take into account the line width TextLineSegment* tls = (TextLineSegment*)parent(); TextLine* tl = (TextLine*)(tls->line()); qreal textlineLineWidth = point(tl->lineWidth()); rypos() -= textlineLineWidth * .5; } if (parent() == 0) return; if (parent()->type() == SEGMENT) { Segment* s = static_cast<Segment*>(parent()); rypos() += s ? s->measure()->system()->staff(staffIdx())->y() : 0.0; } }