📄 renderboxmodelobject.cpp
字号:
return 0; int vpos = 0; EVerticalAlign va = style()->verticalAlign(); if (va == TOP) vpos = PositionTop; else if (va == BOTTOM) vpos = PositionBottom; else { bool checkParent = parent()->isRenderInline() && parent()->style()->verticalAlign() != TOP && parent()->style()->verticalAlign() != BOTTOM; vpos = checkParent ? toRenderInline(parent())->verticalPositionFromCache(firstLine) : 0; // don't allow elements nested inside text-top to have a different valignment. if (va == BASELINE) return vpos; const Font& f = parent()->style(firstLine)->font(); int fontsize = f.pixelSize(); if (va == SUB) vpos += fontsize / 5 + 1; else if (va == SUPER) vpos -= fontsize / 3 + 1; else if (va == TEXT_TOP) vpos += baselinePosition(firstLine) - f.ascent(); else if (va == MIDDLE) vpos += -static_cast<int>(f.xHeight() / 2) - lineHeight(firstLine) / 2 + baselinePosition(firstLine); else if (va == TEXT_BOTTOM) { vpos += f.descent(); if (!isReplaced()) // lineHeight - baselinePosition is always 0 for replaced elements, so don't bother wasting time in that case. vpos -= (lineHeight(firstLine) - baselinePosition(firstLine)); } else if (va == BASELINE_MIDDLE) vpos += -lineHeight(firstLine) / 2 + baselinePosition(firstLine); else if (va == LENGTH) vpos -= style()->verticalAlignLength().calcValue(lineHeight(firstLine)); } return vpos;}bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext, int tx, int ty, int w, int h, const RenderStyle* style, const NinePieceImage& ninePieceImage, CompositeOperator op){ StyleImage* styleImage = ninePieceImage.image(); if (!styleImage || !styleImage->canRender(style->effectiveZoom())) return false; if (!styleImage->isLoaded()) return true; // Never paint a nine-piece image incrementally, but don't paint the fallback borders either. // If we have a border radius, the image gets clipped to the rounded rect. bool clipped = false; if (style->hasBorderRadius()) { IntRect clipRect(tx, ty, w, h); graphicsContext->save(); graphicsContext->addRoundedRectClip(clipRect, style->borderTopLeftRadius(), style->borderTopRightRadius(), style->borderBottomLeftRadius(), style->borderBottomRightRadius()); clipped = true; } // FIXME: border-image is broken with full page zooming when tiling has to happen, since the tiling function // doesn't have any understanding of the zoom that is in effect on the tile. styleImage->setImageContainerSize(IntSize(w, h)); IntSize imageSize = styleImage->imageSize(this, 1.0f); int imageWidth = imageSize.width(); int imageHeight = imageSize.height(); int topSlice = min(imageHeight, ninePieceImage.m_slices.top().calcValue(imageHeight)); int bottomSlice = min(imageHeight, ninePieceImage.m_slices.bottom().calcValue(imageHeight)); int leftSlice = min(imageWidth, ninePieceImage.m_slices.left().calcValue(imageWidth)); int rightSlice = min(imageWidth, ninePieceImage.m_slices.right().calcValue(imageWidth)); ENinePieceImageRule hRule = ninePieceImage.horizontalRule(); ENinePieceImageRule vRule = ninePieceImage.verticalRule(); bool fitToBorder = style->borderImage() == ninePieceImage; int leftWidth = fitToBorder ? style->borderLeftWidth() : leftSlice; int topWidth = fitToBorder ? style->borderTopWidth() : topSlice; int rightWidth = fitToBorder ? style->borderRightWidth() : rightSlice; int bottomWidth = fitToBorder ? style->borderBottomWidth() : bottomSlice; bool drawLeft = leftSlice > 0 && leftWidth > 0; bool drawTop = topSlice > 0 && topWidth > 0; bool drawRight = rightSlice > 0 && rightWidth > 0; bool drawBottom = bottomSlice > 0 && bottomWidth > 0; bool drawMiddle = (imageWidth - leftSlice - rightSlice) > 0 && (w - leftWidth - rightWidth) > 0 && (imageHeight - topSlice - bottomSlice) > 0 && (h - topWidth - bottomWidth) > 0; Image* image = styleImage->image(this, imageSize); if (drawLeft) { // Paint the top and bottom left corners. // The top left corner rect is (tx, ty, leftWidth, topWidth) // The rect to use from within the image is obtained from our slice, and is (0, 0, leftSlice, topSlice) if (drawTop) graphicsContext->drawImage(image, IntRect(tx, ty, leftWidth, topWidth), IntRect(0, 0, leftSlice, topSlice), op); // The bottom left corner rect is (tx, ty + h - bottomWidth, leftWidth, bottomWidth) // The rect to use from within the image is (0, imageHeight - bottomSlice, leftSlice, botomSlice) if (drawBottom) graphicsContext->drawImage(image, IntRect(tx, ty + h - bottomWidth, leftWidth, bottomWidth), IntRect(0, imageHeight - bottomSlice, leftSlice, bottomSlice), op); // Paint the left edge. // Have to scale and tile into the border rect. graphicsContext->drawTiledImage(image, IntRect(tx, ty + topWidth, leftWidth, h - topWidth - bottomWidth), IntRect(0, topSlice, leftSlice, imageHeight - topSlice - bottomSlice), Image::StretchTile, (Image::TileRule)vRule, op); } if (drawRight) { // Paint the top and bottom right corners // The top right corner rect is (tx + w - rightWidth, ty, rightWidth, topWidth) // The rect to use from within the image is obtained from our slice, and is (imageWidth - rightSlice, 0, rightSlice, topSlice) if (drawTop) graphicsContext->drawImage(image, IntRect(tx + w - rightWidth, ty, rightWidth, topWidth), IntRect(imageWidth - rightSlice, 0, rightSlice, topSlice), op); // The bottom right corner rect is (tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth) // The rect to use from within the image is (imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice) if (drawBottom) graphicsContext->drawImage(image, IntRect(tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth), IntRect(imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice), op); // Paint the right edge. graphicsContext->drawTiledImage(image, IntRect(tx + w - rightWidth, ty + topWidth, rightWidth, h - topWidth - bottomWidth), IntRect(imageWidth - rightSlice, topSlice, rightSlice, imageHeight - topSlice - bottomSlice), Image::StretchTile, (Image::TileRule)vRule, op); } // Paint the top edge. if (drawTop) graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty, w - leftWidth - rightWidth, topWidth), IntRect(leftSlice, 0, imageWidth - rightSlice - leftSlice, topSlice), (Image::TileRule)hRule, Image::StretchTile, op); // Paint the bottom edge. if (drawBottom) graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty + h - bottomWidth, w - leftWidth - rightWidth, bottomWidth), IntRect(leftSlice, imageHeight - bottomSlice, imageWidth - rightSlice - leftSlice, bottomSlice), (Image::TileRule)hRule, Image::StretchTile, op); // Paint the middle. if (drawMiddle) graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty + topWidth, w - leftWidth - rightWidth, h - topWidth - bottomWidth), IntRect(leftSlice, topSlice, imageWidth - rightSlice - leftSlice, imageHeight - topSlice - bottomSlice), (Image::TileRule)hRule, (Image::TileRule)vRule, op); // Clear the clip for the border radius. if (clipped) graphicsContext->restore(); return true;}void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx, int ty, int w, int h, const RenderStyle* style, bool begin, bool end){ if (paintNinePieceImage(graphicsContext, tx, ty, w, h, style, style->borderImage())) return; const Color& tc = style->borderTopColor(); const Color& bc = style->borderBottomColor(); const Color& lc = style->borderLeftColor(); const Color& rc = style->borderRightColor(); bool tt = style->borderTopIsTransparent(); bool bt = style->borderBottomIsTransparent(); bool rt = style->borderRightIsTransparent(); bool lt = style->borderLeftIsTransparent(); EBorderStyle ts = style->borderTopStyle(); EBorderStyle bs = style->borderBottomStyle(); EBorderStyle ls = style->borderLeftStyle(); EBorderStyle rs = style->borderRightStyle(); bool renderTop = ts > BHIDDEN && !tt; bool renderLeft = ls > BHIDDEN && begin && !lt; bool renderRight = rs > BHIDDEN && end && !rt; bool renderBottom = bs > BHIDDEN && !bt; // Need sufficient width and height to contain border radius curves. Sanity check our border radii // and our width/height values to make sure the curves can all fit. If not, then we won't paint // any border radii. bool renderRadii = false; IntSize topLeft = style->borderTopLeftRadius(); IntSize topRight = style->borderTopRightRadius(); IntSize bottomLeft = style->borderBottomLeftRadius(); IntSize bottomRight = style->borderBottomRightRadius(); if (style->hasBorderRadius() && static_cast<unsigned>(w) >= static_cast<unsigned>(topLeft.width()) + static_cast<unsigned>(topRight.width()) && static_cast<unsigned>(w) >= static_cast<unsigned>(bottomLeft.width()) + static_cast<unsigned>(bottomRight.width()) && static_cast<unsigned>(h) >= static_cast<unsigned>(topLeft.height()) + static_cast<unsigned>(bottomLeft.height()) && static_cast<unsigned>(h) >= static_cast<unsigned>(topRight.height()) + static_cast<unsigned>(bottomRight.height())) renderRadii = true; // Clip to the rounded rectangle. if (renderRadii) { graphicsContext->save(); graphicsContext->addRoundedRectClip(IntRect(tx, ty, w, h), topLeft, topRight, bottomLeft, bottomRight); } int firstAngleStart, secondAngleStart, firstAngleSpan, secondAngleSpan; float thickness; bool upperLeftBorderStylesMatch = renderLeft && (ts == ls) && (tc == lc); bool upperRightBorderStylesMatch = renderRight && (ts == rs) && (tc == rc) && (ts != OUTSET) && (ts != RIDGE) && (ts != INSET) && (ts != GROOVE); bool lowerLeftBorderStylesMatch = renderLeft && (bs == ls) && (bc == lc) && (bs != OUTSET) && (bs != RIDGE) && (bs != INSET) && (bs != GROOVE); bool lowerRightBorderStylesMatch = renderRight && (bs == rs) && (bc == rc); if (renderTop) { bool ignore_left = (renderRadii && topLeft.width() > 0) || (tc == lc && tt == lt && ts >= OUTSET && (ls == DOTTED || ls == DASHED || ls == SOLID || ls == OUTSET)); bool ignore_right = (renderRadii && topRight.width() > 0) || (tc == rc && tt == rt && ts >= OUTSET && (rs == DOTTED || rs == DASHED || rs == SOLID || rs == INSET)); int x = tx; int x2 = tx + w; if (renderRadii) { x += topLeft.width(); x2 -= topRight.width(); } drawLineForBoxSide(graphicsContext, x, ty, x2, ty + style->borderTopWidth(), BSTop, tc, style->color(), ts, ignore_left ? 0 : style->borderLeftWidth(), ignore_right ? 0 : style->borderRightWidth()); if (renderRadii) { int leftY = ty; // We make the arc double thick and let the clip rect take care of clipping the extra off. // We're doing this because it doesn't seem possible to match the curve of the clip exactly // with the arc-drawing function. thickness = style->borderTopWidth() * 2; if (topLeft.width()) { int leftX = tx; // The inner clip clips inside the arc. This is especially important for 1px borders. bool applyLeftInnerClip = (style->borderLeftWidth() < topLeft.width()) && (style->borderTopWidth() < topLeft.height()) && (ts != DOUBLE || style->borderTopWidth() > 6); if (applyLeftInnerClip) { graphicsContext->save(); graphicsContext->addInnerRoundedRectClip(IntRect(leftX, leftY, topLeft.width() * 2, topLeft.height() * 2), style->borderTopWidth()); } firstAngleStart = 90; firstAngleSpan = upperLeftBorderStylesMatch ? 90 : 45; // Draw upper left arc drawArcForBoxSide(graphicsContext, leftX, leftY, thickness, topLeft, firstAngleStart, firstAngleSpan, BSTop, tc, style->color(), ts, true); if (applyLeftInnerClip) graphicsContext->restore(); } if (topRight.width()) { int rightX = tx + w - topRight.width() * 2; bool applyRightInnerClip = (style->borderRightWidth() < topRight.width()) && (style->borderTopWidth() < topRight.height()) && (ts != DOUBLE || style->borderTopWidth() > 6); if (applyRightInnerClip) { graphicsContext->save(); graphicsContext->addInnerRoundedRectClip(IntRect(rightX, leftY, topRight.width() * 2, topRight.height() * 2), style->borderTopWidth()); } if (upperRightBorderStylesMatch) { secondAngleStart = 0; secondAngleSpan = 90; } else { secondAngleStart = 45;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -