Implemented CGPathApply.#559
Conversation
|
Hi @adein, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution! The agreement was validated by Microsoft and real humans are currently evaluating your PR. TTYL, MSBOT; |
|
@bdrlamb-ms is added to the review. #Closed |
|
Are there tests for these apis that need to be part of this pull request? #Closed |
|
@rajsesh-msft Are you requesting that unit tests be added to the pull request, or for details on how we tested the changes? We tested the changes using a sample project; we have not created unit tests in the bridge. |
|
@adein, yes please. If you added a sample to woccatalog, please include that as well. the idea is to make sure we have test collateral to guard against any future regressions. |
|
|
||
| __CGPath::~__CGPath() { | ||
| if (_components) { | ||
| for (unsigned i = 0; i < _count; i++) { |
There was a problem hiding this comment.
nit: please use spaces instead of tabs to match the rest of the codebase. To that end, we have setup clang-format for the project and ask that all PRs have it run prior to submission so that we can avoid silly formatting comments like this. :-)
|
@jeffMeador could you please rebase the branch and push again? |
|
@rajsesh-msft This branch now contains the test project & unit tests for CGPathApply. The unit tests are in tests/unittests/CoreGraphics/CGPathTests.mm |
|
Could you pull latest changes from github/master your branch, do a git -rebase and resubmit the pull request? The way it stands now, the PR shows 188 changed files and is hard to go through. |
| void cgPathModifyingApplierFunction(void* info, const CGPathElement* element) { | ||
| int pointCount = cgPathPointCountForElementType(element->type); | ||
|
|
||
| NSMutableArray* points = [NSMutableArray array]; |
There was a problem hiding this comment.
element->points? otherwise this seems unused...
There was a problem hiding this comment.
Are you referring to the points NSMutableArray not being used? It's not used, I can remove it. cgPathModifyingApplierFunction just exists to show that paths cannot be manipulated in an applier function.
df76d05 to
a1e40a3
Compare
|
@rajsesh-msft This branch has been properly rebased and now only shows the 5 files that have been edited. |
|
Thanks a bunch, this is a lot easier to look at. In reply to: 228855101 [](ancestors = 228855101) |
| if (path == NULL) { | ||
| return; | ||
| } | ||
|
|
There was a problem hiding this comment.
Nit: it looks like CGPathApply is the only one that is doing the null check. fail fast (by not checking NULL) will make it consistent.
|
It would help to add some comments about the math in all the new methods. In reply to: 228855305 [](ancestors = 228855305,228855101) |
|
🕐 |
|
|
||
| dx0 = x0 - x1; | ||
| dy0 = y0 - y1; | ||
| xl0 = sqrt(dx0 * dx0 + dy0 * dy0); |
There was a problem hiding this comment.
Would be nice to use more descriptive names across the board here. dx0 could be deltaX0 and x10 could be distance10. I know its common to be extra terse in general math but more descriptive names aids the casual reader in remembering what the components all are when the code is longer than a single screen etc.
There was a problem hiding this comment.
Actually would be nice to make dx0 deltaX10. I was confused why there was no dx1 / dy1 but that is because a single point was chosen for the deltas.
In reply to: 68683240 [](ancestors = 68683240)
Replaced pathComponent with CGPathElement. Rewrote CGPathAddEllipseInRect, CGPathAddArc, CGPathAddArcToPoint to support CGPathElement. Implemented CGPathGetCurrentPoint for use in CGPathAddArcToPoint. Removed caveats for CGPathAddArc, CGPathAddEllipseInRect. Caveat for CGPathAddArcToPoint remains.
Used Visual Studio ClangFormat plugin to format CGPath.mm, CGPath.h, and CGPathInternal.h.
Switched text editor setting to use spaces instead of tabs. Re-ran ClangFormat on CGPath.mm CGPathInternal.h and CGPath.h.
Ran untabify and re-ran ClangFormat on CGPath.mm, CGPathInternal.h and CGPath.h.
Added CGPathApply unit tests. Added a test to ensure paths cannot be manipulated in the applier function and multiple tests for creating different types of paths and checking the resulting elements. Multiple bug fixes in CGPath. Re-ran formatter on all files.
Removed unused array in cgPathModifyingApplierFunction.
CGPathApply no longer prevents the maniuplation of points. Added _CGPathAddElement utility function to handle increasing size of elements array and creating point arrays. Point arrays are all now the max size, 3 points. Point arrays are copied in CGPathCreateMutableCopy to new path. CGPathEqualToPath implemented so path copies could be tested. Comments have been added for new math. CGPathAddArcToPoint marked as a todo as it needs to be refactored here, CGContextImpl::CGContextAddArcToPoint and CGContextCairo::CGContextAddArcToPoint. Fixed implementation of CGPathCreateWithEllipseInRect. Added points copy in CGPathAddPath and added unit test for CGPathAddPath.
0745299 to
184e31f
Compare
|
@rajsesh-msft everything we discussed should be addressed in 184e31f . |
| path->_elements = (CGPathElement*)IwRealloc(path->_elements, path->_max * sizeof(CGPathElement)); | ||
| } | ||
| CGPathElement* element = &path->_elements[path->_count]; | ||
| element->points = (CGPoint*)IwCalloc(kCGPathMaxPointCount, sizeof(CGPoint)); |
There was a problem hiding this comment.
This is not what i meant. We are still allocating memory every time a path element is added. perhaps i misunderstood your earlier question. Do you want to chat over the phone so we can get on the same page here? I really want to avoid duplicate allocations for points every time an item is added to the path. Allocating a fixed number of points without doing it once isn't really buying us anything. #Closed
CGPath now uses CGPathElementInternal when creating an array of elements. CGPathElementInternal holds a fixed sized array big enough for the maximum number of points in an element. CGPathElementInternal inherits from CGPathElement and adjusts the points pointer to point at its internal points array as much as possible. Calls to updatePointsArrayPointer() need to be done manually when allocating CGPathElementInternal arrays dynamically or using memcpy.
Added call to base struct constructor in CGPathElementInternal
|
@rajsesh-msft CGPath has been updated to use CGPathElementInternal and just have 1 allocation for an array of elements instead of an allocation for an array of elements & for each array of points. |
| CGPathElementInternal* element = &path->_elements[path->_count]; | ||
| // The new elements needs its points array pointer updated | ||
| // because it was created with alloc | ||
| element->updatePointsArrayPointer(); |
There was a problem hiding this comment.
nit: from a OO standpoint, i would call this function init() (caller doesn't need to know internal details of what this function does). There is alternately, no need for this function, you can call placement new on the memory location like this: CGPathElementInternal* element = new (&path->_elements[path->_count]) CGPathElementInternal(); clearly, this doesnt work for the mutable copy scenario below. so it is okay to leave as is.
|
Added a few minor comments to the new changes. In reply to: 229352074 [](ancestors = 229352074) |
Switched to point references in CGPathEqualToPath and element references in CGPathAddPath to avoid copying. Renamed CGPathElementInternal.updatePointsArrayPointer() to CGPathElementInternal.init()
|
The changes requested have been committed. |
|
In CI build. validated internal apps manually and they look good so far. |
|
CI build passed. |
Replaced pathComponent with CGPathElement. Rewrote CGPathAddEllipseInRect,
CGPathAddArc, CGPathAddArcToPoint to support CGPathElement.
Implemented CGPathGetCurrentPoint for use in CGPathAddArcToPoint.
Removed caveats for CGPathAddArc, CGPathAddEllipseInRect.
Caveat for CGPathAddArcToPoint remains.
Fix #525 : CGPathApply.