Changeset 286588 in webkit
- Timestamp:
- Dec 6, 2021, 10:20:45 PM (4 years ago)
- Location:
- trunk/Source
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r286581 r286588 1 2021-12-06 Patrick Angle <pangle@apple.com> 2 3 [Cocoa] Web Inspector: Unify Grid overlay drawing code 4 https://bugs.webkit.org/show_bug.cgi?id=233773 5 6 Reviewed by Devin Rousso. 7 8 Expose InspectorOverlay::drawGridOverlay as a static method so that it can be used for iOS overlay drawing and 9 clean up other related drawing methods to be private static instead of instance methods or public static methods. 10 11 * inspector/InspectorOverlay.cpp: 12 (WebCore::drawLayoutHatching): 13 (WebCore::fontForLayoutLabel): 14 (WebCore::backgroundPathForLayoutLabel): 15 (WebCore::expectedSizeForLayoutLabel): 16 (WebCore::drawLayoutLabel): 17 (WebCore::InspectorOverlay::drawLayoutHatching): Deleted. 18 (WebCore::InspectorOverlay::fontForLayoutLabel): Deleted. 19 (WebCore::InspectorOverlay::backgroundPathForLayoutLabel): Deleted. 20 (WebCore::InspectorOverlay::drawLayoutLabel): Deleted. 21 * inspector/InspectorOverlay.h: 22 1 23 2021-12-06 Chris Dumez <cdumez@apple.com> 2 24 -
trunk/Source/WebCore/inspector/InspectorOverlay.cpp
r286542 r286588 1171 1171 } 1172 1172 1173 void InspectorOverlay::drawLayoutHatching(GraphicsContext& context, FloatQuad quad)1173 static void drawLayoutHatching(GraphicsContext& context, FloatQuad quad) 1174 1174 { 1175 1175 GraphicsContextStateSaver saver(context); … … 1205 1205 } 1206 1206 1207 FontCascade InspectorOverlay::fontForLayoutLabel()1207 static FontCascade fontForLayoutLabel() 1208 1208 { 1209 1209 FontCascadeDescription fontDescription; … … 1217 1217 } 1218 1218 1219 Path InspectorOverlay::backgroundPathForLayoutLabel(float width, float height, InspectorOverlay::LabelArrowDirection arrowDirection, InspectorOverlay::LabelArrowEdgePosition arrowEdgePosition, float arrowSize)1219 static Path backgroundPathForLayoutLabel(float width, float height, InspectorOverlay::LabelArrowDirection arrowDirection, InspectorOverlay::LabelArrowEdgePosition arrowEdgePosition, float arrowSize) 1220 1220 { 1221 1221 Path path; … … 1347 1347 static FloatSize expectedSizeForLayoutLabel(String label, InspectorOverlay::LabelArrowDirection direction, float maximumWidth = 0) 1348 1348 { 1349 auto font = InspectorOverlay::fontForLayoutLabel();1349 auto font = fontForLayoutLabel(); 1350 1350 1351 1351 float textHeight = font.fontMetrics().floatHeight(); … … 1368 1368 } 1369 1369 1370 void InspectorOverlay::drawLayoutLabel(GraphicsContext& context, String label, FloatPoint point, InspectorOverlay::LabelArrowDirection arrowDirection, InspectorOverlay::LabelArrowEdgePosition arrowEdgePosition, Color backgroundColor, float maximumWidth)1371 { 1372 ASSERT(arrowEdgePosition != LabelArrowEdgePosition::None || arrowDirection ==LabelArrowDirection::None);1370 static void drawLayoutLabel(GraphicsContext& context, String label, FloatPoint point, InspectorOverlay::LabelArrowDirection arrowDirection, InspectorOverlay::LabelArrowEdgePosition arrowEdgePosition, Color backgroundColor, float maximumWidth = 0) 1371 { 1372 ASSERT(arrowEdgePosition != InspectorOverlay::LabelArrowEdgePosition::None || arrowDirection == InspectorOverlay::LabelArrowDirection::None); 1373 1373 1374 1374 GraphicsContextStateSaver saver(context); -
trunk/Source/WebCore/inspector/InspectorOverlay.h
r285529 r286588 219 219 void clearAllGridOverlays(); 220 220 221 WEBCORE_EXPORT static FontCascade fontForLayoutLabel(); 222 WEBCORE_EXPORT static Path backgroundPathForLayoutLabel(float, float, InspectorOverlay::LabelArrowDirection, InspectorOverlay::LabelArrowEdgePosition, float arrowSize); 221 WEBCORE_EXPORT static void drawGridOverlay(GraphicsContext&, const InspectorOverlay::Highlight::GridHighlightOverlay&); 223 222 private: 224 223 using TimeRectPair = std::pair<MonotonicTime, FloatRect>; … … 237 236 Path drawElementTitle(GraphicsContext&, Node&, const Highlight::Bounds&); 238 237 239 void drawLayoutHatching(GraphicsContext&, FloatQuad);240 void drawLayoutLabel(GraphicsContext&, String, FloatPoint, LabelArrowDirection, InspectorOverlay::LabelArrowEdgePosition, Color backgroundColor = Color::white, float maximumWidth = 0);241 242 void drawGridOverlay(GraphicsContext&, const InspectorOverlay::Highlight::GridHighlightOverlay&);243 238 std::optional<InspectorOverlay::Highlight::GridHighlightOverlay> buildGridOverlay(const InspectorOverlay::Grid&, bool offsetBoundsByScroll = false); 244 239 -
trunk/Source/WebKit/ChangeLog
r286585 r286588 1 2021-12-06 Patrick Angle <pangle@apple.com> 2 3 [Cocoa] Web Inspector: Unify Grid overlay drawing code 4 https://bugs.webkit.org/show_bug.cgi?id=233773 5 6 Reviewed by Devin Rousso. 7 8 Remove the (almost) 1-to-1 duplicated logic currently being used to turn Grid Overlays into a layer hierarchy 9 and instead use a graphics context to draw the overlays straight into the view to take advantage of the existing 10 drawing code we use for macOS in WebCore::InspectorOverlay. To accommodate this, we now correctly set the 11 content scale factor of the view itself (so that our drawing does not appear blurry) and set the frame of the 12 view equal to the current visible portion of the parent scroll view, which helps us to avoid having an 13 incredibly large graphics context to draw into (which we would if the view's frame was just set to match the 14 frame of the webpage's view). This frame will not always be the same size, such as when zooming in where less of 15 the frame is visible. Combined with the current content scale, this actually means that on zoom the effective 16 number of pixels that need to be drawn is consistent. 17 18 * UIProcess/Inspector/ios/WKInspectorHighlightView.h: 19 * UIProcess/Inspector/ios/WKInspectorHighlightView.mm: 20 (-[WKInspectorHighlightView initWithFrame:]): 21 - Explicitly set this view to be non-opaque so that page content can be seen below this view. This wasn't 22 previously necessary because the bounds of this view were a zero-rect, which meant the background was never 23 painted. 24 25 (-[WKInspectorHighlightView _removeAllLayers]): 26 (-[WKInspectorHighlightView _createLayers:]): 27 - Because the view's frame origin is now offset, we need to create the node highlight layers offset by the 28 negation of the frame's origin so that they still line up correctly with page content. 29 30 (-[WKInspectorHighlightView drawRect:]): 31 (-[WKInspectorHighlightView update:scale:frame:]): 32 (-[WKInspectorHighlightView _createGridOverlayLayers:scale:]): Deleted. 33 (createLayoutHatchingLayer): Deleted. 34 (createLayoutLabelLayer): Deleted. 35 (-[WKInspectorHighlightView _createGridOverlayLayer:scale:]): Deleted. 36 (-[WKInspectorHighlightView update:scale:]): Deleted. 37 * UIProcess/ios/WKContentView.mm: 38 (-[WKContentView _showInspectorHighlight:]): 39 40 1 41 2021-12-06 Lauro Moura <lmoura@igalia.com> 2 42 -
trunk/Source/WebKit/UIProcess/Inspector/ios/WKInspectorHighlightView.h
r274822 r286588 1 1 /* 2 * Copyright (C) 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2014, 2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #import <WebCore/InspectorOverlay.h> 30 30 31 namespace WebCore { 32 class FloatRect; 33 } 34 31 35 @interface WKInspectorHighlightView : UIView { 32 36 RetainPtr<NSMutableArray<CAShapeLayer *>> _layers; 33 RetainPtr<NSMutableArray<CALayer *>> _gridOverlayLayers;37 std::optional<WebCore::InspectorOverlay::Highlight> _highlight; 34 38 } 35 - (void)update:(const WebCore::InspectorOverlay::Highlight&)highlight scale:(double)scale ;39 - (void)update:(const WebCore::InspectorOverlay::Highlight&)highlight scale:(double)scale frame:(const WebCore::FloatRect&)frame; 36 40 @end 37 41 -
trunk/Source/WebKit/UIProcess/Inspector/ios/WKInspectorHighlightView.mm
r284453 r286588 1 1 /* 2 * Copyright (C) 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2014, 2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #if PLATFORM(IOS_FAMILY) 30 30 31 #import <WebCore/FloatLine.h>32 31 #import <WebCore/FloatQuad.h> 33 #import <WebCore/FontCascade.h> 34 #import <WebCore/FontCascadeDescription.h> 32 #import <WebCore/FloatRect.h> 35 33 #import <WebCore/GeometryUtilities.h> 36 #import <WebCore/ TextRun.h>34 #import <WebCore/GraphicsContextCG.h> 37 35 38 36 @implementation WKInspectorHighlightView … … 43 41 return nil; 44 42 _layers = adoptNS([[NSMutableArray alloc] init]); 45 _gridOverlayLayers = adoptNS([[NSMutableArray alloc] init]);43 self.opaque = NO; 46 44 return self; 47 45 } … … 58 56 [layer removeFromSuperlayer]; 59 57 [_layers removeAllObjects]; 60 for (CALayer *layer in _gridOverlayLayers.get())61 [layer removeFromSuperlayer];62 [_gridOverlayLayers removeAllObjects];63 58 } 64 59 … … 70 65 for (NSUInteger i = 0; i < numLayers; ++i) { 71 66 auto layer = adoptNS([[CAShapeLayer alloc] init]); 67 layer.get().position = CGPointMake(-self.frame.origin.x, -self.frame.origin.y); 72 68 [_layers addObject:layer.get()]; 73 69 [self.layer addSublayer:layer.get()]; … … 269 265 } 270 266 271 - (void)_createGridOverlayLayers:(const WebCore::InspectorOverlay::Highlight&)highlight scale:(double)scale 272 { 273 for (auto gridOverlay : highlight.gridHighlightOverlays) { 274 auto layer = [self _createGridOverlayLayer:gridOverlay scale:scale]; 275 [_gridOverlayLayers addObject:layer]; 276 [self.layer addSublayer:layer]; 277 } 278 } 279 280 static CALayer * createLayoutHatchingLayer(WebCore::FloatQuad quad, WebCore::Color strokeColor) 281 { 282 CAShapeLayer *layer = [CAShapeLayer layer]; 283 284 constexpr auto hatchSpacing = 12; 285 auto hatchPath = adoptCF(CGPathCreateMutable()); 286 287 WebCore::FloatLine topSide = { quad.p1(), quad.p2() }; 288 WebCore::FloatLine leftSide = { quad.p1(), quad.p4() }; 289 290 // The opposite axis' length is used to determine how far to draw a hatch line in both dimensions, which keeps the lines at a 45deg angle. 291 if (topSide.length() > leftSide.length()) { 292 WebCore::FloatLine bottomSide = { quad.p4(), quad.p3() }; 293 // Move across the relative top of the quad, starting left of `0, 0` to ensure that the tail of the previous hatch line is drawn while scrolling. 294 for (float x = -leftSide.length(); x < topSide.length(); x += hatchSpacing) { 295 auto startPoint = topSide.pointAtAbsoluteDistance(x); 296 auto endPoint = bottomSide.pointAtAbsoluteDistance(x + leftSide.length()); 297 CGPathMoveToPoint(hatchPath.get(), 0, startPoint.x(), startPoint.y()); 298 CGPathAddLineToPoint(hatchPath.get(), 0, endPoint.x(), endPoint.y()); 299 } 300 } else { 301 WebCore::FloatLine rightSide = { quad.p2(), quad.p3() }; 302 // Move down the relative left side of the quad, starting above `0, 0` to ensure that the tail of the previous hatch line is drawn while scrolling. 303 for (float y = -topSide.length(); y < leftSide.length(); y += hatchSpacing) { 304 auto startPoint = leftSide.pointAtAbsoluteDistance(y); 305 auto endPoint = rightSide.pointAtAbsoluteDistance(y + topSide.length()); 306 CGPathMoveToPoint(hatchPath.get(), 0, startPoint.x(), startPoint.y()); 307 CGPathAddLineToPoint(hatchPath.get(), 0, endPoint.x(), endPoint.y()); 308 } 309 } 310 layer.path = hatchPath.get(); 311 layer.strokeColor = cachedCGColor(strokeColor).get(); 312 layer.lineWidth = 0.5; 313 layer.lineDashPattern = @[[NSNumber numberWithInt:2], [NSNumber numberWithInt:2]]; 314 315 CAShapeLayer *maskLayer = [CAShapeLayer layer]; 316 layerPath(maskLayer, quad); 317 layer.mask = maskLayer; 318 return layer; 319 } 320 321 static CALayer * createLayoutLabelLayer(String label, WebCore::FloatPoint point, WebCore::InspectorOverlay::LabelArrowDirection arrowDirection, WebCore::InspectorOverlay::LabelArrowEdgePosition arrowEdgePosition, WebCore::Color backgroundColor, WebCore::Color strokeColor, double scale, float maximumWidth = 0) 322 { 323 auto font = WebCore::InspectorOverlay::fontForLayoutLabel(); 324 325 constexpr auto padding = 4; 326 constexpr auto arrowSize = 6; 327 float textHeight = font.fontMetrics().floatHeight(); 328 329 float textWidth = font.width(WebCore::TextRun(label)); 330 if (maximumWidth && textWidth + (padding * 2) > maximumWidth) { 331 label.append("..."_s); 332 while (textWidth + (padding * 2) > maximumWidth && label.length() >= 4) { 333 // Remove the fourth from last character (the character before the ellipsis) and remeasure. 334 label.remove(label.length() - 4); 335 textWidth = font.width(WebCore::TextRun(label)); 336 } 337 } 338 339 // Note: Implementation Difference - The textPosition is the center of text, unlike WebCore::InspectorOverlay, where the textPosition is leftmost point on the baseline of the text. 340 WebCore::FloatPoint textPosition; 341 switch (arrowDirection) { 342 case WebCore::InspectorOverlay::LabelArrowDirection::Down: 343 switch (arrowEdgePosition) { 344 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Leading: 345 textPosition = WebCore::FloatPoint((textWidth / 2) + padding, -(textHeight / 2) - arrowSize - padding); 346 break; 347 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Middle: 348 textPosition = WebCore::FloatPoint(0, -(textHeight / 2) - arrowSize - padding); 349 break; 350 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Trailing: 351 textPosition = WebCore::FloatPoint(-(textWidth / 2) - padding, -(textHeight / 2) - arrowSize - padding); 352 break; 353 case WebCore::InspectorOverlay::LabelArrowEdgePosition::None: 354 break; 355 } 356 break; 357 case WebCore::InspectorOverlay::LabelArrowDirection::Up: 358 switch (arrowEdgePosition) { 359 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Leading: 360 textPosition = WebCore::FloatPoint((textWidth / 2) + padding, (textHeight / 2) + arrowSize + padding); 361 break; 362 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Middle: 363 textPosition = WebCore::FloatPoint(0, (textHeight / 2) + arrowSize + padding); 364 break; 365 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Trailing: 366 textPosition = WebCore::FloatPoint(-(textWidth / 2) - padding, (textHeight / 2) + arrowSize + padding); 367 break; 368 case WebCore::InspectorOverlay::LabelArrowEdgePosition::None: 369 break; 370 } 371 break; 372 case WebCore::InspectorOverlay::LabelArrowDirection::Right: 373 switch (arrowEdgePosition) { 374 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Leading: 375 textPosition = WebCore::FloatPoint(-(textWidth / 2) - arrowSize - padding, (textHeight / 2) + padding); 376 break; 377 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Middle: 378 textPosition = WebCore::FloatPoint(-(textWidth / 2) - arrowSize - padding, 0); 379 break; 380 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Trailing: 381 textPosition = WebCore::FloatPoint(-(textWidth / 2) - arrowSize - padding, -(textHeight / 2) - padding); 382 break; 383 case WebCore::InspectorOverlay::LabelArrowEdgePosition::None: 384 break; 385 } 386 break; 387 case WebCore::InspectorOverlay::LabelArrowDirection::Left: 388 switch (arrowEdgePosition) { 389 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Leading: 390 textPosition = WebCore::FloatPoint((textWidth / 2) + arrowSize + padding, (textHeight / 2) + padding); 391 break; 392 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Middle: 393 textPosition = WebCore::FloatPoint((textWidth / 2) + arrowSize + padding, 0); 394 break; 395 case WebCore::InspectorOverlay::LabelArrowEdgePosition::Trailing: 396 textPosition = WebCore::FloatPoint((textWidth / 2) + arrowSize + padding, -(textHeight / 2) - padding); 397 break; 398 case WebCore::InspectorOverlay::LabelArrowEdgePosition::None: 399 break; 400 } 401 break; 402 case WebCore::InspectorOverlay::LabelArrowDirection::None: 403 // Text position will remain (0, 0). 404 break; 405 } 406 407 CALayer *layer = [CALayer layer]; 408 409 #if USE(CG) 410 // WebCore::Path::PlatformPathPtr is only a CGPath* when `USE(CG)` is true. 411 auto labelPath = WebCore::InspectorOverlay::backgroundPathForLayoutLabel(textWidth + (padding * 2), textHeight + (padding * 2), arrowDirection, arrowEdgePosition, arrowSize); 412 CGPath* platformLabelPath = labelPath.ensurePlatformPath(); 413 414 CAShapeLayer *labelPathLayer = [CAShapeLayer layer]; 415 labelPathLayer.path = platformLabelPath; 416 labelPathLayer.fillColor = cachedCGColor(backgroundColor).get(); 417 labelPathLayer.strokeColor = cachedCGColor(strokeColor).get(); 418 labelPathLayer.position = CGPointMake(point.x(), point.y()); 419 [layer addSublayer:labelPathLayer]; 420 #endif 421 422 CATextLayer *textLayer = [CATextLayer layer]; 423 textLayer.frame = CGRectMake(0, 0, textWidth, textHeight); 424 textLayer.string = label; 425 textLayer.font = font.primaryFont().getCTFont(); 426 textLayer.fontSize = 12; 427 textLayer.alignmentMode = kCAAlignmentLeft; 428 textLayer.foregroundColor = CGColorGetConstantColor(kCGColorBlack); 429 textLayer.position = CGPointMake(textPosition.x() + point.x(), textPosition.y() + point.y()); 430 textLayer.contentsScale = [[UIScreen mainScreen] scale] * scale; 431 [layer addSublayer:textLayer]; 432 433 return layer; 434 } 435 436 - (CALayer *)_createGridOverlayLayer:(const WebCore::InspectorOverlay::Highlight::GridHighlightOverlay&)overlay scale:(double)scale 437 { 438 // Keep implementation roughly equivalent to `WebCore::InspectorOverlay::drawGridOverlay`. 439 CALayer *layer = [CALayer layer]; 440 441 auto gridLinesPath = adoptCF(CGPathCreateMutable()); 442 for (auto gridLine : overlay.gridLines) { 443 CGPathMoveToPoint(gridLinesPath.get(), 0, gridLine.start().x(), gridLine.start().y()); 444 CGPathAddLineToPoint(gridLinesPath.get(), 0, gridLine.end().x(), gridLine.end().y()); 445 } 446 CAShapeLayer *gridLinesLayer = [CAShapeLayer layer]; 447 gridLinesLayer.path = gridLinesPath.get(); 448 gridLinesLayer.lineWidth = 1; 449 gridLinesLayer.strokeColor = cachedCGColor(overlay.color).get(); 450 [layer addSublayer:gridLinesLayer]; 451 452 for (auto gapQuad : overlay.gaps) 453 [layer addSublayer:createLayoutHatchingLayer(gapQuad, overlay.color)]; 454 455 for (auto area : overlay.areas) { 456 CAShapeLayer *areaLayer = [CAShapeLayer layer]; 457 layerPath(areaLayer, area.quad); 458 areaLayer.lineWidth = 3; 459 areaLayer.fillColor = CGColorGetConstantColor(kCGColorClear); 460 areaLayer.strokeColor = cachedCGColor(overlay.color).get(); 461 [layer addSublayer:areaLayer]; 462 } 463 464 constexpr auto translucentLabelBackgroundColor = WebCore::Color::white.colorWithAlphaByte(230); 465 466 for (auto area : overlay.areas) 467 [layer addSublayer:createLayoutLabelLayer(area.name, area.quad.center(), WebCore::InspectorOverlay::LabelArrowDirection::None, WebCore::InspectorOverlay::LabelArrowEdgePosition::None, translucentLabelBackgroundColor, overlay.color, scale, area.quad.boundingBox().width())]; 468 469 for (auto label : overlay.labels) 470 [layer addSublayer:createLayoutLabelLayer(label.text, label.location, label.arrowDirection, label.arrowEdgePosition, label.backgroundColor, overlay.color, scale)]; 471 472 return layer; 473 } 474 475 - (void)update:(const WebCore::InspectorOverlay::Highlight&)highlight scale:(double)scale 267 - (void)drawRect:(CGRect)dirtyRect 268 { 269 [super drawRect:dirtyRect]; 270 271 if (!_highlight) 272 return; 273 274 auto context = WebCore::GraphicsContextCG(UIGraphicsGetCurrentContext()); 275 context.clip({ dirtyRect }); 276 context.translate(-self.frame.origin.x, -self.frame.origin.y); 277 278 for (auto gridHighlightOverlay : _highlight->gridHighlightOverlays) 279 WebCore::InspectorOverlay::drawGridOverlay(context, gridHighlightOverlay); 280 } 281 282 - (void)update:(const WebCore::InspectorOverlay::Highlight&)highlight scale:(double)scale frame:(const WebCore::FloatRect&)frame 476 283 { 477 284 [self _removeAllLayers]; 285 286 _highlight = highlight; 287 self.contentScaleFactor = UIScreen.mainScreen.scale * scale; 288 self.frame = frame; 478 289 479 290 if (highlight.type == WebCore::InspectorOverlay::Highlight::Type::Node || highlight.type == WebCore::InspectorOverlay::Highlight::Type::NodeList) … … 482 293 [self _layoutForRectsHighlight:highlight]; 483 294 484 [self _createGridOverlayLayers:highlight scale:scale]; 295 296 [self setNeedsDisplay]; 485 297 } 486 298 -
trunk/Source/WebKit/UIProcess/ios/WKContentView.mm
r286552 r286588 413 413 [self insertSubview:_inspectorHighlightView.get() aboveSubview:_rootContentView.get()]; 414 414 } 415 416 [_inspectorHighlightView update:highlight scale:[self _contentZoomScale]]; 415 [_inspectorHighlightView update:highlight scale:[self _contentZoomScale] frame:_page->unobscuredContentRect()]; 417 416 } 418 417
Note:
See TracChangeset
for help on using the changeset viewer.