void Render_SW_SDL::renderTextureCur(float x, float y, float w, float h, float ani_top, float ani_bottom, float ani_left, float ani_right) { if(!m_currentTexture) { renderRect(x, y, w, h, (unsigned char)(255.f*color_binded_texture[0]), (unsigned char)(255.f*color_binded_texture[1]), (unsigned char)(255.f*color_binded_texture[2]), (unsigned char)(255.f*color_binded_texture[3]) ); return; } SDL_Rect sourceRect = { (int)roundf((float)m_currentTextureRect.width()*ani_left), (int)roundf((float)m_currentTextureRect.height()*ani_top), abs((int)roundf((float)m_currentTextureRect.width()*ani_right)-(int)roundf((float)m_currentTextureRect.width()*ani_left)), abs((int)roundf((float)m_currentTextureRect.height()*ani_bottom)-(int)roundf((float)m_currentTextureRect.height()*ani_top)) }; SDL_Rect destRect = scaledRect(x, y, w, h); SDL_SetTextureColorMod( m_currentTexture, (unsigned char)(255.f*color_binded_texture[0]), (unsigned char)(255.f*color_binded_texture[1]), (unsigned char)(255.f*color_binded_texture[2])); SDL_SetTextureAlphaMod( m_currentTexture, (unsigned char)(255.f*color_binded_texture[3])); SDL_RenderCopy( m_gRenderer, m_currentTexture, &sourceRect, &destRect ); }
void Render_SW_SDL::renderTexture(PGE_Texture *texture, float x, float y, float w, float h, float ani_top, float ani_bottom, float ani_left, float ani_right) { if(!texture) return; setRenderTexture( texture->texture ); m_currentTextureRect.setRect( 0, 0, texture->w, texture->h ); if(!m_currentTexture) { renderRect(x, y, w, h, (unsigned char)(255.f*color_binded_texture[0]), (unsigned char)(255.f*color_binded_texture[1]), (unsigned char)(255.f*color_binded_texture[2]), (unsigned char)(255.f*color_binded_texture[3]) ); return; } SDL_Rect sourceRect = { (int)roundf((float)texture->w*ani_left), (int)roundf((float)texture->h*ani_top), (int)roundf((float)texture->w*ani_right)-(int)roundf((float)texture->w*ani_left), (int)roundf((float)texture->h*ani_bottom)-(int)roundf((float)texture->h*ani_top) }; SDL_Rect destRect = scaledRect(x, y, w, h); SDL_SetTextureColorMod( m_currentTexture, (unsigned char)(255.f*color_binded_texture[0]), (unsigned char)(255.f*color_binded_texture[1]), (unsigned char)(255.f*color_binded_texture[2])); SDL_SetTextureAlphaMod( m_currentTexture, (unsigned char)(255.f*color_binded_texture[3])); SDL_RenderCopy( m_gRenderer, m_currentTexture, &sourceRect, &destRect ); setUnbindTexture(); }
void QgsComposerUtils::drawText( QPainter *painter, const QRectF &rect, const QString &text, const QFont &font, const QColor &color, const Qt::AlignmentFlag halignment, const Qt::AlignmentFlag valignment, const int flags ) { if ( !painter ) { return; } //upscale using FONT_WORKAROUND_SCALE //ref: http://osgeo-org.1560.x6.nabble.com/Multi-line-labels-and-font-bug-td4157152.html QFont textFont = scaledFontPixelSize( font ); QRectF scaledRect( rect.x() * FONT_WORKAROUND_SCALE, rect.y() * FONT_WORKAROUND_SCALE, rect.width() * FONT_WORKAROUND_SCALE, rect.height() * FONT_WORKAROUND_SCALE ); painter->save(); painter->setFont( textFont ); if ( color.isValid() ) { painter->setPen( color ); } double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE; painter->scale( scaleFactor, scaleFactor ); painter->drawText( scaledRect, halignment | valignment | flags, text ); painter->restore(); }
void TileGrid::setNeedsDisplayInRect(const IntRect& rect) { if (m_tiles.isEmpty()) return; FloatRect scaledRect(rect); scaledRect.scale(m_scale); IntRect repaintRectInTileCoords(enclosingIntRect(scaledRect)); IntSize tileSize = m_controller.tileSize(); // For small invalidations, lookup the covered tiles. if (repaintRectInTileCoords.height() < 2 * tileSize.height() && repaintRectInTileCoords.width() < 2 * tileSize.width()) { TileIndex topLeft; TileIndex bottomRight; getTileIndexRangeForRect(repaintRectInTileCoords, topLeft, bottomRight); for (int y = topLeft.y(); y <= bottomRight.y(); ++y) { for (int x = topLeft.x(); x <= bottomRight.x(); ++x) { TileIndex tileIndex(x, y); TileMap::iterator it = m_tiles.find(tileIndex); if (it != m_tiles.end()) setTileNeedsDisplayInRect(tileIndex, it->value, repaintRectInTileCoords, m_primaryTileCoverageRect); } } return; } for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) setTileNeedsDisplayInRect(it->key, it->value, repaintRectInTileCoords, m_primaryTileCoverageRect); }
void QgsLayoutReportSectionLabel::paint( QPainter *painter, const QStyleOptionGraphicsItem *, QWidget * ) { if ( !mLayout || !mLayout->renderContext().isPreviewRender() ) { //don't draw label in outputs return; } if ( mLabel.isEmpty() ) return; QFont f; f.setPointSizeF( 8 ); QFontMetrics fm( f ); QSize s = fm.size( 0, mLabel ); double margin = fm.height() / 5.0; double scaleValue = scale() / painter->transform().m11(); painter->save(); painter->setRenderHint( QPainter::Antialiasing, true ); painter->scale( scaleValue, scaleValue ); QRectF r = rect(); QRectF scaledRect( r.left() / scaleValue, r.top() / scaleValue, r.width() / scaleValue, r.height() / scaleValue ); if ( scaledRect.width() < s.width() + 2 * margin || scaledRect.height() < s.height() + 2 * margin ) { // zoomed out too far to fully draw label inside item rect return; } QRectF textRect = QRectF( scaledRect.left() + margin, scaledRect.top() + margin, scaledRect.width() - 2 * margin, scaledRect.height() - 2 * margin ); QRectF boxRect = QRectF( scaledRect.left(), scaledRect.bottom() - ( s.height() + 2 * margin ), s.width() + 2 * margin, s.height() + 2 * margin ); QPainterPath p; p.moveTo( boxRect.bottomRight() ); p.lineTo( boxRect.right(), boxRect.top() + margin ); p.arcTo( boxRect.right() - 2 * margin, boxRect.top(), 2 * margin, 2 * margin, 0, 90 ); p.lineTo( boxRect.left() + margin, boxRect.top() ); p.arcTo( boxRect.left(), boxRect.top(), 2 * margin, 2 * margin, 90, 90 ); p.lineTo( boxRect.bottomLeft() ); p.lineTo( boxRect.bottomRight() ); painter->setPen( QColor( 150, 150, 150, 150 ) ); QLinearGradient g( 0, boxRect.top(), 0, boxRect.bottom() ); g.setColorAt( 0, QColor( 200, 200, 200, 150 ) ); g.setColorAt( 1, QColor( 150, 150, 150, 150 ) ); painter->setBrush( QBrush( g ) ); painter->drawPath( p ); painter->setPen( QPen( QColor( 0, 0, 0, 100 ) ) ); painter->setFont( f ); painter->drawText( textRect, Qt::AlignBottom, mLabel ); painter->restore(); }
void FrameView::addRect( const QRect& Rect, const QString& Description ) { QRect scaledRect(Rect.x() * Scale, Rect.y() * Scale, Rect.width() * Scale, Rect.height() * Scale); Scene->addRect(scaledRect, QPen(RectColor)); QGraphicsTextItem* label(Scene->addText(Description)); label->setPos(scaledRect.bottomLeft()); label->setDefaultTextColor(RectColor); qint32 color(RectColor); ++color > Qt::yellow ? RectColor = Qt::red : RectColor = static_cast<Qt::GlobalColor>(color); }
inline void FilterEffect::copyImageBytes(Uint8ClampedArray* source, Uint8ClampedArray* destination, const IntRect& rect) { IntRect scaledRect(rect); scaledRect.scale(m_filter.filterScale()); IntSize scaledPaintSize(m_absolutePaintRect.size()); scaledPaintSize.scale(m_filter.filterScale()); if (!source || !destination) return; // Initialize the destination to transparent black, if not entirely covered by the source. if (scaledRect.x() < 0 || scaledRect.y() < 0 || scaledRect.maxX() > scaledPaintSize.width() || scaledRect.maxY() > scaledPaintSize.height()) memset(destination->data(), 0, destination->length()); // Early return if the rect does not intersect with the source. if (scaledRect.maxX() <= 0 || scaledRect.maxY() <= 0 || scaledRect.x() >= scaledPaintSize.width() || scaledRect.y() >= scaledPaintSize.height()) return; int xOrigin = scaledRect.x(); int xDest = 0; if (xOrigin < 0) { xDest = -xOrigin; xOrigin = 0; } int xEnd = scaledRect.maxX(); if (xEnd > scaledPaintSize.width()) xEnd = scaledPaintSize.width(); int yOrigin = scaledRect.y(); int yDest = 0; if (yOrigin < 0) { yDest = -yOrigin; yOrigin = 0; } int yEnd = scaledRect.maxY(); if (yEnd > scaledPaintSize.height()) yEnd = scaledPaintSize.height(); int size = (xEnd - xOrigin) * 4; int destinationScanline = scaledRect.width() * 4; int sourceScanline = scaledPaintSize.width() * 4; unsigned char *destinationPixel = destination->data() + ((yDest * scaledRect.width()) + xDest) * 4; unsigned char *sourcePixel = source->data() + ((yOrigin * scaledPaintSize.width()) + xOrigin) * 4; while (yOrigin < yEnd) { memcpy(destinationPixel, sourcePixel, size); destinationPixel += destinationScanline; sourcePixel += sourceScanline; ++yOrigin; } }
void QgsDecorationGrid::drawText( QPainter* p, const QRectF& rect, const QString& text, const QFont& font, Qt::AlignmentFlag halignment, Qt::AlignmentFlag valignment ) const { QFont textFont = scaledFontPixelSize( font ); QRectF scaledRect( rect.x() * FONT_WORKAROUND_SCALE, rect.y() * FONT_WORKAROUND_SCALE, rect.width() * FONT_WORKAROUND_SCALE, rect.height() * FONT_WORKAROUND_SCALE ); p->save(); p->setFont( textFont ); double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE; p->scale( scaleFactor, scaleFactor ); p->drawText( scaledRect, halignment | valignment | Qt::TextWordWrap, text ); p->restore(); }
cv::Rect_<int> RoboyVision::convertFromScaledFrameToOriginalFrameCoordinates(cv::Rect_<int> rect) { int origX0 = originalFrame.size().width / 2; int origY0 = originalFrame.size().height / 2; int scaledX0 = scaledFrame.size().width / 2; int scaledY0 = scaledFrame.size().height / 2; int x0 = origX0 - (scaledX0 - rect.tl().x) / FRAME_SCALE; int y0 = origY0 - (scaledY0 - rect.tl().y) / FRAME_SCALE; int w = rect.size().width / FRAME_SCALE; int h = rect.size().height / FRAME_SCALE; cv::Rect_<int> scaledRect ( x0, y0, w, h ); return scaledRect; }
void Render_SW_SDL::renderRect(float x, float y, float w, float h, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha, bool filled) { SDL_Rect aRect = scaledRect(x, y, w, h); SDL_SetRenderDrawColor( m_gRenderer, (unsigned char)(255.f*red), (unsigned char)(255.f*green), (unsigned char)(255.f*blue), (unsigned char)(255.f*alpha) ); if(filled) { SDL_RenderFillRect( m_gRenderer, &aRect ); } else { SDL_RenderDrawRect( m_gRenderer, &aRect ); } }
bool TileGrid::tilesWouldChangeForCoverageRect(const FloatRect& coverageRect) const { if (coverageRect.isEmpty()) return false; FloatRect scaledRect(coverageRect); scaledRect.scale(m_scale); IntRect currentCoverageRectInTileCoords(enclosingIntRect(scaledRect)); TileIndex topLeft; TileIndex bottomRight; getTileIndexRangeForRect(currentCoverageRectInTileCoords, topLeft, bottomRight); IntRect tileCoverageRect = rectForTileIndex(topLeft); tileCoverageRect.unite(rectForTileIndex(bottomRight)); return tileCoverageRect != m_primaryTileCoverageRect; }
void TileGrid::dropTilesInRect(const IntRect& rect) { if (m_tiles.isEmpty()) return; FloatRect scaledRect(rect); scaledRect.scale(m_scale); IntRect dropRectInTileCoords(enclosingIntRect(scaledRect)); Vector<TileIndex> tilesToRemove; for (auto& index : m_tiles.keys()) { if (rectForTileIndex(index).intersects(dropRectInTileCoords)) tilesToRemove.append(index); } removeTiles(tilesToRemove); }
static IntRect centerRectVerticallyInParentInputElement(const RenderObject& renderObject, const IntRect& rect) { // Get the renderer of <input> element. Node* input = renderObject.node()->shadowHost(); if (!input) input = renderObject.node(); if (!input->renderer()->isBox()) return IntRect(); // If possible center the y-coordinate of the rect vertically in the parent input element. // We also add one pixel here to ensure that the y coordinate is rounded up for box heights // that are even, which looks in relation to the box text. IntRect inputContentBox = toRenderBox(input->renderer())->absoluteContentBox(); // Make sure the scaled decoration stays square and will fit in its parent's box. int iconSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), rect.height())); IntRect scaledRect(rect.x(), inputContentBox.y() + (inputContentBox.height() - iconSize + 1) / 2, iconSize, iconSize); return scaledRect; }
void detectAt(const int dx, const int dy, const Level& level, const ChannelStorage& storage, dvector& detections) const { float detectionScore = 0.f; const Octave& octave = *(level.octave); int stBegin = octave.index * octave.weaks, stEnd = stBegin + octave.weaks; for(int st = stBegin; st < stEnd; ++st) { const Weak& weak = weaks[st]; int nId = st * 3; // work with root node const Node& node = nodes[nId]; const Feature& feature = features[node.feature]; cv::Rect scaledRect(feature.rect); float threshold = level.rescale(scaledRect, node.threshold, (int)(feature.channel > 6)) * feature.rarea; float sum = storage.get(feature.channel, scaledRect); int next = (sum >= threshold)? 2 : 1; // leaves const Node& leaf = nodes[nId + next]; const Feature& fLeaf = features[leaf.feature]; scaledRect = fLeaf.rect; threshold = level.rescale(scaledRect, leaf.threshold, (int)(fLeaf.channel > 6)) * fLeaf.rarea; sum = storage.get(fLeaf.channel, scaledRect); int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0); float impact = leaves[(st * 4) + lShift]; detectionScore += impact; if (detectionScore <= weak.threshold) return; } if (detectionScore > 0) level.addDetection(dx, dy, detectionScore, detections); }
int16 GfxText32::getTextCount(const Common::String &text, const uint index, const Common::Rect &textRect, const bool doScaling) { const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; Common::Rect scaledRect(textRect); if (doScaling) { mulinc(scaledRect, Ratio(_xResolution, scriptWidth), Ratio(_yResolution, scriptHeight)); } Common::String oldText = _text; _text = text; uint charIndex = index; int16 maxWidth = scaledRect.width(); int16 lineCount = (scaledRect.height() - 2) / _font->getHeight(); while (lineCount--) { getLongest(&charIndex, maxWidth); } _text = oldText; return charIndex - index; }
void SVGImage::drawSVGToImageBuffer(ImageBuffer* buffer, const IntSize& size, float zoom, float scale, ShouldClearBuffer shouldClear) { // FIXME: This doesn't work correctly with animations. If an image contains animations, that say run for 2 seconds, // and we currently have one <img> that displays us. If we open another document referencing the same SVGImage it // will display the document at a time where animations already ran - even though it has its own ImageBuffer. // We currently don't implement SVGSVGElement::setCurrentTime, and can NOT go back in time, once animations started. // There's no way to fix this besides avoiding style/attribute mutations from SVGAnimationElement. ASSERT(buffer); ASSERT(!size.isEmpty()); if (!m_page) return; Frame* frame = m_page->mainFrame(); SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement(); if (!rootElement) return; RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()); if (!renderer) return; // Draw image at requested size. ImageObserver* observer = imageObserver(); ASSERT(observer); // Temporarily reset image observer, we don't want to receive any changeInRect() calls due to this relayout. setImageObserver(0); // Disable repainting; we don't want deferred repaints to schedule any timers due to this relayout. frame->view()->beginDisableRepaints(); renderer->setContainerSize(size); frame->view()->resize(this->size()); if (zoom != 1) frame->setPageZoomFactor(zoom); // Eventually clear image buffer. IntRect rect(IntPoint(), size); FloatRect scaledRect(rect); scaledRect.scale(scale); if (shouldClear == ClearImageBuffer) buffer->context()->clearRect(enclosingIntRect(scaledRect)); // Draw SVG on top of ImageBuffer. draw(buffer->context(), enclosingIntRect(scaledRect), rect, ColorSpaceDeviceRGB, CompositeSourceOver); // Reset container size & zoom to initial state. Otherwhise the size() of this // image would return whatever last size was set by drawSVGToImageBuffer(). if (zoom != 1) frame->setPageZoomFactor(1); renderer->setContainerSize(IntSize()); frame->view()->resize(this->size()); if (frame->view()->needsLayout()) frame->view()->layout(); setImageObserver(observer); frame->view()->endDisableRepaints(); }
void OverlayUser::updateLayout() { QPixmap pm; if (scene()) uiSize = iroundf(scene()->sceneRect().height() + 0.5); prepareGeometryChange(); for (int i=0;i<4;++i) qgpiName[i]->setPixmap(pm); qgpiAvatar->setPixmap(pm); qgpiChannel->setPixmap(pm); { QImageReader qir(QLatin1String("skin:muted_self.svg")); QSize sz = qir.size(); sz.scale(SCALESIZE(MutedDeafened), Qt::KeepAspectRatio); qir.setScaledSize(sz); qgpiMuted->setPixmap(QPixmap::fromImage(qir.read())); } { QImageReader qir(QLatin1String("skin:deafened_self.svg")); QSize sz = qir.size(); sz.scale(SCALESIZE(MutedDeafened), Qt::KeepAspectRatio); qir.setScaledSize(sz); qgpiDeafened->setPixmap(QPixmap::fromImage(qir.read())); } qgpiMuted->setPos(alignedPosition(scaledRect(os->qrfMutedDeafened, uiSize * os->fZoom), qgpiMuted->boundingRect(), os->qaMutedDeafened)); qgpiMuted->setZValue(1.0f); qgpiMuted->setOpacity(os->fMutedDeafened); qgpiDeafened->setPos(alignedPosition(scaledRect(os->qrfMutedDeafened, uiSize * os->fZoom), qgpiDeafened->boundingRect(), os->qaMutedDeafened)); qgpiDeafened->setZValue(1.0f); qgpiDeafened->setOpacity(os->fMutedDeafened); qgpiAvatar->setPos(0.0f, 0.0f); qgpiAvatar->setOpacity(os->fAvatar); for (int i=0;i<4;++i) { qgpiName[i]->setPos(0.0f, 0.0f); qgpiName[i]->setZValue(2.0f); qgpiName[i]->setOpacity(os->fUserName); } qgpiChannel->setPos(0.0f, 0.0f); qgpiChannel->setZValue(3.0f); qgpiChannel->setOpacity(os->fChannel); QRectF childrenBounds = os->qrfAvatar | os->qrfChannel | os->qrfMutedDeafened | os->qrfUserName; bool haspen = (os->qcBoxPen != os->qcBoxFill) && (! qFuzzyCompare(os->qcBoxPen.alphaF(), static_cast<qreal>(0.0f))); qreal pw = haspen ? qMax<qreal>(1.0f, os->fBoxPenWidth * uiSize * os->fZoom) : 0.0f; qreal pad = os->fBoxPad * uiSize * os->fZoom; QPainterPath pp; pp.addRoundedRect(childrenBounds.x() * uiSize * os->fZoom + -pw / 2.0f - pad, childrenBounds.y() * uiSize * os->fZoom + -pw / 2.0f - pad, childrenBounds.width() * uiSize * os->fZoom + pw + 2.0f * pad, childrenBounds.height() * uiSize * os->fZoom + pw + 2.0f * pad, 2.0f * pw, 2.0f * pw); qgpiBox->setPath(pp); qgpiBox->setPos(0.0f, 0.0f); qgpiBox->setZValue(-1.0f); qgpiBox->setPen(haspen ? QPen(os->qcBoxPen, pw) : Qt::NoPen); qgpiBox->setBrush(qFuzzyCompare(os->qcBoxFill.alphaF(), static_cast<qreal>(0.0f)) ? Qt::NoBrush : os->qcBoxFill); qgpiBox->setOpacity(1.0f); if (! cuUser) { switch (tsColor) { case Settings::Passive: qsName = Overlay::tr("Silent"); break; case Settings::Talking: qsName = Overlay::tr("Talking"); break; case Settings::Whispering: qsName = Overlay::tr("Whisper"); break; case Settings::Shouting: qsName = Overlay::tr("Shout"); break; } } }
void OverlayUser::updateUser() { if (os->bUserName && (qgpiName[0]->pixmap().isNull() || (cuUser && (qsName != cuUser->qsName)))) { if (cuUser) qsName = cuUser->qsName; OverlayTextLine tl(qsName, os->qfUserName); for (int i=0; i<4; ++i) { const QPixmap &pm = tl.createPixmap(SCALESIZE(UserName), os->qcUserName[i]); qgpiName[i]->setPixmap(pm); if (i == 0) qgpiName[0]->setPos(alignedPosition(scaledRect(os->qrfUserName, uiSize * os->fZoom), qgpiName[0]->boundingRect(), os->qaUserName)); else qgpiName[i]->setPos(qgpiName[0]->pos()); } } if (os->bChannel && (qgpiChannel->pixmap().isNull() || (cuUser && (qsChannelName != cuUser->cChannel->qsName)))) { if (cuUser) qsChannelName = cuUser->cChannel->qsName; const QPixmap &pm = OverlayTextLine(qsChannelName, os->qfChannel).createPixmap(SCALESIZE(Channel), os->qcChannel); qgpiChannel->setPixmap(pm); qgpiChannel->setPos(alignedPosition(scaledRect(os->qrfChannel, uiSize * os->fZoom), qgpiChannel->boundingRect(), os->qaChannel)); } if (os->bAvatar && (qgpiAvatar->pixmap().isNull() || (cuUser && (qbaAvatar != cuUser->qbaTextureHash)))) { if (cuUser) qbaAvatar = cuUser->qbaTextureHash; QImage img; if (! qbaAvatar.isNull() && cuUser->qbaTexture.isEmpty()) { g.o->requestTexture(cuUser); } else if (qbaAvatar.isNull()) { QImageReader qir(QLatin1String("skin:default_avatar.svg")); QSize sz = qir.size(); sz.scale(SCALESIZE(Avatar), Qt::KeepAspectRatio); qir.setScaledSize(sz); img = qir.read(); } else { QBuffer qb(& cuUser->qbaTexture); qb.open(QIODevice::ReadOnly); QImageReader qir(&qb, cuUser->qbaTextureFormat); QSize sz = qir.size(); sz.scale(SCALESIZE(Avatar), Qt::KeepAspectRatio); qir.setScaledSize(sz); img = qir.read(); } qgpiAvatar->setPixmap(QPixmap::fromImage(img)); qgpiAvatar->setPos(alignedPosition(scaledRect(os->qrfAvatar, uiSize * os->fZoom), qgpiAvatar->boundingRect(), os->qaAvatar)); } qgpiAvatar->setVisible(os->bAvatar); if (cuUser) { ClientUser *self = ClientUser::get(g.uiSession); if (os->bMutedDeafened) { if (cuUser->bDeaf || cuUser->bSelfDeaf) { qgpiMuted->hide(); qgpiDeafened->show(); } else if (cuUser->bMute || cuUser->bSelfMute || cuUser->bLocalMute || cuUser->bSuppress) { qgpiMuted->show(); qgpiDeafened->hide(); } else { qgpiMuted->hide(); qgpiDeafened->hide(); } } else { qgpiMuted->hide(); qgpiDeafened->hide(); } bool samechannel = self && (self->cChannel == cuUser->cChannel); qgpiChannel->setVisible(os->bChannel && ! samechannel); tsColor = cuUser->tsState; } else { qgpiChannel->setVisible(os->bChannel && (tsColor != Settings::Passive) && (tsColor != Settings::Talking)); qgpiMuted->setVisible(os->bChannel); qgpiDeafened->hide(); } if (os->bUserName) for (int i=0;i<4;++i) qgpiName[i]->setVisible(i == tsColor); else for (int i=0;i<4;++i) qgpiName[i]->setVisible(false); qgpiBox->setVisible(os->bBox); setOpacity(os->fUser[tsColor]); }
IntRect TileGrid::ensureTilesForRect(const FloatRect& rect, CoverageType newTileType) { if (m_controller.unparentsOffscreenTiles() && !m_controller.isInWindow()) return IntRect(); FloatRect scaledRect(rect); scaledRect.scale(m_scale); IntRect rectInTileCoords(enclosingIntRect(scaledRect)); TileIndex topLeft; TileIndex bottomRight; getTileIndexRangeForRect(rectInTileCoords, topLeft, bottomRight); TileCohort currCohort = nextTileCohort(); unsigned tilesInCohort = 0; IntRect coverageRect; for (int y = topLeft.y(); y <= bottomRight.y(); ++y) { for (int x = topLeft.x(); x <= bottomRight.x(); ++x) { TileIndex tileIndex(x, y); IntRect tileRect = rectForTileIndex(tileIndex); TileInfo& tileInfo = m_tiles.add(tileIndex, TileInfo()).iterator->value; coverageRect.unite(tileRect); bool shouldChangeTileLayerFrame = false; if (!tileInfo.layer) { tileInfo.layer = m_controller.createTileLayer(tileRect, *this); ASSERT(!m_tileRepaintCounts.contains(tileInfo.layer.get())); } else { // We already have a layer for this tile. Ensure that its size is correct. FloatSize tileLayerSize(tileInfo.layer->bounds().size()); shouldChangeTileLayerFrame = tileLayerSize != FloatSize(tileRect.size()); if (shouldChangeTileLayerFrame) { tileInfo.layer->setBounds(FloatRect(FloatPoint(), tileRect.size())); tileInfo.layer->setPosition(tileRect.location()); tileInfo.layer->setNeedsDisplay(); } } if (newTileType == CoverageType::SecondaryTiles && !tileRect.intersects(m_primaryTileCoverageRect)) { tileInfo.cohort = currCohort; ++tilesInCohort; } bool shouldParentTileLayer = (!m_controller.unparentsOffscreenTiles() || m_controller.isInWindow()) && !tileInfo.layer->superlayer(); if (shouldParentTileLayer) m_containerLayer.get().appendSublayer(*tileInfo.layer); } } if (tilesInCohort) startedNewCohort(currCohort); return coverageRect; }
void TileGrid::revalidateTiles(TileValidationPolicy validationPolicy) { FloatRect coverageRect = m_controller.coverageRect(); IntRect bounds = m_controller.bounds(); if (coverageRect.isEmpty() || bounds.isEmpty()) return; FloatRect scaledRect(coverageRect); scaledRect.scale(m_scale); IntRect coverageRectInTileCoords(enclosingIntRect(scaledRect)); TileCohort currCohort = nextTileCohort(); unsigned tilesInCohort = 0; double minimumRevalidationTimerDuration = std::numeric_limits<double>::max(); bool needsTileRevalidation = false; // Move tiles newly outside the coverage rect into the cohort map. for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) { TileInfo& tileInfo = it->value; TileIndex tileIndex = it->key; PlatformCALayer* tileLayer = tileInfo.layer.get(); IntRect tileRect = rectForTileIndex(tileIndex); if (tileRect.intersects(coverageRectInTileCoords)) { tileInfo.cohort = VisibleTileCohort; if (tileInfo.hasStaleContent) { // FIXME: store a dirty region per layer? tileLayer->setNeedsDisplay(); tileInfo.hasStaleContent = false; } } else { // Add to the currentCohort if not already in one. if (tileInfo.cohort == VisibleTileCohort) { tileInfo.cohort = currCohort; ++tilesInCohort; if (m_controller.unparentsOffscreenTiles()) tileLayer->removeFromSuperlayer(); } else if (m_controller.unparentsOffscreenTiles() && m_controller.shouldAggressivelyRetainTiles() && tileLayer->superlayer()) { // Aggressive tile retention means we'll never remove cohorts, but we need to make sure they're unparented. // We can't immediately unparent cohorts comprised of secondary tiles that never touch the primary coverage rect, // because that would defeat the usefulness of prepopulateRect(); instead, age prepopulated tiles out as if they were being removed. for (auto& cohort : m_cohortList) { if (cohort.cohort != tileInfo.cohort) continue; double timeUntilCohortExpires = cohort.timeUntilExpiration(); if (timeUntilCohortExpires > 0) { minimumRevalidationTimerDuration = std::min(minimumRevalidationTimerDuration, timeUntilCohortExpires); needsTileRevalidation = true; } else tileLayer->removeFromSuperlayer(); break; } } } } if (needsTileRevalidation) m_controller.scheduleTileRevalidation(minimumRevalidationTimerDuration); if (tilesInCohort) startedNewCohort(currCohort); if (!m_controller.shouldAggressivelyRetainTiles()) { if (m_controller.shouldTemporarilyRetainTileCohorts()) scheduleCohortRemoval(); else if (tilesInCohort) removeTilesInCohort(currCohort); } // Ensure primary tile coverage tiles. m_primaryTileCoverageRect = ensureTilesForRect(coverageRect, CoverageType::PrimaryTiles); if (validationPolicy & PruneSecondaryTiles) { removeAllSecondaryTiles(); m_cohortList.clear(); } else { for (auto& secondaryCoverageRect : m_secondaryTileCoverageRects) { FloatRect secondaryRectInLayerCoordinates(secondaryCoverageRect); secondaryRectInLayerCoordinates.scale(1 / m_scale); ensureTilesForRect(secondaryRectInLayerCoordinates, CoverageType::SecondaryTiles); } m_secondaryTileCoverageRects.clear(); } if (m_controller.unparentsOffscreenTiles() && (validationPolicy & UnparentAllTiles)) { for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) it->value.layer->removeFromSuperlayer(); } auto boundsAtLastRevalidate = m_controller.boundsAtLastRevalidate(); if (boundsAtLastRevalidate != bounds) { // If there are margin tiles and the bounds have grown taller or wider, then the tiles that used to // be bottom or right margin tiles need to be invalidated. if (m_controller.hasMargins()) { if (bounds.width() > boundsAtLastRevalidate.width() || bounds.height() > boundsAtLastRevalidate.height()) { IntRect boundsWithoutMargin = m_controller.boundsWithoutMargin(); IntRect oldBoundsWithoutMargin = m_controller.boundsAtLastRevalidateWithoutMargin(); if (bounds.height() > boundsAtLastRevalidate.height()) { IntRect formerBottomMarginRect = IntRect(oldBoundsWithoutMargin.x(), oldBoundsWithoutMargin.height(), oldBoundsWithoutMargin.width(), boundsWithoutMargin.height() - oldBoundsWithoutMargin.height()); setNeedsDisplayInRect(formerBottomMarginRect); } if (bounds.width() > boundsAtLastRevalidate.width()) { IntRect formerRightMarginRect = IntRect(oldBoundsWithoutMargin.width(), oldBoundsWithoutMargin.y(), boundsWithoutMargin.width() - oldBoundsWithoutMargin.width(), oldBoundsWithoutMargin.height()); setNeedsDisplayInRect(formerRightMarginRect); } } } FloatRect scaledBounds(bounds); scaledBounds.scale(m_scale); IntRect boundsInTileCoords(enclosingIntRect(scaledBounds)); TileIndex topLeftForBounds; TileIndex bottomRightForBounds; getTileIndexRangeForRect(boundsInTileCoords, topLeftForBounds, bottomRightForBounds); Vector<TileIndex> tilesToRemove; for (auto& index : m_tiles.keys()) { if (index.y() < topLeftForBounds.y() || index.y() > bottomRightForBounds.y() || index.x() < topLeftForBounds.x() || index.x() > bottomRightForBounds.x()) tilesToRemove.append(index); } removeTiles(tilesToRemove); } m_controller.didRevalidateTiles(); }