📄 renderthemesafari.cpp
字号:
return sizes;}const int* RenderThemeSafari::popupButtonPadding(NSControlSize size) const{ static const int padding[3][4] = { { 2, 26, 3, 8 }, { 2, 23, 3, 8 }, { 2, 22, 3, 10 } }; return padding[size];}bool RenderThemeSafari::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& info, const IntRect& r){ ASSERT(SafariThemeLibrary()); NSControlSize controlSize = controlSizeFromRect(r, popupButtonSizes()); IntRect inflatedRect = r; IntSize size = popupButtonSizes()[controlSize]; size.setWidth(r.width()); // Now inflate it to account for the shadow. if (r.width() >= minimumMenuListSize(o->style())) inflatedRect = inflateRect(inflatedRect, size, popupButtonMargins(controlSize)); paintThemePart(DropDownButtonPart, info.context->platformContext(), inflatedRect, controlSize, determineState(o)); return false;}const float baseFontSize = 11.0f;const float baseArrowHeight = 5.0f;const float baseArrowWidth = 7.0f;const int arrowPaddingLeft = 5;const int arrowPaddingRight = 5;const int paddingBeforeSeparator = 4;const int baseBorderRadius = 5;const int styledPopupPaddingLeft = 8;const int styledPopupPaddingTop = 1;const int styledPopupPaddingBottom = 2;static void TopGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData){ static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.4f }; static float light[4] = { 1.0f, 1.0f, 1.0f, 0.15f }; float a = inData[0]; int i = 0; for (i = 0; i < 4; i++) outData[i] = (1.0f - a) * dark[i] + a * light[i];}static void BottomGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData){ static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.0f }; static float light[4] = { 1.0f, 1.0f, 1.0f, 0.3f }; float a = inData[0]; int i = 0; for (i = 0; i < 4; i++) outData[i] = (1.0f - a) * dark[i] + a * light[i];}static void MainGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData){ static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.15f }; static float light[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float a = inData[0]; int i = 0; for (i = 0; i < 4; i++) outData[i] = (1.0f - a) * dark[i] + a * light[i];}static void TrackGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData){ static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.678f }; static float light[4] = { 0.0f, 0.0f, 0.0f, 0.13f }; float a = inData[0]; int i = 0; for (i = 0; i < 4; i++) outData[i] = (1.0f - a) * dark[i] + a * light[i];}void RenderThemeSafari::paintMenuListButtonGradients(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r){ CGContextRef context = paintInfo.context->platformContext(); paintInfo.context->save(); int radius = o->style()->borderTopLeftRadius().width(); RetainPtr<CGColorSpaceRef> cspace(AdoptCF, CGColorSpaceCreateDeviceRGB()); FloatRect topGradient(r.x(), r.y(), r.width(), r.height() / 2.0f); struct CGFunctionCallbacks topCallbacks = { 0, TopGradientInterpolate, NULL }; RetainPtr<CGFunctionRef> topFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &topCallbacks)); RetainPtr<CGShadingRef> topShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.bottom()), topFunction.get(), false, false)); FloatRect bottomGradient(r.x() + radius, r.y() + r.height() / 2.0f, r.width() - 2.0f * radius, r.height() / 2.0f); struct CGFunctionCallbacks bottomCallbacks = { 0, BottomGradientInterpolate, NULL }; RetainPtr<CGFunctionRef> bottomFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &bottomCallbacks)); RetainPtr<CGShadingRef> bottomShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(bottomGradient.x(), bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.bottom()), bottomFunction.get(), false, false)); struct CGFunctionCallbacks mainCallbacks = { 0, MainGradientInterpolate, NULL }; RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks)); RetainPtr<CGShadingRef> mainShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.x(), r.y()), CGPointMake(r.x(), r.bottom()), mainFunction.get(), false, false)); RetainPtr<CGShadingRef> leftShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.x(), r.y()), CGPointMake(r.x() + radius, r.y()), mainFunction.get(), false, false)); RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.right(), r.y()), CGPointMake(r.right() - radius, r.y()), mainFunction.get(), false, false)); paintInfo.context->save(); CGContextClipToRect(context, r); paintInfo.context->addRoundedRectClip(r, o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); CGContextDrawShading(context, mainShading.get()); paintInfo.context->restore(); paintInfo.context->save(); CGContextClipToRect(context, topGradient); paintInfo.context->addRoundedRectClip(enclosingIntRect(topGradient), o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), IntSize(), IntSize()); CGContextDrawShading(context, topShading.get()); paintInfo.context->restore(); paintInfo.context->save(); CGContextClipToRect(context, bottomGradient); paintInfo.context->addRoundedRectClip(enclosingIntRect(bottomGradient), IntSize(), IntSize(), o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); CGContextDrawShading(context, bottomShading.get()); paintInfo.context->restore(); paintInfo.context->save(); CGContextClipToRect(context, r); paintInfo.context->addRoundedRectClip(r, o->style()->borderTopLeftRadius(), o->style()->borderTopRightRadius(), o->style()->borderBottomLeftRadius(), o->style()->borderBottomRightRadius()); CGContextDrawShading(context, leftShading.get()); CGContextDrawShading(context, rightShading.get()); paintInfo.context->restore(); paintInfo.context->restore();}bool RenderThemeSafari::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r){ paintInfo.context->save(); IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(), r.y() + o->style()->borderTopWidth(), r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(), r.height() - o->style()->borderTopWidth() - o->style()->borderBottomWidth()); // Draw the gradients to give the styled popup menu a button appearance paintMenuListButtonGradients(o, paintInfo, bounds); // Since we actually know the size of the control here, we restrict the font scale to make sure the arrow will fit vertically in the bounds float fontScale = min(o->style()->fontSize() / baseFontSize, bounds.height() / baseArrowHeight); float centerY = bounds.y() + bounds.height() / 2.0f; float arrowHeight = baseArrowHeight * fontScale; float arrowWidth = baseArrowWidth * fontScale; float leftEdge = bounds.right() - arrowPaddingRight - arrowWidth; if (bounds.width() < arrowWidth + arrowPaddingLeft) return false; paintInfo.context->setFillColor(o->style()->color()); paintInfo.context->setStrokeColor(NoStroke); FloatPoint arrow[3]; arrow[0] = FloatPoint(leftEdge, centerY - arrowHeight / 2.0f); arrow[1] = FloatPoint(leftEdge + arrowWidth, centerY - arrowHeight / 2.0f); arrow[2] = FloatPoint(leftEdge + arrowWidth / 2.0f, centerY + arrowHeight / 2.0f); // Draw the arrow paintInfo.context->drawConvexPolygon(3, arrow, true); Color leftSeparatorColor(0, 0, 0, 40); Color rightSeparatorColor(255, 255, 255, 40); // FIXME: Should the separator thickness and space be scaled up by fontScale? int separatorSpace = 2; int leftEdgeOfSeparator = static_cast<int>(leftEdge - arrowPaddingLeft); // FIXME: Round? // Draw the separator to the left of the arrows paintInfo.context->setStrokeThickness(1.0f); paintInfo.context->setStrokeStyle(SolidStroke); paintInfo.context->setStrokeColor(leftSeparatorColor); paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()), IntPoint(leftEdgeOfSeparator, bounds.bottom())); paintInfo.context->setStrokeColor(rightSeparatorColor); paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()), IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.bottom())); paintInfo.context->restore(); return false;}void RenderThemeSafari::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const{ NSControlSize controlSize = controlSizeForFont(style); style->resetBorder(); style->resetPadding(); // Height is locked to auto. style->setHeight(Length(Auto)); // White-space is locked to pre style->setWhiteSpace(PRE); // Set the foreground color to black or gray when we have the aqua look. // Cast to RGB32 is to work around a compiler bug. style->setColor(e->isFormControlElement() && toFormControlElement(e)->isEnabled() ? static_cast<RGBA32>(Color::black) : Color::darkGray); // Set the button's vertical size. setButtonSize(style); // Our font is locked to the appropriate system font size for the control. To clarify, we first use the CSS-specified font to figure out // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate // system font for the control size instead. setFontFromControlSize(selector, style, controlSize);}int RenderThemeSafari::popupInternalPaddingLeft(RenderStyle* style) const{ if (style->appearance() == MenulistPart) return popupButtonPadding(controlSizeForFont(style))[leftPadding]; if (style->appearance() == MenulistButtonPart) return styledPopupPaddingLeft; return 0;}int RenderThemeSafari::popupInternalPaddingRight(RenderStyle* style) const{ if (style->appearance() == MenulistPart) return popupButtonPadding(controlSizeForFont(style))[rightPadding]; if (style->appearance() == MenulistButtonPart) { float fontScale = style->fontSize() / baseFontSize; float arrowWidth = baseArrowWidth * fontScale; return static_cast<int>(ceilf(arrowWidth + arrowPaddingLeft + arrowPaddingRight + paddingBeforeSeparator)); } return 0;}int RenderThemeSafari::popupInternalPaddingTop(RenderStyle* style) const{ if (style->appearance() == MenulistPart) return popupButtonPadding(controlSizeForFont(style))[topPadding]; if (style->appearance() == MenulistButtonPart) return styledPopupPaddingTop; return 0;}int RenderThemeSafari::popupInternalPaddingBottom(RenderStyle* style) const{ if (style->appearance() == MenulistPart) return popupButtonPadding(controlSizeForFont(style))[bottomPadding]; if (style->appearance() == MenulistButtonPart) return styledPopupPaddingBottom; return 0;}void RenderThemeSafari::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const{ float fontScale = style->fontSize() / baseFontSize; style->resetPadding(); style->setBorderRadius(IntSize(int(baseBorderRadius + fontScale - 1), int(baseBorderRadius + fontScale - 1))); // FIXME: Round up? const int minHeight = 15; style->setMinHeight(Length(minHeight, Fixed)); style->setLineHeight(RenderStyle::initialLineHeight());}const IntSize* RenderThemeSafari::menuListSizes() const{ static const IntSize sizes[3] = { IntSize(9, 0), IntSize(5, 0), IntSize(0, 0) }; return sizes;}int RenderThemeSafari::minimumMenuListSize(RenderStyle* style) const{ return sizeForSystemFont(style, menuListSizes()).width();}const int trackWidth = 5;const int trackRadius = 2;bool RenderThemeSafari::paintSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r){ IntRect bounds = r; if (o->style()->appearance() == SliderHorizontalPart || o->style()->appearance() == MediaSliderPart) { bounds.setHeight(trackWidth); bounds.setY(r.y() + r.height() / 2 - trackWidth / 2); } else if (o->style()->appearance() == SliderVerticalPart) { bounds.setWidth(trackWidth); bounds.setX(r.x() + r.width() / 2 - trackWidth / 2); } CGContextRef context = paintInfo.context->platformContext(); RetainPtr<CGColorSpaceRef> cspace(AdoptCF, CGColorSpaceCreateDeviceRGB()); paintInfo.context->save(); CGContextClipToRect(context, bounds);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -