Bug 169273 - Implement stroke-width CSS property.
Summary: Implement stroke-width CSS property.
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Per Arne Vollan
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2017-03-07 05:03 PST by Per Arne Vollan
Modified: 2018-03-15 09:48 PDT (History)
6 users (show)

See Also:


Attachments
Patch (11.02 KB, patch)
2017-03-07 05:14 PST, Per Arne Vollan
no flags Details | Formatted Diff | Diff
Patch (15.92 KB, patch)
2017-03-07 06:44 PST, Per Arne Vollan
no flags Details | Formatted Diff | Diff
Patch (14.80 KB, patch)
2017-03-07 07:57 PST, Per Arne Vollan
no flags Details | Formatted Diff | Diff
Patch (14.92 KB, patch)
2017-03-07 09:00 PST, Per Arne Vollan
no flags Details | Formatted Diff | Diff
Patch (16.35 KB, patch)
2017-03-08 01:29 PST, Per Arne Vollan
simon.fraser: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Per Arne Vollan 2017-03-07 05:03:17 PST
Implement stroke-width, see https://drafts.fxtf.org/paint/.
Comment 1 Per Arne Vollan 2017-03-07 05:14:50 PST
Created attachment 303645 [details]
Patch
Comment 2 WebKit Commit Bot 2017-03-07 05:42:32 PST
Attachment 303645 [details] did not pass style-queue:


ERROR: Source/WebCore/ChangeLog:8:  You should remove the 'No new tests' and either add and list tests, or explain why no new tests were possible.  [changelog/nonewtests] [5]
Total errors found: 1 in 9 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 3 Per Arne Vollan 2017-03-07 06:44:02 PST
Created attachment 303649 [details]
Patch
Comment 4 Per Arne Vollan 2017-03-07 07:57:15 PST
Created attachment 303652 [details]
Patch
Comment 5 Per Arne Vollan 2017-03-07 09:00:53 PST
Created attachment 303660 [details]
Patch
Comment 6 Per Arne Vollan 2017-03-07 09:02:28 PST
rdar://problem/30754819
Comment 7 Brent Fulgham 2017-03-07 09:30:11 PST
Comment on attachment 303660 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=303660&action=review

I think Simon should do the full review of this, but it seems reasonable.

I do think that "textStrokeWidht()" might be able to encapsulate the "explicitly set stroke width" case, at least from the examples in this patch. Perhaps there are bigger picture issues that make it better to handle the two cases separately, but it seems like a lot of duplicated checks in multiple places.

> Source/WebCore/rendering/InlineFlowBox.cpp:172
> +            if (childStyle->letterSpacing() < 0 || childStyle->textShadow() || childStyle->textEmphasisMark() != TextEmphasisMarkNone || childStyle->textStrokeWidth() || (childStyle->hasExplicitlySetStrokeWidth() && childStyle->strokeWidth().value()))

You and Simon have probably already hashed all of this out, but reading this code makes me wonder why "childStyle->textStrokeWidth()" couldn't handle the explicit stroke width case internally. I guess there might be cases where we want the textStrokeWidth even if we have an explicitly set stroke width?

> Source/WebCore/rendering/InlineFlowBox.cpp:908
> +    int strokeOverflow = static_cast<int>(ceilf(lineStyle.computedTextStrokeWidth(viewport) / 2.0f));

I think this should be "std::ceil" so it will shift type if we ever modify lineStyle's return types.
Comment 8 Simon Fraser (smfr) 2017-03-07 13:59:53 PST
Comment on attachment 303660 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=303660&action=review

>> Source/WebCore/rendering/InlineFlowBox.cpp:172
>> +            if (childStyle->letterSpacing() < 0 || childStyle->textShadow() || childStyle->textEmphasisMark() != TextEmphasisMarkNone || childStyle->textStrokeWidth() || (childStyle->hasExplicitlySetStrokeWidth() && childStyle->strokeWidth().value()))
> 
> You and Simon have probably already hashed all of this out, but reading this code makes me wonder why "childStyle->textStrokeWidth()" couldn't handle the explicit stroke width case internally. I guess there might be cases where we want the textStrokeWidth even if we have an explicitly set stroke width?

I don't know why we need hasExplicitlySetStrokeWidth() and the changelog is sorely lacking in explanation.

>> Source/WebCore/rendering/InlineFlowBox.cpp:908
>> +    int strokeOverflow = static_cast<int>(ceilf(lineStyle.computedTextStrokeWidth(viewport) / 2.0f));
> 
> I think this should be "std::ceil" so it will shift type if we ever modify lineStyle's return types.

Just adding half stroke width here seems naive, and doesn't take into account miters.

> Source/WebCore/rendering/style/RenderStyle.h:1920
> +        unsigned hasSetStrokeWidth : 1;

I don't think this should be here; it should be in StyleRareInheritedData.
Comment 9 Per Arne Vollan 2017-03-08 01:29:00 PST
Created attachment 303797 [details]
Patch
Comment 10 Per Arne Vollan 2017-03-08 06:20:54 PST
(In reply to comment #8)
> Comment on attachment 303660 [details]
> Patch
> 

Thanks for reviewing!

> View in context:
> https://bugs.webkit.org/attachment.cgi?id=303660&action=review
> 
> >> Source/WebCore/rendering/InlineFlowBox.cpp:172
> >> +            if (childStyle->letterSpacing() < 0 || childStyle->textShadow() || childStyle->textEmphasisMark() != TextEmphasisMarkNone || childStyle->textStrokeWidth() || (childStyle->hasExplicitlySetStrokeWidth() && childStyle->strokeWidth().value()))
> > 
> > You and Simon have probably already hashed all of this out, but reading this code makes me wonder why "childStyle->textStrokeWidth()" couldn't handle the explicit stroke width case internally. I guess there might be cases where we want the textStrokeWidth even if we have an explicitly set stroke width?
> 

Added a new member to simplify this in the last patch.

> I don't know why we need hasExplicitlySetStrokeWidth() and the changelog is
> sorely lacking in explanation.
> 

I added hasExplicitlySetStrokeWidth() to fall back to the -webkit-text-stroke-width value when stroke-width is not set, to make sure the -webkit-text-stroke-width property still works.

Currently, a float member is holding the value of the -webkit-text-stroke-width value, and a Length member is holding the value of the stroke-width property. Would a better solution be to let both properties use the same Length member?

> >> Source/WebCore/rendering/InlineFlowBox.cpp:908
> >> +    int strokeOverflow = static_cast<int>(ceilf(lineStyle.computedTextStrokeWidth(viewport) / 2.0f));
> > 
> > I think this should be "std::ceil" so it will shift type if we ever modify lineStyle's return types.
> 

Fixed.

> Just adding half stroke width here seems naive, and doesn't take into
> account miters.
> 

Do you think we should involve the stroke-miterlimit property here  (https://bugs.webkit.org/show_bug.cgi?id=169078)?
Comment 11 Simon Fraser (smfr) 2017-03-08 11:45:34 PST
Comment on attachment 303797 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=303797&action=review

r+ but please check SVG rendering.

> Source/WebCore/rendering/style/RenderStyle.cpp:2267
> +        ExceptionOr<float> result = length.value() * (viewportSize.width() + viewportSize.height()) / 200.0f;

Please add a comment here referencing the "Percentages: relative to the scaled viewport size, scaled viewport size is the geometric mean of the viewport width and height" part of the spec, otherwise this code is really confusing to see.

Does this code work when stroke-width is used inside SVG?

> Source/WebCore/rendering/style/StyleRareInheritedData.h:143
> +    Length strokeWidth;    
> +    unsigned hasSetStrokeWidth : 1;

You may get better packing by putting the bitfield before the Length
Comment 12 Per Arne Vollan 2017-03-09 01:41:06 PST
(In reply to comment #11)
> Comment on attachment 303797 [details]
> Patch
> 

Thanks for reviewing :)

> View in context:
> https://bugs.webkit.org/attachment.cgi?id=303797&action=review
> 
> r+ but please check SVG rendering.
> 

A quick test shows that rendering is correct when using stroke-width in SVG.


> > Source/WebCore/rendering/style/RenderStyle.cpp:2267
> > +        ExceptionOr<float> result = length.value() * (viewportSize.width() + viewportSize.height()) / 200.0f;
> 
> Please add a comment here referencing the "Percentages: relative to the
> scaled viewport size, scaled viewport size is the geometric mean of the
> viewport width and height" part of the spec, otherwise this code is really
> confusing to see.
> 
> Does this code work when stroke-width is used inside SVG?

I believe this code path is not used by SVG.
Comment 13 Per Arne Vollan 2017-03-09 01:52:36 PST
Committed <https://trac.webkit.org/changeset/213634>.
Comment 14 Jon Lee 2017-03-09 10:06:31 PST
Per, could you add tests that show expected fallback behavior between stroke-width and -webkit-text-stroke-width?
Comment 15 Per Arne Vollan 2017-03-09 12:11:06 PST
(In reply to comment #14)
> Per, could you add tests that show expected fallback behavior between
> stroke-width and -webkit-text-stroke-width?

Yes :)
Comment 16 Myles C. Maxfield 2018-03-14 13:38:24 PDT
Comment on attachment 303797 [details]
Patch

I don't see anywhere where you inflate repaint rects to account of stroke-widths. Is this not a problem?
Comment 17 Per Arne Vollan 2018-03-15 09:48:59 PDT
(In reply to Myles C. Maxfield from comment #16)
> Comment on attachment 303797 [details]
> Patch
> 
> I don't see anywhere where you inflate repaint rects to account of
> stroke-widths. Is this not a problem?

I am not aware of any problems related to that. I might be mistaken, but I think this is handled by the computation of the 'strokeOverflow' variable in the patch.