{"action":"created","comment":{"url":"https://api.github.com/repos/Microsoft/WinObjC/pulls/comments/101130600","pull_request_review_id":21851278,"id":101130600,"diff_hunk":"@@ -1913,71 +1943,155 @@ void CGContextSetPatternPhase(CGContextRef context, CGSize phase) {\n     // Undo assumed inversion about Y axis\n     CGAffineTransform textTransform = CGAffineTransformScale(textMatrix, 1.0, -1.0);\n     CGAffineTransform deviceTransform = CGContextGetUserSpaceToDeviceSpaceTransform(this);\n+    CGAffineTransform combinedTransform = CGAffineTransformConcat(textTransform, deviceTransform);\n \n     // Snap the vertical baseline to the nearest pixel to avoid blurring on devices with vertical antialiasing\n     textTransform.ty = std::round(textTransform.ty);\n \n-    CGAffineTransform finalTextTransform = CGAffineTransformConcat(textTransform, deviceTransform);\n-    if ((fabs(finalTextTransform.a * glyphRun->fontEmSize) <= c_glyphThreshold &&\n-         fabs(finalTextTransform.b * glyphRun->fontEmSize) <= c_glyphThreshold) ||\n-        (fabs(finalTextTransform.d * glyphRun->fontEmSize) <= c_glyphThreshold &&\n-         fabs(finalTextTransform.c * glyphRun->fontEmSize) <= c_glyphThreshold)) {\n-        TraceWarning(TAG, L\"Glyphs too small to be rendered\");\n-\n-        // Not a failure state! Not drawing the glyphs is *okay*.\n-        return S_FALSE;\n+    bool fastPathTextDrawing =\n+        ((textTransform.a == 1.0f && fabs(textTransform.d) == 1.0f && textTransform.b == 0.0f && textTransform.c == 0.0f) ||\n+         !transformByGlyph) &&\n+        state.textDrawingMode == kCGTextFill;\n+\n+    std::vector<GlyphRunData> runs;\n+\n+    size_t maxGlyphCount = std::max_element(glyphRuns, glyphRuns + runsCount, [](const GlyphRunData& left, const GlyphRunData& right) {\n+                               return left.run->glyphCount < right.run->glyphCount;\n+                           })->run->glyphCount;\n+\n+    // Shared between transformed glyph runs\n+    std::unique_ptr<CGFloat[]> zeroAdvances(new CGFloat[maxGlyphCount]());\n+\n+    for (size_t i = 0; i < runsCount; ++i) {\n+        auto& run = glyphRuns[i].run;\n+        if ((fabs(combinedTransform.a * run->fontEmSize) <= c_glyphThreshold &&\n+             fabs(combinedTransform.b * run->fontEmSize) <= c_glyphThreshold) ||\n+            (fabs(combinedTransform.d * run->fontEmSize) <= c_glyphThreshold &&\n+             fabs(combinedTransform.c * run->fontEmSize) <= c_glyphThreshold)) {\n+            // Not a failure state! Not drawing the glyphs is *okay*.\n+            TraceWarning(TAG, L\"Glyphs too small to be rendered\");\n+        } else {\n+            if (fastPathTextDrawing) {\n+                runs.emplace_back(glyphRuns[i]);\n+            } else {\n+                // Get the linear transformation that is the inverse of the text transform\n+                // We transform the positions of each glyph by the inverse so they will be positioned correctly\n+                // While still being transformed per glyph by the text transformation\n+                CGAffineTransform invertedTextTransformation = CGAffineTransformInvert(\n+                    CGAffineTransformScale(CGAffineTransformMake(textTransform.a, textTransform.b, textTransform.c, textTransform.d, 0, 0),\n+                                           1,\n+                                           -1));\n+\n+                DWRITE_GLYPH_OFFSET* positions = new DWRITE_GLYPH_OFFSET[run->glyphCount];\n+                // First glyph's origin is at the given relative position for the glyph run\n+                CGPoint runningPosition{ glyphRuns[i].relativePosition.x, std::round(glyphRuns[i].relativePosition.y) };\n+                for (size_t j = 0; j < run->glyphCount; ++j) {\n+                    // Invert position by text transformation\n+                    CGPoint transformedPosition = CGPointApplyAffineTransform(runningPosition, invertedTextTransformation);\n+\n+                    // Set current glyph's position to be the actual position transformed by the inverted text position\n+                    // So when the space is transformed by the text position it will be drawn in the correct real position\n+                    positions[j] = DWRITE_GLYPH_OFFSET{ transformedPosition.x + run->glyphOffsets[j].advanceOffset,\n+                                                        std::round(transformedPosition.y + run->glyphOffsets[j].ascenderOffset) };\n+\n+                    // Translate position of next glyph by current glyph's advance\n+                    runningPosition.x += run->glyphAdvances[j];\n+                }\n+\n+                DWRITE_GLYPH_RUN* transformedGlyphRun =\n+                    new DWRITE_GLYPH_RUN{ run->fontFace,      run->fontEmSize, run->glyphCount, run->glyphIndices,\n+                                          zeroAdvances.get(), positions,       run->isSideways, run->bidiLevel };\n+                runs.emplace_back(GlyphRunData{ transformedGlyphRun, CGPointZero, glyphRuns[i].attributes });\n+            }\n+        }\n     }\n \n-    auto& state = CurrentGState();\n+    // Iterate through every glyph by incrementing pointer in glyphIndices array\n+    ComPtr<ID2D1TransformedGeometry> transformedGeometry;\n+    if (state.textDrawingMode & kCGTextStrokeClip) {\n+        ComPtr<ID2D1PathGeometry> pathGeometry;\n+        RETURN_IF_FAILED(Factory()->CreatePathGeometry(&pathGeometry));\n+        ComPtr<ID2D1GeometrySink> sink;\n+        RETURN_IF_FAILED(pathGeometry->Open(&sink));\n+        for (auto& runData : runs) {\n+            RETURN_IF_FAILED(runData.run->fontFace->GetGlyphRunOutline(runData.run->fontEmSize,\n+                                                                       (runData.run->glyphIndices),\n+                                                                       runData.run->glyphAdvances,\n+                                                                       runData.run->glyphOffsets,\n+                                                                       runData.run->glyphCount,\n+                                                                       runData.run->isSideways,\n+                                                                       ((runData.run->bidiLevel & 1) == 1),\n+                                                                       sink.Get()));\n+        }\n+        RETURN_IF_FAILED(sink->Close());\n \n-    // If text is only flipped vertically, we can draw it all at once rather than glyph by glyph\n-    if ((textTransform.a == 1.0f && fabs(textTransform.d) == 1.0f && textTransform.b == 0.0f && textTransform.c == 0.0f) ||\n-        !transformByGlyph) {\n-        RETURN_IF_FAILED(\n-            Draw(_kCGCoordinateModeUserSpace, &textTransform, [&state, glyphRun](CGContextRef context, ID2D1DeviceContext* deviceContext) {\n-                deviceContext->DrawGlyphRun(D2D1::Point2F(0, 0), glyphRun, state.fillBrush.Get(), DWRITE_MEASURING_MODE_NATURAL);\n-                return S_OK;\n-            }));\n-    } else {\n-        // Using device space here gives us finer-grained control over the transform.\n+        // Transform the geometry by the final transformation to be stroked/clipped correctly\n         RETURN_IF_FAILED(\n-            Draw(_kCGCoordinateModeDeviceSpace,\n-                 nullptr,\n-                 [&state, &glyphRun, &deviceTransform, &textTransform](CGContextRef context, ID2D1DeviceContext* deviceContext) {\n-                     CGAffineTransform runningGlobalTransform = deviceTransform;\n-                     // Text scaling and rotation apply to each glyph relative to its origin, so we must draw each glyph\n-                     // transformed\n-                     // independently\n-                     DWRITE_GLYPH_RUN individualGlyphRun{ glyphRun->fontFace,\n-                                                          glyphRun->fontEmSize,\n-                                                          1, // Since this is glyph by glyph, glyphCount is one\n-                                                          glyphRun->glyphIndices,\n-                                                          nullptr,\n-                                                          nullptr,\n-                                                          glyphRun->isSideways,\n-                                                          glyphRun->bidiLevel };\n-                     D2D1_POINT_2F origin{ 0, 0 };\n-                     // Iterate through every glyph by incrementing pointer in glyphIndices array\n-                     for (uint32_t i = 0; i < glyphRun->glyphCount; ++i, ++(individualGlyphRun.glyphIndices)) {\n-                         CGAffineTransform finalTextTransform = CGAffineTransformConcat(textTransform, runningGlobalTransform);\n-                         deviceContext->SetTransform(__CGAffineTransformToD2D_F(finalTextTransform));\n-                         deviceContext->DrawGlyphRun(origin, &individualGlyphRun, state.fillBrush.Get(), DWRITE_MEASURING_MODE_NATURAL);\n-\n-                         // Uses glyphAdvances to move each glyph\n-                         runningGlobalTransform = CGAffineTransformTranslate(runningGlobalTransform, glyphRun->glyphAdvances[i], 0);\n-                     }\n-                     return S_OK;\n-                 }));\n+            Factory()->CreateTransformedGeometry(pathGeometry.Get(), __CGAffineTransformToD2D_F(combinedTransform), &transformedGeometry));\n+    }\n+\n+    HRESULT ret = Draw(_kCGCoordinateModeDeviceSpace, nullptr, [&](CGContextRef context, ID2D1DeviceContext* deviceContext) {\n+        if (state.textDrawingMode & kCGTextFill) {\n+            deviceContext->SetTransform(__CGAffineTransformToD2D_F(combinedTransform));\n+            D2D1_POINT_2F origin{ 0, 0 };\n+            for (auto& runData : runs) {\n+                if (runData.attributes) {\n+                    CGColorRef fontColor = (CGColorRef)CFDictionaryGetValue(runData.attributes, _kCGForegroundColorAttributeName);\n+                    if (fontColor) {\n+                        CGContextSetFillColorWithColor(context, fontColor);","path":"Frameworks/CoreGraphics/CGContext.mm","position":208,"original_position":208,"commit_id":"9036cc3ddf4805d47e1ad99290c8628ee317f118","original_commit_id":"9036cc3ddf4805d47e1ad99290c8628ee317f118","user":{"login":"aballway","id":7557395,"avatar_url":"https://avatars.githubusercontent.com/u/7557395?v=3","gravatar_id":"","url":"https://api.github.com/users/aballway","html_url":"https://github.com/aballway","followers_url":"https://api.github.com/users/aballway/followers","following_url":"https://api.github.com/users/aballway/following{/other_user}","gists_url":"https://api.github.com/users/aballway/gists{/gist_id}","starred_url":"https://api.github.com/users/aballway/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aballway/subscriptions","organizations_url":"https://api.github.com/users/aballway/orgs","repos_url":"https://api.github.com/users/aballway/repos","events_url":"https://api.github.com/users/aballway/events{/privacy}","received_events_url":"https://api.github.com/users/aballway/received_events","type":"User","site_admin":false},"body":"Our current implementation has it modifying the global state","created_at":"2017-02-14T20:07:50Z","updated_at":"2017-02-14T20:07:50Z","html_url":"https://github.com/Microsoft/WinObjC/pull/1933#discussion_r101130600","pull_request_url":"https://api.github.com/repos/Microsoft/WinObjC/pulls/1933","_links":{"self":{"href":"https://api.github.com/repos/Microsoft/WinObjC/pulls/comments/101130600"},"html":{"href":"https://github.com/Microsoft/WinObjC/pull/1933#discussion_r101130600"},"pull_request":{"href":"https://api.github.com/repos/Microsoft/WinObjC/pulls/1933"}}},"pull_request":{"url":"https://api.github.com/repos/Microsoft/WinObjC/pulls/1933","id":105316111,"html_url":"https://github.com/Microsoft/WinObjC/pull/1933","diff_url":"https://github.com/Microsoft/WinObjC/pull/1933.diff","patch_url":"https://github.com/Microsoft/WinObjC/pull/1933.patch","issue_url":"https://api.github.com/repos/Microsoft/WinObjC/issues/1933","number":1933,"state":"open","locked":false,"title":"Add support for all CGTextDrawingModes","user":{"login":"aballway","id":7557395,"avatar_url":"https://avatars.githubusercontent.com/u/7557395?v=3","gravatar_id":"","url":"https://api.github.com/users/aballway","html_url":"https://github.com/aballway","followers_url":"https://api.github.com/users/aballway/followers","following_url":"https://api.github.com/users/aballway/following{/other_user}","gists_url":"https://api.github.com/users/aballway/gists{/gist_id}","starred_url":"https://api.github.com/users/aballway/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aballway/subscriptions","organizations_url":"https://api.github.com/users/aballway/orgs","repos_url":"https://api.github.com/users/aballway/repos","events_url":"https://api.github.com/users/aballway/events{/privacy}","received_events_url":"https://api.github.com/users/aballway/received_events","type":"User","site_admin":false},"body":"Several changes have been added to address #1933 and #1935 \r\n\r\nCGContextDrawGlyphRun has been changed to _CGContextDrawGlyphRuns and __CGContext::DrawGlyphRun -> __CGContext::DrawGlyphsRuns, which takes a dummy struct GlyphRunData, which holds the DWRITE_GLYPH_RUN, relative position of the glyph run (to the text position), and attributes of the glyph run (fill color, etc.).\r\n\r\nText drawing methods such as CTFrameDraw now accumulate an array of GlyphRunDatas and pass them to _CGContextDrawGlyphRuns, which in turn calls context->DrawGlyphRuns.\r\n\r\nTo batch all run drawing for clipping/stroking into the same geometry, the runs have to be drawn with the same transformation, so position has to be given (hence relative position in GlyphRunData).  The position is transformed by the inverse of the text transform, so when the glyph is drawn and transformed by the real text transform it will have the correct position.  This has the added benefit of allowing us to draw a glyph run which has a transformed text matrix all together, rather than glyph-by-glyph as we did previously.\r\n\r\nBecause text drawing is being batched, attributes which are handled at draw time on a run-per-run basis such as fill color need to be done in DrawGlyphRuns.  The attribute names are defined in CoreText, though all of them are just CoreGraphics attributes, so local values have been added to CGContext.mm rather than making an internal version and defining the CT/UIKit versions as CG.\r\n\r\nImages have been updates since changing this seems to have enabled antialiasing to some degree on several tests. \r\n\r\nFixes #1933 \r\nFixes #1935","created_at":"2017-02-08T22:07:44Z","updated_at":"2017-02-14T20:07:50Z","closed_at":null,"merged_at":null,"merge_commit_sha":"de6cfc187e13965eb0b0af504bcb88392453d79d","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/Microsoft/WinObjC/pulls/1933/commits","review_comments_url":"https://api.github.com/repos/Microsoft/WinObjC/pulls/1933/comments","review_comment_url":"https://api.github.com/repos/Microsoft/WinObjC/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Microsoft/WinObjC/issues/1933/comments","statuses_url":"https://api.github.com/repos/Microsoft/WinObjC/statuses/9036cc3ddf4805d47e1ad99290c8628ee317f118","head":{"label":"aballway:ct","ref":"ct","sha":"9036cc3ddf4805d47e1ad99290c8628ee317f118","user":{"login":"aballway","id":7557395,"avatar_url":"https://avatars.githubusercontent.com/u/7557395?v=3","gravatar_id":"","url":"https://api.github.com/users/aballway","html_url":"https://github.com/aballway","followers_url":"https://api.github.com/users/aballway/followers","following_url":"https://api.github.com/users/aballway/following{/other_user}","gists_url":"https://api.github.com/users/aballway/gists{/gist_id}","starred_url":"https://api.github.com/users/aballway/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aballway/subscriptions","organizations_url":"https://api.github.com/users/aballway/orgs","repos_url":"https://api.github.com/users/aballway/repos","events_url":"https://api.github.com/users/aballway/events{/privacy}","received_events_url":"https://api.github.com/users/aballway/received_events","type":"User","site_admin":false},"repo":{"id":62087158,"name":"WinObjC","full_name":"aballway/WinObjC","owner":{"login":"aballway","id":7557395,"avatar_url":"https://avatars.githubusercontent.com/u/7557395?v=3","gravatar_id":"","url":"https://api.github.com/users/aballway","html_url":"https://github.com/aballway","followers_url":"https://api.github.com/users/aballway/followers","following_url":"https://api.github.com/users/aballway/following{/other_user}","gists_url":"https://api.github.com/users/aballway/gists{/gist_id}","starred_url":"https://api.github.com/users/aballway/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aballway/subscriptions","organizations_url":"https://api.github.com/users/aballway/orgs","repos_url":"https://api.github.com/users/aballway/repos","events_url":"https://api.github.com/users/aballway/events{/privacy}","received_events_url":"https://api.github.com/users/aballway/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/aballway/WinObjC","description":"Objective-C for Windows","fork":true,"url":"https://api.github.com/repos/aballway/WinObjC","forks_url":"https://api.github.com/repos/aballway/WinObjC/forks","keys_url":"https://api.github.com/repos/aballway/WinObjC/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aballway/WinObjC/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aballway/WinObjC/teams","hooks_url":"https://api.github.com/repos/aballway/WinObjC/hooks","issue_events_url":"https://api.github.com/repos/aballway/WinObjC/issues/events{/number}","events_url":"https://api.github.com/repos/aballway/WinObjC/events","assignees_url":"https://api.github.com/repos/aballway/WinObjC/assignees{/user}","branches_url":"https://api.github.com/repos/aballway/WinObjC/branches{/branch}","tags_url":"https://api.github.com/repos/aballway/WinObjC/tags","blobs_url":"https://api.github.com/repos/aballway/WinObjC/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aballway/WinObjC/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aballway/WinObjC/git/refs{/sha}","trees_url":"https://api.github.com/repos/aballway/WinObjC/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aballway/WinObjC/statuses/{sha}","languages_url":"https://api.github.com/repos/aballway/WinObjC/languages","stargazers_url":"https://api.github.com/repos/aballway/WinObjC/stargazers","contributors_url":"https://api.github.com/repos/aballway/WinObjC/contributors","subscribers_url":"https://api.github.com/repos/aballway/WinObjC/subscribers","subscription_url":"https://api.github.com/repos/aballway/WinObjC/subscription","commits_url":"https://api.github.com/repos/aballway/WinObjC/commits{/sha}","git_commits_url":"https://api.github.com/repos/aballway/WinObjC/git/commits{/sha}","comments_url":"https://api.github.com/repos/aballway/WinObjC/comments{/number}","issue_comment_url":"https://api.github.com/repos/aballway/WinObjC/issues/comments{/number}","contents_url":"https://api.github.com/repos/aballway/WinObjC/contents/{+path}","compare_url":"https://api.github.com/repos/aballway/WinObjC/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aballway/WinObjC/merges","archive_url":"https://api.github.com/repos/aballway/WinObjC/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aballway/WinObjC/downloads","issues_url":"https://api.github.com/repos/aballway/WinObjC/issues{/number}","pulls_url":"https://api.github.com/repos/aballway/WinObjC/pulls{/number}","milestones_url":"https://api.github.com/repos/aballway/WinObjC/milestones{/number}","notifications_url":"https://api.github.com/repos/aballway/WinObjC/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aballway/WinObjC/labels{/name}","releases_url":"https://api.github.com/repos/aballway/WinObjC/releases{/id}","deployments_url":"https://api.github.com/repos/aballway/WinObjC/deployments","created_at":"2016-06-27T20:48:04Z","updated_at":"2016-11-11T16:51:37Z","pushed_at":"2017-02-14T20:01:04Z","git_url":"git://github.com/aballway/WinObjC.git","ssh_url":"git@github.com:aballway/WinObjC.git","clone_url":"https://github.com/aballway/WinObjC.git","svn_url":"https://github.com/aballway/WinObjC","homepage":"","size":337685,"stargazers_count":0,"watchers_count":0,"language":"Objective-C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Microsoft:develop","ref":"develop","sha":"4527ce3fb869a3bd6676f46c2a8f69d766e8fdc8","user":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"repo":{"id":37950166,"name":"WinObjC","full_name":"Microsoft/WinObjC","owner":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Microsoft/WinObjC","description":"Objective-C for Windows","fork":false,"url":"https://api.github.com/repos/Microsoft/WinObjC","forks_url":"https://api.github.com/repos/Microsoft/WinObjC/forks","keys_url":"https://api.github.com/repos/Microsoft/WinObjC/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Microsoft/WinObjC/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Microsoft/WinObjC/teams","hooks_url":"https://api.github.com/repos/Microsoft/WinObjC/hooks","issue_events_url":"https://api.github.com/repos/Microsoft/WinObjC/issues/events{/number}","events_url":"https://api.github.com/repos/Microsoft/WinObjC/events","assignees_url":"https://api.github.com/repos/Microsoft/WinObjC/assignees{/user}","branches_url":"https://api.github.com/repos/Microsoft/WinObjC/branches{/branch}","tags_url":"https://api.github.com/repos/Microsoft/WinObjC/tags","blobs_url":"https://api.github.com/repos/Microsoft/WinObjC/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Microsoft/WinObjC/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Microsoft/WinObjC/git/refs{/sha}","trees_url":"https://api.github.com/repos/Microsoft/WinObjC/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Microsoft/WinObjC/statuses/{sha}","languages_url":"https://api.github.com/repos/Microsoft/WinObjC/languages","stargazers_url":"https://api.github.com/repos/Microsoft/WinObjC/stargazers","contributors_url":"https://api.github.com/repos/Microsoft/WinObjC/contributors","subscribers_url":"https://api.github.com/repos/Microsoft/WinObjC/subscribers","subscription_url":"https://api.github.com/repos/Microsoft/WinObjC/subscription","commits_url":"https://api.github.com/repos/Microsoft/WinObjC/commits{/sha}","git_commits_url":"https://api.github.com/repos/Microsoft/WinObjC/git/commits{/sha}","comments_url":"https://api.github.com/repos/Microsoft/WinObjC/comments{/number}","issue_comment_url":"https://api.github.com/repos/Microsoft/WinObjC/issues/comments{/number}","contents_url":"https://api.github.com/repos/Microsoft/WinObjC/contents/{+path}","compare_url":"https://api.github.com/repos/Microsoft/WinObjC/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Microsoft/WinObjC/merges","archive_url":"https://api.github.com/repos/Microsoft/WinObjC/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Microsoft/WinObjC/downloads","issues_url":"https://api.github.com/repos/Microsoft/WinObjC/issues{/number}","pulls_url":"https://api.github.com/repos/Microsoft/WinObjC/pulls{/number}","milestones_url":"https://api.github.com/repos/Microsoft/WinObjC/milestones{/number}","notifications_url":"https://api.github.com/repos/Microsoft/WinObjC/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Microsoft/WinObjC/labels{/name}","releases_url":"https://api.github.com/repos/Microsoft/WinObjC/releases{/id}","deployments_url":"https://api.github.com/repos/Microsoft/WinObjC/deployments","created_at":"2015-06-23T23:14:58Z","updated_at":"2017-02-14T18:07:35Z","pushed_at":"2017-02-14T20:01:06Z","git_url":"git://github.com/Microsoft/WinObjC.git","ssh_url":"git@github.com:Microsoft/WinObjC.git","clone_url":"https://github.com/Microsoft/WinObjC.git","svn_url":"https://github.com/Microsoft/WinObjC","homepage":"","size":378379,"stargazers_count":5593,"watchers_count":5593,"language":"Objective-C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":745,"mirror_url":null,"open_issues_count":319,"forks":745,"open_issues":319,"watchers":5593,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/Microsoft/WinObjC/pulls/1933"},"html":{"href":"https://github.com/Microsoft/WinObjC/pull/1933"},"issue":{"href":"https://api.github.com/repos/Microsoft/WinObjC/issues/1933"},"comments":{"href":"https://api.github.com/repos/Microsoft/WinObjC/issues/1933/comments"},"review_comments":{"href":"https://api.github.com/repos/Microsoft/WinObjC/pulls/1933/comments"},"review_comment":{"href":"https://api.github.com/repos/Microsoft/WinObjC/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Microsoft/WinObjC/pulls/1933/commits"},"statuses":{"href":"https://api.github.com/repos/Microsoft/WinObjC/statuses/9036cc3ddf4805d47e1ad99290c8628ee317f118"}}}}
{"actor":{"display_login":"aballway"}}