void LayoutSVGInlineText::addMetricsFromRun( const TextRun& run, bool& lastCharacterWasWhiteSpace) { Vector<CharacterRange> charRanges = scaledFont().individualCharacterRanges(run); synthesizeGraphemeWidths(run, charRanges); const float cachedFontHeight = scaledFont().getFontMetrics().floatHeight() / m_scalingFactor; const bool preserveWhiteSpace = styleRef().whiteSpace() == PRE; const unsigned runLength = static_cast<unsigned>(run.length()); // TODO(pdr): Character-based iteration is ambiguous and error-prone. It // should be unified under a single concept. See: https://crbug.com/593570 unsigned characterIndex = 0; while (characterIndex < runLength) { bool currentCharacterIsWhiteSpace = run[characterIndex] == ' '; if (!preserveWhiteSpace && lastCharacterWasWhiteSpace && currentCharacterIsWhiteSpace) { m_metrics.append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics)); characterIndex++; continue; } unsigned length = isValidSurrogatePair(run, characterIndex) ? 2 : 1; float width = charRanges[characterIndex].width() / m_scalingFactor; m_metrics.append(SVGTextMetrics(length, width, cachedFontHeight)); lastCharacterWasWhiteSpace = currentCharacterIsWhiteSpace; characterIndex += length; } }
QFont TileWidget::letterFont() { // Sorry for the hardcoded constants :( :( if (m_information.isStartLocation && m_information.tileType != Quackle::Board::LetterTile) return scaledFont(0.7); else if (m_arrowDirection == GraphicalBoardFrame::NoArrow && m_information.tileType == Quackle::Board::BonusSquareTile) return scaledFont(.35); else { double initialScale = 0.7; if (m_information.tileType == Quackle::Board::LetterTile) { QString text = letterText(); if (text.length() > 1) { initialScale = 1.0 / text.length(); } } double scale = m_information.isBlank? initialScale * 5 / 7 : initialScale; QFont ret = scaledFont(scale); ret.setBold(true); return ret; } }
RefPtr<Font> Font::platformCreateScaledFont(const FontDescription& fontDescription, float scaleFactor) const { float scaledSize = scaleFactor * m_platformData.size(); if (isCustomFont()) { FontPlatformData scaledFont(m_platformData); scaledFont.setSize(scaledSize); return Font::create(scaledFont, true, false); } LOGFONT winfont; GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winfont); winfont.lfHeight = -lroundf(scaledSize * (m_platformData.useGDI() ? 1 : 32)); auto hfont = adoptGDIObject(::CreateFontIndirect(&winfont)); return Font::create(FontPlatformData(WTFMove(hfont), scaledSize, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.useGDI()), isCustomFont(), false); }
void QgsTextDiagram::renderDiagram( const QgsFeature& feature, QgsRenderContext& c, const QgsDiagramSettings& s, QPointF position ) { QPainter* p = c.painter(); if ( !p ) { return; } //convert from mm / map units to painter units QSizeF spu = sizePainterUnits( s.size, s, c ); double w = spu.width(); double h = spu.height(); double baseX = position.x(); double baseY = position.y() - h; QVector<QPointF> textPositions; //midpoints for text placement int nCategories = s.categoryAttributes.size(); for ( int i = 0; i < nCategories; ++i ) { if ( mOrientation == Horizontal ) { textPositions.push_back( QPointF( baseX + ( w / nCategories ) * i + w / nCategories / 2.0, baseY + h / 2.0 ) ); } else //vertical { textPositions.push_back( QPointF( baseX + w / 2.0, baseY + h / nCategories * i + w / nCategories / 2.0 ) ); } } mPen.setColor( s.penColor ); setPenWidth( mPen, s, c ); p->setPen( mPen ); mBrush.setColor( s.backgroundColor ); p->setBrush( mBrush ); //draw shapes and separator lines first if ( mShape == Circle ) { p->drawEllipse( baseX, baseY, w, h ); //draw separator lines QList<QPointF> intersect; //intersections between shape and separation lines QPointF center( baseX + w / 2.0, baseY + h / 2.0 ); double r1 = w / 2.0; double r2 = h / 2.0; for ( int i = 1; i < nCategories; ++i ) { if ( mOrientation == Horizontal ) { lineEllipseIntersection( QPointF( baseX + w / nCategories * i, baseY ), QPointF( baseX + w / nCategories * i, baseY + h ), center, r1, r2, intersect ); } else //vertical { lineEllipseIntersection( QPointF( baseX, baseY + h / nCategories * i ), QPointF( baseX + w, baseY + h / nCategories * i ), center, r1, r2, intersect ); } if ( intersect.size() > 1 ) { p->drawLine( intersect.at( 0 ), intersect.at( 1 ) ); } } } else if ( mShape == Rectangle ) { p->drawRect( QRectF( baseX, baseY, w, h ) ); for ( int i = 1; i < nCategories; ++i ) { if ( mOrientation == Horizontal ) { p->drawLine( QPointF( baseX + w / nCategories * i, baseY ), QPointF( baseX + w / nCategories * i, baseY + h ) ); } else { p->drawLine( QPointF( baseX, baseY + h / nCategories * i ), QPointF( baseX + w, baseY + h / nCategories * i ) ); } } } else //triangle { QPolygonF triangle; triangle << QPointF( baseX, baseY + h ) << QPointF( baseX + w, baseY + h ) << QPointF( baseX + w / 2.0, baseY ); p->drawPolygon( triangle ); QLineF triangleEdgeLeft( baseX + w / 2.0, baseY, baseX, baseY + h ); QLineF triangleEdgeRight( baseX + w, baseY + h, baseX + w / 2.0, baseY ); QPointF intersectionPoint1, intersectionPoint2; for ( int i = 1; i < nCategories; ++i ) { if ( mOrientation == Horizontal ) { QLineF verticalLine( baseX + w / nCategories * i, baseY + h, baseX + w / nCategories * i, baseY ); if ( baseX + w / nCategories * i < baseX + w / 2.0 ) { verticalLine.intersect( triangleEdgeLeft, &intersectionPoint1 ); } else { verticalLine.intersect( triangleEdgeRight, &intersectionPoint1 ); } p->drawLine( QPointF( baseX + w / nCategories * i, baseY + h ), intersectionPoint1 ); } else //vertical { QLineF horizontalLine( baseX, baseY + h / nCategories * i, baseX + w, baseY + h / nCategories * i ); horizontalLine.intersect( triangleEdgeLeft, &intersectionPoint1 ); horizontalLine.intersect( triangleEdgeRight, &intersectionPoint2 ); p->drawLine( intersectionPoint1, intersectionPoint2 ); } } } //draw text QFont sFont = scaledFont( s, c ); QFontMetricsF fontMetrics( sFont ); p->setFont( sFont ); QgsExpressionContext expressionContext = c.expressionContext(); expressionContext.setFeature( feature ); if ( feature.fields() ) expressionContext.setFields( *feature.fields() ); for ( int i = 0; i < textPositions.size(); ++i ) { QgsExpression* expression = getExpression( s.categoryAttributes.at( i ), expressionContext ); QString val = expression->evaluate( &expressionContext ).toString(); //find out dimesions double textWidth = fontMetrics.width( val ); double textHeight = fontMetrics.height(); mPen.setColor( s.categoryColors.at( i ) ); p->setPen( mPen ); QPointF position = textPositions.at( i ); // Calculate vertical placement double xOffset = 0; switch ( s.labelPlacementMethod ) { case QgsDiagramSettings::Height: xOffset = textHeight / 2.0; break; case QgsDiagramSettings::XHeight: xOffset = fontMetrics.xHeight(); break; } p->drawText( QPointF( position.x() - textWidth / 2.0, position.y() + xOffset ), val ); } }
void FretCanvas::paintEvent(QPaintEvent* ev) { double mag = 1.5; double _spatium = 20.0 * mag; double lw1 = _spatium * 0.08; int fretOffset = diagram->fretOffset(); double lw2 = fretOffset ? lw1 : _spatium * 0.2; double stringDist = _spatium * .7; double fretDist = _spatium * .8; int _strings = diagram->strings(); int _frets = diagram->frets(); int _barre = diagram->barre(); double w = (_strings - 1) * stringDist; double xo = (width() - w) * .5; double h = (_frets * fretDist) + fretDist * .5; double yo = (height() - h) * .5; QFont font("FreeSans"); int size = lrint(18.0 * mag); font.setPixelSize(size); QPainter p(this); p.setRenderHint(QPainter::Antialiasing, preferences.antialiasedDrawing); p.setRenderHint(QPainter::TextAntialiasing, true); p.translate(xo, yo); QPen pen(p.pen()); pen.setWidthF(lw2); pen.setCapStyle(Qt::FlatCap); p.setPen(pen); p.setBrush(pen.color()); double x2 = (_strings-1) * stringDist; p.drawLine(QLineF(-lw1 * .5, 0.0, x2+lw1*.5, 0.0)); pen.setWidthF(lw1); p.setPen(pen); double y2 = (_frets+1) * fretDist - fretDist*.5; for (int i = 0; i < _strings; ++i) { double x = stringDist * i; p.drawLine(QLineF(x, fretOffset ? -_spatium*.2 : 0.0, x, y2)); } for (int i = 1; i <= _frets; ++i) { double y = fretDist * i; p.drawLine(QLineF(0.0, y, x2, y)); } for (int i = 0; i < _strings; ++i) { p.setPen(Qt::NoPen); if (diagram->dot(i)) { double dotd = stringDist * .6 + lw1; int fret = diagram->dot(i) - 1; double x = stringDist * i - dotd * .5; double y = fretDist * fret + fretDist * .5 - dotd * .5; p.drawEllipse(QRectF(x, y, dotd, dotd)); } p.setPen(pen); if (diagram->marker(i)) { p.setFont(font); double x = stringDist * i; double y = -fretDist * .1; p.drawText(QRectF(x, y, 0.0, 0.0), Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip, QChar(diagram->marker(i))); } } if (_barre) { int string = -1; for (int i = 0; i < _strings; ++i) { if (diagram->dot(i) == _barre) { string = i; break; } } if (string != -1) { qreal x1 = stringDist * string; qreal x2 = stringDist * (_strings-1); qreal y = fretDist * (_barre-1) + fretDist * .5; pen.setWidthF(stringDist * .6 * .7); // dont use style barreLineWidth pen.setCapStyle(Qt::RoundCap); p.setPen(pen); p.drawLine(QLineF(x1, y, x2, y)); } } if ((cfret > 0) && (cfret <= _frets) && (cstring >= 0) && (cstring < _strings)) { double dotd; if (diagram->dot(cstring) != cfret) { p.setPen(Qt::NoPen); dotd = stringDist * .6 + lw1; } else { p.setPen(pen); dotd = stringDist * .6; } double x = stringDist * cstring - dotd * .5; double y = fretDist * (cfret-1) + fretDist * .5 - dotd * .5; p.setBrush(Qt::lightGray); p.drawEllipse(QRectF(x, y, dotd, dotd)); } if (fretOffset > 0) { qreal fretNumMag = 2.0; // TODO: get the value from StyleIdx::fretNumMag QFont scaledFont(font); scaledFont.setPixelSize(font.pixelSize() * fretNumMag); p.setFont(scaledFont); p.setPen(pen); // Todo: make dependant from StyleIdx::fretNumPos p.drawText(QRectF(-stringDist * .4, 0.0, 0.0, fretDist), Qt::AlignVCenter|Qt::AlignRight|Qt::TextDontClip, QString("%1").arg(fretOffset+1)); p.setFont(font); } QFrame::paintEvent(ev); }
void FretCanvas::paintEvent(QPaintEvent* ev) { double mag = 1.5; double _spatium = 20.0 * mag; double lw1 = _spatium * 0.08; int fretOffset = diagram->fretOffset(); double lw2 = (fretOffset || !diagram->showNut()) ? lw1 : _spatium * 0.2; double stringDist = _spatium * .7; double fretDist = _spatium * .8; int _strings = diagram->strings(); int _frets = diagram->frets(); double dotd = stringDist * .6 + lw1; double w = (_strings - 1) * stringDist; double xo = (width() - w) * .5; double h = (_frets * fretDist) + fretDist * .5; double yo = (height() - h) * .5; QFont font("FreeSans"); int size = lrint(18.0 * mag); font.setPixelSize(size); QPainter p(this); p.setRenderHint(QPainter::Antialiasing, preferences.getBool(PREF_UI_CANVAS_MISC_ANTIALIASEDDRAWING)); p.setRenderHint(QPainter::TextAntialiasing, true); p.translate(xo, yo); QPen pen(p.pen()); pen.setWidthF(lw2); pen.setCapStyle(Qt::FlatCap); p.setPen(pen); p.setBrush(pen.color()); double x2 = (_strings-1) * stringDist; p.drawLine(QLineF(-lw1 * .5, 0.0, x2 + lw1 * .5, 0.0)); pen.setWidthF(lw1); p.setPen(pen); double y2 = (_frets+1) * fretDist - fretDist*.5; QPen symPen(pen); symPen.setCapStyle(Qt::RoundCap); symPen.setWidthF(lw1 * 1.2); // Draw strings and frets for (int i = 0; i < _strings; ++i) { double x = stringDist * i; p.drawLine(QLineF(x, fretOffset ? -_spatium*.2 : 0.0, x, y2)); } for (int i = 1; i <= _frets; ++i) { double y = fretDist * i; p.drawLine(QLineF(0.0, y, x2, y)); } // Draw dots and markers for (int i = 0; i < _strings; ++i) { for (auto const& d : diagram->dot(i)) { if (d.exists()) { p.setPen(symPen); int fret = d.fret; double x = stringDist * i - dotd * .5; double y = fretDist * (fret - 1) + fretDist * .5 - dotd * .5; paintDotSymbol(p, symPen, x, y, dotd, d.dtype); } } p.setPen(pen); FretItem::Marker mark = diagram->marker(i); if (mark.exists()) { p.setFont(font); double x = stringDist * i; double y = -fretDist * .1; p.drawText(QRectF(x, y, 0.0, 0.0), Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip, FretItem::markerToChar(mark.mtype)); } } // Draw barres p.setPen(pen); for (auto const& i : diagram->barres()) { int fret = i.first; int startString = i.second.startString; int endString = i.second.endString; qreal x1 = stringDist * startString; qreal newX2 = endString == -1 ? x2 : stringDist * endString; qreal y = fretDist * (fret - 1) + fretDist * .5; pen.setWidthF(dotd * diagram->score()->styleD(Sid::barreLineWidth)); // don’t use style barreLineWidth - why not? pen.setCapStyle(Qt::RoundCap); p.setPen(pen); p.drawLine(QLineF(x1, y, newX2, y)); } // Draw 'hover' dot if ((cfret > 0) && (cfret <= _frets) && (cstring >= 0) && (cstring < _strings)) { FretItem::Dot cd = diagram->dot(cstring, cfret)[0]; std::vector<FretItem::Dot> otherDots = diagram->dot(cstring); FretDotType dtype; symPen.setColor(Qt::lightGray); if (cd.exists()) { dtype = cd.dtype; symPen.setColor(Qt::red); } else { dtype = _automaticDotType ? FretDotType::NORMAL : _currentDtype; } p.setPen(symPen); double x = stringDist * cstring - dotd * .5; double y = fretDist * (cfret-1) + fretDist * .5 - dotd * .5; p.setBrush(Qt::lightGray); paintDotSymbol(p, symPen, x, y, dotd, dtype); } if (fretOffset > 0) { qreal fretNumMag = 2.0; // TODO: get the value from Sid::fretNumMag QFont scaledFont(font); scaledFont.setPixelSize(font.pixelSize() * fretNumMag); p.setFont(scaledFont); p.setPen(pen); // Todo: make dependent from Sid::fretNumPos p.drawText(QRectF(-stringDist * .4, 0.0, 0.0, fretDist), Qt::AlignVCenter|Qt::AlignRight|Qt::TextDontClip, QString("%1").arg(fretOffset+1)); p.setFont(font); } QFrame::paintEvent(ev); }
QFont MarkWidget::letterFont() { return scaledFont(0.7); }
QFont TileWidget::miniFont() { return scaledFont(miniText().length() > 1? .275 : .325); }
QFont TileWidget::actualLetterFont() { return scaledFont(1); }