//FIXME: width and length for arrow QPolygonF QNEConnection::createArrowPoly(QPainterPath& p, QNEPort* conn) { float arrowStartPercentage; float arrowEndPercentage; if (conn->isOutput()) { arrowStartPercentage = p.percentAtLength(p.length() - conn->radius() - arrowSize); arrowEndPercentage = p.percentAtLength(p.length() - conn->radius()); } else { //assuming is start connector, should throw exception otherwise? arrowStartPercentage = p.percentAtLength(conn->radius() + arrowSize); arrowEndPercentage = p.percentAtLength(conn->radius()); } QPointF headStartP = p.pointAtPercent(arrowStartPercentage); QPointF headEndP = p.pointAtPercent(arrowEndPercentage); QLineF arrowMiddleLine(headStartP, headEndP); //QLineF normHead = arrowMiddleLine.normalVector(); arrowMiddleLine.unitVector(); QPointF normHead(arrowMiddleLine.dy(), -arrowMiddleLine.dx()); QPointF arrowP1 = headStartP + normHead * 0.4; QPointF arrowP2 = headStartP - normHead * 0.4; QPolygonF arrowHeadEnd; arrowHeadEnd << headEndP << arrowP1 << arrowP2 << headEndP /*<< headEndP*/; return arrowHeadEnd; }
QPolygonF mafNodeConnectionGraphicWidget::createArrowPoly(QPainterPath& p, mafNodeConnectorGraphicWidget* conn) { float arrowStartPercentage; float arrowEndPercentage; if (conn == mEndConnector) { arrowStartPercentage = p.percentAtLength(p.length() - conn->mRadius - arrowSize); arrowEndPercentage = p.percentAtLength(p.length() - conn->mRadius); } else { arrowStartPercentage = p.percentAtLength(conn->mRadius + arrowSize); arrowEndPercentage = p.percentAtLength(conn->mRadius); } QPointF headStartP = p.pointAtPercent(arrowStartPercentage); QPointF headEndP = p.pointAtPercent(arrowEndPercentage); QLineF arrowMiddleLine(headStartP, headEndP); //QLineF normHead = arrowMiddleLine.normalVector(); arrowMiddleLine.unitVector(); QPointF normHead(arrowMiddleLine.dy(), -arrowMiddleLine.dx()); QPointF arrowP1 = headStartP + normHead * 0.4; QPointF arrowP2 = headStartP - normHead * 0.4; QPolygonF arrowHeadEnd; arrowHeadEnd << headEndP << arrowP1 << arrowP2 /*<< headEndP*/; return arrowHeadEnd; }
void PrimitivePainter::drawLabel(QPainterPath* R, QPainter* thePainter, qreal PixelPerM, QString str, QString strBg) const { if (!DrawLabel) return; if (str.isEmpty() && strBg.isEmpty()) return; thePainter->save(); if (getLabelArea()) { QPointF C(R->boundingRect().center()); drawPointLabel(C, str, strBg, thePainter, PixelPerM); thePainter->restore(); return; } LineParameters lp = labelBoundary(); qreal WW = PixelPerM*lp.Proportional+lp.Fixed; if (WW < 10) return; //qreal WWR = qMax(PixelPerM*R->widthOf()*BackgroundScale+BackgroundOffset, PixelPerM*R->widthOf()*ForegroundScale+ForegroundOffset); QPainterPath textPath; QPainterPath tranformedRoadPath = *R; QFont font = getLabelFont(); if (!str.isEmpty()) { QRegion rg = thePainter->clipRegion(); font.setPixelSize(int(WW)); QFontMetrics metrics(font); if (font.pixelSize() >= 5 && tranformedRoadPath.length() > metrics.width(str)) { thePainter->setFont(font); int repeat = int((tranformedRoadPath.length() / ((metrics.width(str) * LABEL_PATH_DISTANCE))) - 0.5); int numSegment = repeat+1; qreal lenSegment = tranformedRoadPath.length() / numSegment; qreal startSegment = 0; QPainterPath textPath; do { QRegion rg = thePainter->clipRegion(); qreal curLen = startSegment + ((lenSegment - metrics.width(str)) / 2); int modIncrement = 1; qreal modAngle = 0; int modY = 0; if (cos(angToRad(tranformedRoadPath.angleAtPercent((startSegment+(lenSegment/2))/tranformedRoadPath.length()))) < 0) { modIncrement = -1; modAngle = 180.0; curLen += metrics.width(str); } for (int i = 0; i < str.length(); ++i) { qreal t = tranformedRoadPath.percentAtLength(curLen); QPointF pt = tranformedRoadPath.pointAtPercent(t); qreal angle = tranformedRoadPath.angleAtPercent(t); modY = (metrics.ascent()/2)-3; QMatrix m; m.translate(pt.x(), pt.y()); m.rotate(-angle+modAngle); QPainterPath charPath; charPath.addText(0, modY, font, str.mid(i, 1)); charPath = charPath * m; textPath.addPath(charPath); qreal incremenet = metrics.width(str[i]); curLen += (incremenet * modIncrement); } startSegment += lenSegment; } while (--repeat >= 0); if (getLabelHalo()) { thePainter->setPen(QPen(Qt::white, font.pixelSize()/6)); thePainter->drawPath(textPath); } thePainter->setPen(Qt::NoPen); thePainter->setBrush(LabelColor); thePainter->drawPath(textPath); thePainter->setClipRegion(rg); } } if (DrawLabelBackground && !strBg.isEmpty()) { QRegion rg = thePainter->clipRegion(); font.setPixelSize(int(WW)); QFontMetrics metrics(font); int repeat = int((tranformedRoadPath.length() / (metrics.width(strBg) * LABEL_STRAIGHT_DISTANCE)) - 0.5); int numSegment = repeat+1; qreal lenSegment = tranformedRoadPath.length() / numSegment; qreal startSegment = 0; do { int modX = 0; int modY = 0; qreal curLen = startSegment + (lenSegment / 2); qreal t = tranformedRoadPath.percentAtLength(curLen); QPointF pt = tranformedRoadPath.pointAtPercent(t); modX = - (metrics.width(strBg)/2); //modX = WW; modY = (metrics.ascent()/2); QPainterPath textPath, bgPath; textPath.addText(modX, modY, font, strBg); bgPath.addRect(textPath.boundingRect().adjusted(-BG_SPACING, -BG_SPACING, BG_SPACING, BG_SPACING)); bool rgContains = false; for (int i=0; i<rg.rects().size(); i++) { if (rg.rects()[i].contains(bgPath.boundingRect().toRect().translated(pt.toPoint()))) { rgContains = true; break; } } if (rgContains) { thePainter->translate(pt); thePainter->setPen(QPen(LabelColor, BG_PEN_SZ)); thePainter->setBrush(LabelBackgroundColor); thePainter->drawPath(bgPath); if (getLabelHalo()) { thePainter->setPen(QPen(Qt::white, font.pixelSize()/5)); thePainter->drawPath(textPath); } thePainter->setPen(Qt::NoPen); thePainter->setBrush(LabelColor); thePainter->drawPath(textPath); rg -= bgPath.boundingRect().toRect().translated(pt.toPoint()); } startSegment += lenSegment; } while (--repeat >= 0); thePainter->setClipRegion(rg); } thePainter->restore(); }
void PageItem_PathText::DrawObj_Item(ScPainter *p, QRectF cullingArea) { itemText.invalidateAll(); firstChar = 0; MaxChars = 0; int a; double chs; QString chstr, chstr2, chstr3; ScText *hl; double dx; FPoint point = FPoint(0, 0); FPoint tangent = FPoint(0, 0); uint seg = 0; double segLen = 0; QColor tmp; CurX = Extra; QString cachedStroke = ""; QString cachedFill = ""; double cachedFillShade = -1; double cachedStrokeShade = -1; QString actStroke = ""; QString actFill = ""; double actFillShade = -1; double actStrokeShade = -1; QColor cachedFillQ; QColor cachedStrokeQ; if (!m_Doc->layerOutline(LayerID)) { if (PoShow) { p->setupPolygon(&PoLine, false); if (NamedLStyle.isEmpty()) { if ((!patternStrokeVal.isEmpty()) && (m_Doc->docPatterns.contains(patternStrokeVal))) { if (patternStrokePath) { QPainterPath guidePath = PoLine.toQPainterPath(false); DrawStrokePattern(p, guidePath); } else { p->setPattern(&m_Doc->docPatterns[patternStrokeVal], patternStrokeScaleX, patternStrokeScaleY, patternStrokeOffsetX, patternStrokeOffsetY, patternStrokeRotation, patternStrokeSkewX, patternStrokeSkewY, patternStrokeMirrorX, patternStrokeMirrorY); p->setStrokeMode(ScPainter::Pattern); p->strokePath(); } } else if (GrTypeStroke > 0) { if ((!gradientStrokeVal.isEmpty()) && (!m_Doc->docGradients.contains(gradientStrokeVal))) gradientStrokeVal = ""; if (!(gradientStrokeVal.isEmpty()) && (m_Doc->docGradients.contains(gradientStrokeVal))) stroke_gradient = m_Doc->docGradients[gradientStrokeVal]; if (stroke_gradient.Stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient. { if (lineColor() != CommonStrings::None) { p->setBrush(strokeQColor); p->setStrokeMode(ScPainter::Solid); } else p->setStrokeMode(ScPainter::None); } else { p->setStrokeMode(ScPainter::Gradient); p->stroke_gradient = stroke_gradient; if (GrTypeStroke == 6) p->setGradient(VGradient::linear, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeStartX, GrStrokeStartY), GrStrokeScale, GrStrokeSkew); else p->setGradient(VGradient::radial, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeFocalX, GrStrokeFocalY), GrStrokeScale, GrStrokeSkew); } p->strokePath(); } else if (lineColor() != CommonStrings::None) { p->setStrokeMode(ScPainter::Solid); p->strokePath(); } } else { p->setStrokeMode(ScPainter::Solid); multiLine ml = m_Doc->MLineStyles[NamedLStyle]; QColor tmp; for (int it = ml.size()-1; it > -1; it--) { if (ml[it].Color != CommonStrings::None) // && (ml[it].Width != 0)) { SetQColor(&tmp, ml[it].Color, ml[it].Shade); p->setPen(tmp, ml[it].Width, static_cast<Qt::PenStyle>(ml[it].Dash), static_cast<Qt::PenCapStyle>(ml[it].LineEnd), static_cast<Qt::PenJoinStyle>(ml[it].LineJoin)); p->strokePath(); } } } } } double totalTextLen = 0.0; double totalCurveLen = 0.0; double extraOffset = 0.0; if (itemText.length() != 0) { CurX += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0; totalTextLen += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0; } segLen = PoLine.lenPathSeg(seg); for (a = firstChar; a < itemText.length(); ++a) { hl = itemText.item(a); chstr = hl->ch; if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT || chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK) continue; if (a < itemText.length()-1) chstr += itemText.text(a+1, 1); hl->glyph.yadvance = 0; layoutGlyphs(itemText.charStyle(a), chstr, hl->glyph); hl->glyph.shrink(); if (hl->ch == SpecialChars::OBJECT) totalTextLen += (hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth()) * hl->glyph.scaleH; else totalTextLen += hl->glyph.wide()+hl->fontSize() * hl->tracking() / 10000.0; } for (uint segs = 0; segs < PoLine.size()-3; segs += 4) { totalCurveLen += PoLine.lenPathSeg(segs); } if ((itemText.defaultStyle().alignment() != 0) && (totalCurveLen >= totalTextLen + Extra)) { if (itemText.defaultStyle().alignment() == 2) { CurX = totalCurveLen - totalTextLen; CurX -= Extra; } if (itemText.defaultStyle().alignment() == 1) CurX = (totalCurveLen - totalTextLen) / 2.0; if ((itemText.defaultStyle().alignment() == 3) || (itemText.defaultStyle().alignment() == 4)) extraOffset = (totalCurveLen - Extra - totalTextLen) / static_cast<double>(itemText.length()); } #ifndef NLS_PROTO QPainterPath guidePath = PoLine.toQPainterPath(false); QList<QPainterPath> pathList = decomposePath(guidePath); QPainterPath currPath = pathList[0]; int currPathIndex = 0; for (a = firstChar; a < itemText.length(); ++a) { CurY = 0; hl = itemText.item(a); chstr = hl->ch; if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT || chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK) continue; chs = hl->fontSize(); if (a < itemText.length()-1) chstr += itemText.text(a+1, 1); hl->glyph.yadvance = 0; layoutGlyphs(itemText.charStyle(a), chstr, hl->glyph); hl->glyph.shrink(); // HACK if (hl->ch == SpecialChars::OBJECT) dx = (hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth()) * hl->glyph.scaleH / 2.0; else dx = hl->glyph.wide() / 2.0; CurX += dx; double currPerc = currPath.percentAtLength(CurX); if (currPerc >= 0.9999999) { currPathIndex++; if (currPathIndex == pathList.count()) { MaxChars = a; break; } currPath = pathList[currPathIndex]; CurX = dx; currPerc = currPath.percentAtLength(CurX); } double currAngle = currPath.angleAtPercent(currPerc); #if QT_VERSION >= 0x040400 if (currAngle <= 180.0) currAngle *= -1.0; else currAngle = 360.0 - currAngle; #endif QPointF currPoint = currPath.pointAtPercent(currPerc); tangent = FPoint(cos(currAngle * M_PI / 180.0), sin(currAngle * M_PI / 180.0)); point = FPoint(currPoint.x(), currPoint.y()); hl->glyph.xoffset = 0; hl->PtransX = point.x(); hl->PtransY = point.y(); hl->PRot = currAngle * M_PI / 180.0; hl->PDx = dx; QTransform trafo = QTransform( 1, 0, 0, -1, -dx, 0 ); if (textPathFlipped) trafo *= QTransform(1, 0, 0, -1, 0, 0); if (textPathType == 0) trafo *= QTransform( tangent.x(), tangent.y(), tangent.y(), -tangent.x(), point.x(), point.y() ); // ID's Rainbow mode else if (textPathType == 1) trafo *= QTransform( 1, 0, 0, -1, point.x(), point.y() ); // ID's Stair Step mode else if (textPathType == 2) { double a = 1; if (tangent.x() < 0) a = -1; if (fabs(tangent.x()) > 0.1) trafo *= QTransform( a, (tangent.y() / tangent.x()) * a, 0, -1, point.x(), point.y() ); // ID's Skew mode else trafo *= QTransform( a, 4 * a, 0, -1, point.x(), point.y() ); } QTransform sca = p->worldMatrix(); trafo *= sca; p->save(); QTransform savWM = p->worldMatrix(); p->setWorldMatrix(trafo); if (!m_Doc->RePos) { actFill = itemText.charStyle(a).fillColor(); actFillShade = itemText.charStyle(a).fillShade(); if (actFill != CommonStrings::None) { p->setFillMode(ScPainter::Solid); if ((cachedFillShade != actFillShade) || (cachedFill != actFill)) { SetQColor(&tmp, actFill, actFillShade); p->setBrush(tmp); cachedFillQ = tmp; cachedFill = actFill; cachedFillShade = actFillShade; } else p->setBrush(cachedFillQ); } else p->setFillMode(ScPainter::None); actStroke = itemText.charStyle(a).strokeColor(); actStrokeShade = itemText.charStyle(a).strokeShade(); if (actStroke != CommonStrings::None) { if ((cachedStrokeShade != actStrokeShade) || (cachedStroke != actStroke)) { SetQColor(&tmp, actStroke, actStrokeShade); p->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); cachedStrokeQ = tmp; cachedStroke = actStroke; cachedStrokeShade = actStrokeShade; } else p->setPen(cachedStrokeQ, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); } p->translate(0.0, BaseOffs); if (hl->ch == SpecialChars::OBJECT) DrawObj_Embedded(p, cullingArea, itemText.charStyle(a), hl->embedded.getItem()); else drawGlyphs(p, itemText.charStyle(a), hl->glyph); } p->setWorldMatrix(savWM); p->restore(); MaxChars = a+1; CurX -= dx; if (hl->ch == SpecialChars::OBJECT) CurX += (hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth()) * hl->glyph.scaleH; else CurX += hl->glyph.wide()+hl->fontSize() * hl->tracking() / 10000.0 + extraOffset; } #endif }
void SCgAlphabet::paintPair(QPainter *painter, SCgPair *pair) { Q_ASSERT(pair != 0); QVector<QPointF> points = pair->points(); Q_ASSERT(points.size() > 1); static float arrowLength = 10.f; static float arrowWidth = LINE_FAT_WIDTH; if (pair->isOrient()) { static const QPointF arrowPoints[3] = {QPointF(-arrowWidth / 2.f, 0.f), QPointF(arrowWidth / 2.f, 0.f), QPointF(0.f, arrowLength)}; // draw arrow for orient pairs QLineF line(points[points.size() - 2], points.last()); double angle = ::atan2(line.dx(), line.dy()); painter->save(); painter->translate(line.p2()); painter->rotate(-angle * 180.f / M_PI); painter->translate(0.f, -arrowLength); painter->setBrush(QBrush(pair->color(), Qt::SolidPattern)); painter->setPen(Qt::NoPen); painter->drawConvexPolygon(arrowPoints, 3); painter->restore(); // correct last point points.last() -= QPointF((arrowLength) * ::sin(angle), (arrowLength) * ::cos(angle)); } // get type data SCgPosType posType = pair->posType(); SCgConstType constType = pair->constType(); SCgPermType permType = pair->permType(); painter->setBrush(Qt::NoBrush); QPen pen(pair->color()); pen.setCapStyle(Qt::FlatCap); pen.setJoinStyle(Qt::RoundJoin); // draw all cases if (pair->isAccessory()) { pen.setWidthF(LINE_THIN_WIDTH); QPen markPen = pen; if (constType == ConstUnknown && posType == PosUnknown) { painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); markPen.setWidthF(LINE_COM_ACCESS_MARK_WIDTH); markPen.setDashPattern(msCommonAccessoryDashPattern); painter->setPen(markPen); painter->drawPolyline(&(points[0]), points.size()); }else { if (permType == Permanent && constType == Var) pen.setDashPattern(msPermVarAccesDashPattern); if (permType == Temporary) { if (constType == Const) pen.setDashPattern(msTempConstAccesDashPattern); else pen.setDashPattern(msTempVarAccesDashPattern); } painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); // draw negative lines if (posType == Negative) { painter->setPen(markPen); QPainterPath path = pair->shapeNormal(); float length = path.length() - arrowLength - 3; int i = 0; qreal mult = 28.f; qreal offset = 22.f; qreal l = offset; while (l < length) { qreal perc = path.percentAtLength(l); painter->save(); painter->translate(path.pointAtPercent(perc)); painter->rotate(-path.angleAtPercent(perc)); painter->drawLine(0.f, -LINE_MARK_NEG_LENGTH, 0.f, LINE_MARK_NEG_LENGTH); painter->restore(); l = (++i) * mult + offset; } }else // draw fuzzy lines if (posType == Fuzzy) { painter->setPen(markPen); QPainterPath path = pair->shapeNormal(); float length = path.length() - arrowLength - 3; int i = 0; qreal mult = 28.f; qreal offset = 22.f; qreal l = offset; while (l < length) { qreal perc = path.percentAtLength(l); painter->save(); painter->translate(path.pointAtPercent(perc)); painter->rotate(-path.angleAtPercent(perc)); if (i % 2 == 0) painter->drawLine(0.f, -LINE_MARK_FUZ_LENGTH, 0.f, 0.f); else painter->drawLine(0.f, LINE_MARK_FUZ_LENGTH, 0.f, 0.f); painter->restore(); l = (++i) * mult + offset; } } } }else // draw binary pairs { pen.setWidthF(LINE_FAT_WIDTH); painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); if (constType == Var) { pen.setWidthF(LINE_FATIN_WIDTH); pen.setDashPattern(msPermVarNoAccesDashPattern); pen.setDashOffset(20); pen.setColor(QColor(255, 255, 255)); painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); }else { pen.setWidthF(LINE_FATIN_WIDTH); pen.setColor(Qt::white); painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); if (constType == ConstUnknown) { pen.setWidthF(LINE_THIN_WIDTH); pen.setDashPattern(msPermVarAccesDashPattern); pen.setColor(pair->color()); painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); } } } }
void PageItem_PathText::DrawObj_Item(ScPainter *p, QRectF cullingArea) { itemText.invalidateAll(); firstChar = 0; MaxChars = 0; int a; QString chstr, chstr2, chstr3; double dx; FPoint point = FPoint(0, 0); FPoint tangent = FPoint(0, 0); QColor tmp; CurX = m_textDistanceMargins.left(); QString cachedStroke = ""; QString cachedFill = ""; double cachedFillShade = -1; double cachedStrokeShade = -1; QString actStroke = ""; QString actFill = ""; double actFillShade = -1; double actStrokeShade = -1; QColor cachedFillQ; QColor cachedStrokeQ; if (!m_Doc->layerOutline(LayerID)) { if (PoShow) { p->setupPolygon(&PoLine, false); if (NamedLStyle.isEmpty()) { if ((!patternStrokeVal.isEmpty()) && (m_Doc->docPatterns.contains(patternStrokeVal))) { if (patternStrokePath) { QPainterPath guidePath = PoLine.toQPainterPath(false); DrawStrokePattern(p, guidePath); } else { p->setPattern(&m_Doc->docPatterns[patternStrokeVal], patternStrokeScaleX, patternStrokeScaleY, patternStrokeOffsetX, patternStrokeOffsetY, patternStrokeRotation, patternStrokeSkewX, patternStrokeSkewY, patternStrokeMirrorX, patternStrokeMirrorY); p->setStrokeMode(ScPainter::Pattern); p->strokePath(); } } else if (GrTypeStroke > 0) { if ((!gradientStrokeVal.isEmpty()) && (!m_Doc->docGradients.contains(gradientStrokeVal))) gradientStrokeVal = ""; if (!(gradientStrokeVal.isEmpty()) && (m_Doc->docGradients.contains(gradientStrokeVal))) stroke_gradient = m_Doc->docGradients[gradientStrokeVal]; if (stroke_gradient.Stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient. { if (lineColor() != CommonStrings::None) { p->setBrush(strokeQColor); p->setStrokeMode(ScPainter::Solid); } else p->setStrokeMode(ScPainter::None); } else { p->setStrokeMode(ScPainter::Gradient); p->stroke_gradient = stroke_gradient; if (GrTypeStroke == 6) p->setGradient(VGradient::linear, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeStartX, GrStrokeStartY), GrStrokeScale, GrStrokeSkew); else p->setGradient(VGradient::radial, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeFocalX, GrStrokeFocalY), GrStrokeScale, GrStrokeSkew); } p->strokePath(); } else if (lineColor() != CommonStrings::None) { p->setStrokeMode(ScPainter::Solid); p->strokePath(); } } else { p->setStrokeMode(ScPainter::Solid); multiLine ml = m_Doc->MLineStyles[NamedLStyle]; QColor tmp; for (int it = ml.size()-1; it > -1; it--) { if (ml[it].Color != CommonStrings::None) // && (ml[it].Width != 0)) { SetQColor(&tmp, ml[it].Color, ml[it].Shade); p->setPen(tmp, ml[it].Width, static_cast<Qt::PenStyle>(ml[it].Dash), static_cast<Qt::PenCapStyle>(ml[it].LineEnd), static_cast<Qt::PenJoinStyle>(ml[it].LineJoin)); p->strokePath(); } } } } } double totalTextLen = 0.0; double totalCurveLen = 0.0; double extraOffset = 0.0; if (itemText.length() != 0) { CurX += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0; totalTextLen += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0; } itemRenderText.clear(); itemRenderText.setDoc(m_Doc); itemRenderText.setDefaultStyle(itemText.defaultStyle()); for (a = firstChar; a < itemText.length(); ++a) { CharStyle nstyle = itemText.charStyle(a); ParagraphStyle pstyle = itemText.paragraphStyle(a); chstr = itemText.text(a, 1); if ((chstr[0] == SpecialChars::OBJECT) && (itemText.hasObject(a))) { int pot = itemRenderText.length(); itemRenderText.insertObject(pot, itemText.object(a)->inlineCharID); } else { if (!(chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK)) chstr = ExpandToken(a); for (int cc = 0; cc < chstr.count(); cc++) { int pot = itemRenderText.length(); itemRenderText.insertChars(pot, chstr.mid(cc, 1)); itemRenderText.applyStyle(pot, pstyle); itemRenderText.applyCharStyle(pot, 1, nstyle); } } chstr.clear(); } textLayout.setStory(&itemRenderText); int spaceCount = 0; double wordExtra = 0; for (a = firstChar; a < itemRenderText.length(); ++a) { GlyphLayout* glyphs = itemRenderText.getGlyphs(a); chstr = itemRenderText.text(a, 1); if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT || chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK) continue; if (chstr[0] == SpecialChars::BLANK) spaceCount++; if (a < itemRenderText.length()-1) chstr += itemRenderText.text(a+1, 1); glyphs->yadvance = 0; layoutGlyphs(itemRenderText.charStyle(a), chstr, itemRenderText.flags(a), *glyphs); glyphs->shrink(); if (itemRenderText.hasObject(a)) totalTextLen += (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs->scaleH; else totalTextLen += glyphs->wide()+itemRenderText.charStyle(a).fontSize() * itemRenderText.charStyle(a).tracking() / 10000.0; } for (int segs = 0; segs < PoLine.size()-3; segs += 4) { totalCurveLen += PoLine.lenPathSeg(segs); } if ((itemRenderText.paragraphStyle(0).alignment() != 0) && (totalCurveLen >= totalTextLen + m_textDistanceMargins.left())) { if (itemRenderText.paragraphStyle(0).alignment() == 2) { CurX = totalCurveLen - totalTextLen; CurX -= m_textDistanceMargins.left(); } if (itemRenderText.paragraphStyle(0).alignment() == 1) CurX = (totalCurveLen - totalTextLen) / 2.0; if (itemRenderText.paragraphStyle(0).alignment() == 3) { if (spaceCount != 0) { extraOffset = 0; wordExtra = (totalCurveLen - m_textDistanceMargins.left() - totalTextLen) / static_cast<double>(spaceCount); } else { extraOffset = (totalCurveLen - m_textDistanceMargins.left() - totalTextLen) / static_cast<double>(itemRenderText.length()); wordExtra = 0; } } if (itemRenderText.paragraphStyle(0).alignment() == 4) extraOffset = (totalCurveLen - m_textDistanceMargins.left() - totalTextLen) / static_cast<double>(itemRenderText.length()); } QPainterPath guidePath = PoLine.toQPainterPath(false); QList<QPainterPath> pathList = decomposePath(guidePath); QPainterPath currPath = pathList[0]; int currPathIndex = 0; for (a = firstChar; a < itemRenderText.length(); ++a) { CurY = 0; GlyphLayout* glyphs = itemRenderText.getGlyphs(a); PathData* pdata = & (textLayout.point(a)); chstr = itemRenderText.text(a,1); if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT || chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK) continue; if (a < itemRenderText.length()-1) chstr += itemRenderText.text(a+1, 1); glyphs->yadvance = 0; layoutGlyphs(itemRenderText.charStyle(a), chstr, itemRenderText.flags(a), *glyphs); glyphs->shrink(); // HACK if (itemRenderText.hasObject(a)) dx = (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs->scaleH / 2.0; else dx = glyphs->wide() / 2.0; CurX += dx; double currPerc = currPath.percentAtLength(CurX); if (currPerc >= 0.9999999) { currPathIndex++; if (currPathIndex == pathList.count()) { MaxChars = a; break; } currPath = pathList[currPathIndex]; CurX = dx; currPerc = currPath.percentAtLength(CurX); } double currAngle = currPath.angleAtPercent(currPerc); if (currAngle <= 180.0) currAngle *= -1.0; else currAngle = 360.0 - currAngle; QPointF currPoint = currPath.pointAtPercent(currPerc); tangent = FPoint(cos(currAngle * M_PI / 180.0), sin(currAngle * M_PI / 180.0)); point = FPoint(currPoint.x(), currPoint.y()); glyphs->xoffset = 0; pdata->PtransX = point.x(); pdata->PtransY = point.y(); pdata->PRot = currAngle * M_PI / 180.0; pdata->PDx = dx; QTransform trafo = QTransform( 1, 0, 0, -1, -dx, 0 ); if (textPathFlipped) trafo *= QTransform(1, 0, 0, -1, 0, 0); if (textPathType == 0) trafo *= QTransform( tangent.x(), tangent.y(), tangent.y(), -tangent.x(), point.x(), point.y() ); // ID's Rainbow mode else if (textPathType == 1) trafo *= QTransform( 1, 0, 0, -1, point.x(), point.y() ); // ID's Stair Step mode else if (textPathType == 2) { double a = 1; if (tangent.x() < 0) a = -1; if (fabs(tangent.x()) > 0.1) trafo *= QTransform( a, (tangent.y() / tangent.x()) * a, 0, -1, point.x(), point.y() ); // ID's Skew mode else trafo *= QTransform( a, 4 * a, 0, -1, point.x(), point.y() ); } QTransform sca = p->worldMatrix(); trafo *= sca; p->save(); QTransform savWM = p->worldMatrix(); p->setWorldMatrix(trafo); if (!m_Doc->RePos) { actFill = itemRenderText.charStyle(a).fillColor(); actFillShade = itemRenderText.charStyle(a).fillShade(); if (actFill != CommonStrings::None) { p->setFillMode(ScPainter::Solid); if ((cachedFillShade != actFillShade) || (cachedFill != actFill)) { SetQColor(&tmp, actFill, actFillShade); p->setBrush(tmp); cachedFillQ = tmp; cachedFill = actFill; cachedFillShade = actFillShade; } else p->setBrush(cachedFillQ); } else p->setFillMode(ScPainter::None); actStroke = itemRenderText.charStyle(a).strokeColor(); actStrokeShade = itemRenderText.charStyle(a).strokeShade(); if (actStroke != CommonStrings::None) { if ((cachedStrokeShade != actStrokeShade) || (cachedStroke != actStroke)) { SetQColor(&tmp, actStroke, actStrokeShade); p->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); cachedStrokeQ = tmp; cachedStroke = actStroke; cachedStrokeShade = actStrokeShade; } else p->setPen(cachedStrokeQ, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); } p->translate(0.0, BaseOffs); if (itemRenderText.hasObject(a)) DrawObj_Embedded(p, cullingArea, itemRenderText.charStyle(a), itemRenderText.object(a)); else drawGlyphs(p, itemRenderText.charStyle(a), itemRenderText.flags(a), *glyphs); } p->setWorldMatrix(savWM); p->restore(); MaxChars = a+1; CurX -= dx; if (itemRenderText.hasObject(a)) CurX += (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs->scaleH + extraOffset; else if (chstr[0] == SpecialChars::BLANK) CurX += glyphs->wide()+itemRenderText.charStyle(a).fontSize() * itemRenderText.charStyle(a).tracking() / 10000.0 + wordExtra + extraOffset; else CurX += glyphs->wide()+itemRenderText.charStyle(a).fontSize() *itemRenderText.charStyle(a).tracking() / 10000.0 + extraOffset; } }