コード例 #1
0
ファイル: sgi_symbolpin.cpp プロジェクト: LibrePCB/LibrePCB
void SGI_SymbolPin::updateCacheAndRepaint() noexcept {
  mShape = QPainterPath();
  mShape.setFillRule(Qt::WindingFill);
  mBoundingRect = QRectF();

  // rotation
  Angle absAngle = mLibPin.getRotation() + mPin.getSymbol().getRotation();
  absAngle.mapTo180deg();
  mMirrored = mPin.getSymbol().getMirrored();
  if (!mMirrored)
    mRotate180 = (absAngle <= -Angle::deg90() || absAngle > Angle::deg90());
  else
    mRotate180 = (absAngle < -Angle::deg90() || absAngle >= Angle::deg90());

  // circle
  mShape.addEllipse(-mRadiusPx, -mRadiusPx, 2 * mRadiusPx, 2 * mRadiusPx);
  mBoundingRect = mBoundingRect.united(mShape.boundingRect());

  // line
  QRectF lineRect =
      QRectF(QPointF(0, 0), Point(*mLibPin.getLength(), 0).toPxQPointF())
          .normalized();
  lineRect.adjust(-Length(79375).toPx(), -Length(79375).toPx(),
                  Length(79375).toPx(), Length(79375).toPx());
  mBoundingRect = mBoundingRect.united(lineRect).normalized();

  // text
  qreal x = mLibPin.getLength()->toPx() + 4;
  mStaticText.setText(mPin.getDisplayText());
  mStaticText.prepare(QTransform(), mFont);
  mTextOrigin.setX(mRotate180 ? -x - mStaticText.size().width() : x);
  mTextOrigin.setY(-mStaticText.size().height() / 2);
  mStaticText.prepare(QTransform()
                          .rotate(mRotate180 ? 180 : 0)
                          .translate(mTextOrigin.x(), mTextOrigin.y()),
                      mFont);
  if (mRotate180)
    mTextBoundingRect =
        QRectF(-mTextOrigin.x(), -mTextOrigin.y(), -mStaticText.size().width(),
               -mStaticText.size().height())
            .normalized();
  else
    mTextBoundingRect =
        QRectF(mTextOrigin.x(), -mTextOrigin.y() - mStaticText.size().height(),
               mStaticText.size().width(), mStaticText.size().height())
            .normalized();
  mBoundingRect = mBoundingRect.united(mTextBoundingRect).normalized();

  if (mMirrored)
    mTextOrigin.setX(mRotate180 ? x : -x - mStaticText.size().width());

  mIsVisibleJunction = mPin.isVisibleJunction();

  update();
}
コード例 #2
0
ファイル: sgi_symbol.cpp プロジェクト: 0xB767B/LibrePCB
void SGI_Symbol::updateCacheAndRepaint() noexcept
{
    prepareGeometryChange();

    mBoundingRect = QRectF();
    mShape = QPainterPath();
    mShape.setFillRule(Qt::WindingFill);

    // cross rect
    QRectF crossRect(-4, -4, 8, 8);
    mBoundingRect = mBoundingRect.united(crossRect);
    mShape.addRect(crossRect);

    // polygons
    for (int i = 0; i < mLibSymbol.getPolygonCount(); i++)
    {
        const Polygon* polygon = mLibSymbol.getPolygon(i);
        Q_ASSERT(polygon); if (!polygon) continue;

        QPainterPath polygonPath = polygon->toQPainterPathPx();
        qreal w = polygon->getWidth().toPx() / 2;
        mBoundingRect = mBoundingRect.united(polygonPath.boundingRect().adjusted(-w, -w, w, w));
        if (polygon->isGrabArea()) mShape = mShape.united(polygonPath);
    }

    // texts
    mCachedTextProperties.clear();
    for (int i = 0; i < mLibSymbol.getTextCount(); i++)
    {
        const Text* text = mLibSymbol.getText(i);
        Q_ASSERT(text); if (!text) continue;

        // create static text properties
        CachedTextProperties_t props;

        // get the text to display
        props.text = text->getText();
        mSymbol.replaceVariablesWithAttributes(props.text, true);

        // calculate font metrics
        props.fontPixelSize = qCeil(text->getHeight().toPx());
        mFont.setPixelSize(props.fontPixelSize);
        QFontMetricsF metrics(mFont);
        props.scaleFactor = text->getHeight().toPx() / metrics.height();
        props.textRect = metrics.boundingRect(QRectF(), text->getAlign().toQtAlign() |
                                              Qt::TextDontClip, props.text);
        QRectF scaledTextRect = QRectF(props.textRect.topLeft() * props.scaleFactor,
                                       props.textRect.bottomRight() * props.scaleFactor);

        // check rotation
        Angle absAngle = text->getRotation() + mSymbol.getRotation();
        absAngle.mapTo180deg();
        props.rotate180 = (absAngle <= -Angle::deg90() || absAngle > Angle::deg90());

        // calculate text position
        scaledTextRect.translate(text->getPosition().toPxQPointF());

        // text alignment
        if (props.rotate180)
            props.flags = text->getAlign().mirrored().toQtAlign() | Qt::TextWordWrap;
        else
            props.flags = text->getAlign().toQtAlign() | Qt::TextWordWrap;

        // calculate text bounding rect
        mBoundingRect = mBoundingRect.united(scaledTextRect);
        props.textRect = QRectF(scaledTextRect.topLeft() / props.scaleFactor,
                                scaledTextRect.bottomRight() / props.scaleFactor);
        if (props.rotate180)
        {
            props.textRect = QRectF(-props.textRect.x(), -props.textRect.y(),
                                    -props.textRect.width(), -props.textRect.height()).normalized();
        }

        // save properties
        mCachedTextProperties.insert(text, props);
    }

    update();
}
コード例 #3
0
ファイル: sgi_symbol.cpp プロジェクト: LibrePCB/LibrePCB
void SGI_Symbol::updateCacheAndRepaint() noexcept {
  prepareGeometryChange();

  mBoundingRect = QRectF();

  mShape = QPainterPath();
  mShape.setFillRule(Qt::WindingFill);

  // cross rect
  QRectF crossRect(-4, -4, 8, 8);
  mBoundingRect = mBoundingRect.united(crossRect);
  mShape.addRect(crossRect);

  // polygons
  for (const Polygon& polygon : mLibSymbol.getPolygons()) {
    // query polygon path and line width
    QPainterPath polygonPath = polygon.getPath().toQPainterPathPx();
    qreal        w           = polygon.getLineWidth()->toPx() / 2;

    // update bounding rectangle
    mBoundingRect =
        mBoundingRect.united(polygonPath.boundingRect().adjusted(-w, -w, w, w));

    // update shape
    if (polygon.isGrabArea()) {
      QPainterPathStroker stroker;
      stroker.setCapStyle(Qt::RoundCap);
      stroker.setJoinStyle(Qt::RoundJoin);
      stroker.setWidth(2 * w);
      // add polygon area
      mShape = mShape.united(polygonPath);
      // add stroke area
      mShape = mShape.united(stroker.createStroke(polygonPath));
    }
  }

  // circles
  for (const Circle& circle : mLibSymbol.getCircles()) {
    // get circle radius, including compensation for the stroke width
    qreal w = circle.getLineWidth()->toPx() / 2;
    qreal r = circle.getDiameter()->toPx() / 2 + w;

    // get the bounding rectangle for the circle
    QPointF center = circle.getCenter().toPxQPointF();
    QRectF  boundingRect =
        QRectF(QPointF(center.x() - r, center.y() - r), QSizeF(r * 2, r * 2));

    // update bounding rectangle
    mBoundingRect = mBoundingRect.united(boundingRect);

    // update shape
    if (circle.isGrabArea()) {
      mShape.addEllipse(circle.getCenter().toPxQPointF(), r, r);
    }
  }

  // texts
  mCachedTextProperties.clear();
  for (const Text& text : mLibSymbol.getTexts()) {
    // create static text properties
    CachedTextProperties_t props;

    // get the text to display
    props.text = AttributeSubstitutor::substitute(text.getText(), &mSymbol);

    // calculate font metrics
    props.fontPixelSize = qCeil(text.getHeight()->toPx());
    mFont.setPixelSize(props.fontPixelSize);
    QFontMetricsF metrics(mFont);
    props.scaleFactor = text.getHeight()->toPx() / metrics.height();
    props.textRect    = metrics.boundingRect(
        QRectF(), text.getAlign().toQtAlign() | Qt::TextDontClip, props.text);
    QRectF scaledTextRect =
        QRectF(props.textRect.topLeft() * props.scaleFactor,
               props.textRect.bottomRight() * props.scaleFactor);

    // check rotation
    Angle absAngle = text.getRotation() + mSymbol.getRotation();
    absAngle.mapTo180deg();
    props.mirrored = mSymbol.getMirrored();
    if (!props.mirrored)
      props.rotate180 =
          (absAngle <= -Angle::deg90() || absAngle > Angle::deg90());
    else
      props.rotate180 =
          (absAngle < -Angle::deg90() || absAngle >= Angle::deg90());

    // calculate text position
    scaledTextRect.translate(text.getPosition().toPxQPointF());

    // text alignment
    if (props.rotate180)
      props.flags = text.getAlign().mirrored().toQtAlign();
    else
      props.flags = text.getAlign().toQtAlign();

    // calculate text bounding rect
    mBoundingRect  = mBoundingRect.united(scaledTextRect);
    props.textRect = QRectF(scaledTextRect.topLeft() / props.scaleFactor,
                            scaledTextRect.bottomRight() / props.scaleFactor);
    if (props.rotate180) {
      props.textRect = QRectF(-props.textRect.x(), -props.textRect.y(),
                              -props.textRect.width(), -props.textRect.height())
                           .normalized();
    }

    // save properties
    mCachedTextProperties.insert(&text, props);
  }

  update();
}
コード例 #4
0
void FootprintPreviewGraphicsItem::updateCacheAndRepaint() noexcept
{
    prepareGeometryChange();

    mBoundingRect = QRectF();
    mShape = QPainterPath();
    mShape.setFillRule(Qt::WindingFill);

    // cross rect
    QRectF crossRect(-4, -4, 8, 8);
    mBoundingRect = mBoundingRect.united(crossRect);
    mShape.addRect(crossRect);

    // polygons
    for (int i = 0; i < mFootprint.getPolygonCount(); i++)
    {
        const Polygon* polygon = mFootprint.getPolygon(i);
        Q_ASSERT(polygon); if (!polygon) continue;

        QPainterPath polygonPath = polygon->toQPainterPathPx();
        qreal w = polygon->getLineWidth().toPx() / 2;
        mBoundingRect = mBoundingRect.united(polygonPath.boundingRect().adjusted(-w, -w, w, w));
        if (polygon->isGrabArea()) mShape = mShape.united(polygonPath);
    }

    // texts
    mCachedTextProperties.clear();
    for (int i = 0; i < mFootprint.getTextCount(); i++)
    {
        const Text* text = mFootprint.getText(i);
        Q_ASSERT(text); if (!text) continue;

        // create static text properties
        CachedTextProperties_t props;

        // get the text to display
        props.text = text->getText();
        replaceVariablesWithAttributes(props.text, false);

        // calculate font metrics
        mFont.setPointSizeF(text->getHeight().toPx());
        QFontMetricsF metrics(mFont);
        props.fontSize = text->getHeight().toPx()*0.8*text->getHeight().toPx()/metrics.height();
        mFont.setPointSizeF(props.fontSize);
        metrics = QFontMetricsF(mFont);
        props.textRect = metrics.boundingRect(QRectF(), text->getAlign().toQtAlign() |
                                              Qt::TextDontClip, props.text);

        // check rotation
        Angle absAngle = text->getRotation() + Angle::fromDeg(rotation());
        absAngle.mapTo180deg();
        props.rotate180 = (absAngle <= -Angle::deg90() || absAngle > Angle::deg90());

        // calculate text position
        qreal dx, dy;
        if (text->getAlign().getV() == VAlign::top())
            dy = text->getPosition().toPxQPointF().y()-props.textRect.top();
        else if (text->getAlign().getV() == VAlign::bottom())
            dy = text->getPosition().toPxQPointF().y()-props.textRect.bottom();
        else
            dy = text->getPosition().toPxQPointF().y()-(props.textRect.top()+props.textRect.bottom())/2;
        if (text->getAlign().getH() == HAlign::left())
            dx = text->getPosition().toPxQPointF().x()-props.textRect.left();
        else if (text->getAlign().getH() == HAlign::right())
            dx = text->getPosition().toPxQPointF().x()-props.textRect.right();
        else
            dx = text->getPosition().toPxQPointF().x()-(props.textRect.left()+props.textRect.right())/2;

        // text alignment
        if (props.rotate180)
        {
            props.align = 0;
            if (text->getAlign().getV() == VAlign::top()) props.align |= Qt::AlignBottom;
            if (text->getAlign().getV() == VAlign::center()) props.align |= Qt::AlignVCenter;
            if (text->getAlign().getV() == VAlign::bottom()) props.align |= Qt::AlignTop;
            if (text->getAlign().getH() == HAlign::left()) props.align |= Qt::AlignRight;
            if (text->getAlign().getH() == HAlign::center()) props.align |= Qt::AlignHCenter;
            if (text->getAlign().getH() == HAlign::right()) props.align |= Qt::AlignLeft;
        }
        else
            props.align = text->getAlign().toQtAlign();

        // calculate text bounding rect
        props.textRect = props.textRect.translated(dx, dy).normalized();
        mBoundingRect = mBoundingRect.united(props.textRect);
        if (props.rotate180)
        {
            props.textRect = QRectF(-props.textRect.x(), -props.textRect.y(),
                                    -props.textRect.width(), -props.textRect.height()).normalized();
        }

        // save properties
        mCachedTextProperties.insert(text, props);
    }

    update();
}