void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { if (!showsUnavailablePluginIndicator()) return; if (paintInfo.phase == PaintPhaseSelection) return; GraphicsContext& context = paintInfo.context(); if (context.paintingDisabled()) return; FloatRect contentRect; FloatRect indicatorRect; FloatRect replacementTextRect; FloatRect arrowRect; FontCascade font; TextRun run(emptyString()); float textWidth; if (!getReplacementTextGeometry(paintOffset, contentRect, indicatorRect, replacementTextRect, arrowRect, font, run, textWidth)) return; Path background; background.addRoundedRect(indicatorRect, FloatSize(replacementTextRoundedRectRadius, replacementTextRoundedRectRadius)); GraphicsContextStateSaver stateSaver(context); context.clip(contentRect); context.setFillColor(m_unavailablePluginIndicatorIsPressed ? replacementTextRoundedRectPressedColor() : replacementTextRoundedRectColor()); context.fillPath(background); Path strokePath; FloatRect strokeRect(indicatorRect); strokeRect.inflate(1); strokePath.addRoundedRect(strokeRect, FloatSize(replacementTextRoundedRectRadius + 1, replacementTextRoundedRectRadius + 1)); context.setStrokeColor(unavailablePluginBorderColor()); context.setStrokeThickness(2); context.strokePath(strokePath); const FontMetrics& fontMetrics = font.fontMetrics(); float labelX = roundf(replacementTextRect.location().x() + replacementTextRoundedRectLeftTextMargin); float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - fontMetrics.height()) / 2 + fontMetrics.ascent() + replacementTextRoundedRectTopTextMargin); context.setFillColor(replacementTextColor()); context.drawBidiText(font, run, FloatPoint(labelX, labelY)); if (shouldUnavailablePluginMessageBeButton(document(), m_pluginUnavailabilityReason)) { arrowRect.inflate(-replacementArrowCirclePadding); context.beginTransparencyLayer(1.0); context.setFillColor(replacementTextColor()); context.fillEllipse(arrowRect); context.setCompositeOperation(CompositeClear); drawReplacementArrow(context, arrowRect); context.endTransparencyLayer(); } }
void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext& context, TextDecoration decoration, const SVGTextFragment& fragment, RenderBoxModelObject& decorationRenderer) { ASSERT(!m_paintingResource); ASSERT(m_paintingResourceMode != ApplyToDefaultMode); RenderStyle& decorationStyle = decorationRenderer.style(); float scalingFactor = 1; FontCascade scaledFont; RenderSVGInlineText::computeNewScaledFontForStyle(decorationRenderer, decorationStyle, scalingFactor, scaledFont); ASSERT(scalingFactor); // The initial y value refers to overline position. float thickness = thicknessForDecoration(decoration, scaledFont); if (fragment.width <= 0 && thickness <= 0) return; FloatPoint decorationOrigin(fragment.x, fragment.y); float width = fragment.width; const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics(); GraphicsContextStateSaver stateSaver(context); if (scalingFactor != 1) { width *= scalingFactor; decorationOrigin.scale(scalingFactor, scalingFactor); context.scale(FloatSize(1 / scalingFactor, 1 / scalingFactor)); } decorationOrigin.move(0, -scaledFontMetrics.floatAscent() + positionOffsetForDecoration(decoration, scaledFontMetrics, thickness)); Path path; path.addRect(FloatRect(decorationOrigin, FloatSize(width, thickness))); GraphicsContext* contextPtr = &context; if (acquirePaintingResource(contextPtr, scalingFactor, decorationRenderer, &decorationStyle)) releasePaintingResource(contextPtr, &path); }
void FullscreenVideoController::draw() { auto bitmapDC = adoptGDIObject(::CreateCompatibleDC(HWndDC(m_hudWindow))); HGDIOBJ oldBitmap = SelectObject(bitmapDC.get(), m_bitmap.get()); GraphicsContext context(bitmapDC.get(), true); context.save(); // Draw the background IntSize outerRadius(borderRadius, borderRadius); IntRect outerRect(0, 0, windowWidth, windowHeight); IntSize innerRadius(borderRadius - borderThickness, borderRadius - borderThickness); IntRect innerRect(borderThickness, borderThickness, windowWidth - borderThickness * 2, windowHeight - borderThickness * 2); context.fillRoundedRect(FloatRoundedRect(outerRect, outerRadius, outerRadius, outerRadius, outerRadius), Color(borderColor)); context.setCompositeOperation(CompositeCopy); context.fillRoundedRect(FloatRoundedRect(innerRect, innerRadius, innerRadius, innerRadius, innerRadius), Color(backgroundColor)); // Draw the widgets m_playPauseButton.draw(context); m_volumeUpButton.draw(context); m_volumeSliderButton.draw(context); m_volumeDownButton.draw(context); m_timeSliderButton.draw(context); m_exitFullscreenButton.draw(context); m_volumeSlider.draw(context); m_timeSlider.draw(context); // Draw the text strings FontCascadeDescription desc; NONCLIENTMETRICS metrics; metrics.cbSize = sizeof(metrics); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0); desc.setOneFamily(metrics.lfSmCaptionFont.lfFaceName); desc.setComputedSize(textSize); FontCascade font = FontCascade(desc, 0, 0); font.update(0); String s; // The y positioning of these two text strings is tricky because they are so small. They // are currently positioned relative to the center of the slider and then down the font // height / 4 (which is actually half of font height /2), which positions the center of // the text at the center of the slider. // Left string s = timeToString(currentTime()); int fontHeight = font.fontMetrics().height(); TextRun leftText(s); context.setFillColor(Color(textColor)); context.drawText(font, leftText, IntPoint(windowWidth / 2 - timeSliderWidth / 2 - margin - font.width(leftText), windowHeight - margin - sliderHeight / 2 + fontHeight / 4)); // Right string s = timeToString(currentTime() - duration()); TextRun rightText(s); context.setFillColor(Color(textColor)); context.drawText(font, rightText, IntPoint(windowWidth / 2 + timeSliderWidth / 2 + margin, windowHeight - margin - sliderHeight / 2 + fontHeight / 4)); // Copy to the window BLENDFUNCTION blendFunction = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; SIZE size = { windowWidth, windowHeight }; POINT sourcePoint = {0, 0}; POINT destPoint = { m_hudPosition.x(), m_hudPosition.y() }; BOOL result = UpdateLayeredWindow(m_hudWindow, 0, &destPoint, &size, bitmapDC.get(), &sourcePoint, 0, &blendFunction, ULW_ALPHA); context.restore(); ::SelectObject(bitmapDC.get(), oldBitmap); }
void PopupMenuWin::paint(const IntRect& damageRect, HDC hdc) { if (!m_popup) return; if (!m_DC) { m_DC = adoptGDIObject(::CreateCompatibleDC(HWndDC(m_popup))); if (!m_DC) return; } if (m_bmp) { bool keepBitmap = false; BITMAP bitmap; if (::GetObject(m_bmp.get(), sizeof(bitmap), &bitmap)) keepBitmap = bitmap.bmWidth == clientRect().width() && bitmap.bmHeight == clientRect().height(); if (!keepBitmap) m_bmp.clear(); } if (!m_bmp) { BitmapInfo bitmapInfo = BitmapInfo::createBottomUp(clientRect().size()); void* pixels = 0; m_bmp = adoptGDIObject(::CreateDIBSection(m_DC.get(), &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0)); if (!m_bmp) return; ::SelectObject(m_DC.get(), m_bmp.get()); } GraphicsContext context(m_DC.get()); int itemCount = client()->listSize(); // listRect is the damageRect translated into the coordinates of the entire menu list (which is itemCount * m_itemHeight pixels tall) IntRect listRect = damageRect; listRect.move(IntSize(0, m_scrollOffset * m_itemHeight)); for (int y = listRect.y(); y < listRect.maxY(); y += m_itemHeight) { int index = y / m_itemHeight; Color optionBackgroundColor, optionTextColor; PopupMenuStyle itemStyle = client()->itemStyle(index); if (index == focusedIndex()) { optionBackgroundColor = RenderTheme::defaultTheme()->activeListBoxSelectionBackgroundColor(); optionTextColor = RenderTheme::defaultTheme()->activeListBoxSelectionForegroundColor(); } else { optionBackgroundColor = itemStyle.backgroundColor(); optionTextColor = itemStyle.foregroundColor(); } // itemRect is in client coordinates IntRect itemRect(0, (index - m_scrollOffset) * m_itemHeight, damageRect.width(), m_itemHeight); // Draw the background for this menu item if (itemStyle.isVisible()) context.fillRect(itemRect, optionBackgroundColor); if (client()->itemIsSeparator(index)) { IntRect separatorRect(itemRect.x() + separatorPadding, itemRect.y() + (itemRect.height() - separatorHeight) / 2, itemRect.width() - 2 * separatorPadding, separatorHeight); context.fillRect(separatorRect, optionTextColor); continue; } String itemText = client()->itemText(index); TextRun textRun(itemText, 0, 0, AllowTrailingExpansion, itemStyle.textDirection(), itemStyle.hasTextDirectionOverride()); context.setFillColor(optionTextColor); FontCascade itemFont = client()->menuStyle().font(); if (client()->itemIsLabel(index)) { auto d = itemFont.fontDescription(); d.setWeight(d.bolderWeight()); itemFont = FontCascade(d, itemFont.letterSpacing(), itemFont.wordSpacing()); itemFont.update(m_popupClient->fontSelector()); } // Draw the item text if (itemStyle.isVisible()) { int textX = 0; if (client()->menuStyle().textDirection() == LTR) { textX = std::max<int>(0, client()->clientPaddingLeft() - client()->clientInsetLeft()); if (RenderTheme::defaultTheme()->popupOptionSupportsTextIndent()) textX += minimumIntValueForLength(itemStyle.textIndent(), itemRect.width()); } else { textX = itemRect.width() - client()->menuStyle().font().width(textRun); textX = std::min<int>(textX, textX - client()->clientPaddingRight() + client()->clientInsetRight()); if (RenderTheme::defaultTheme()->popupOptionSupportsTextIndent()) textX -= minimumIntValueForLength(itemStyle.textIndent(), itemRect.width()); } int textY = itemRect.y() + itemFont.fontMetrics().ascent() + (itemRect.height() - itemFont.fontMetrics().height()) / 2; context.drawBidiText(itemFont, textRun, IntPoint(textX, textY)); } } if (m_scrollbar) m_scrollbar->paint(context, damageRect); HWndDC hWndDC; HDC localDC = hdc ? hdc : hWndDC.setHWnd(m_popup); ::BitBlt(localDC, damageRect.x(), damageRect.y(), damageRect.width(), damageRect.height(), m_DC.get(), damageRect.x(), damageRect.y(), SRCCOPY); }