{"action":"created","comment":{"url":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/comments/187108376","pull_request_review_id":118822508,"id":187108376,"diff_hunk":"@@ -0,0 +1,264 @@\n+require 'bigdecimal'\n+\n+module TTFunk\n+  class Table\n+    class Cff < TTFunk::Table\n+      class Dict < TTFunk::SubTable\n+        class InvalidOperandError < StandardError; end\n+        class TooManyOperandsError < StandardError; end\n+\n+        # for regular single-byte operators\n+        OPERATOR_BZERO = 0..21\n+        OPERAND_BZERO = [28..30, 32..254].freeze\n+\n+        # for operators that are two bytes wide\n+        WIDE_OPERATOR_BZERO = 12\n+        WIDE_OPERATOR_ADJUSTMENT = 1200\n+\n+        # maximum number of operands allowed per operator\n+        MAX_OPERANDS = 48\n+\n+        # used to validate operands expressed in scientific notation\n+        VALID_SCI_SIGNIFICAND_RE = /\\A-?\\d+(?:\\.\\d+)?\\z/\n+        VALID_SCI_EXPONENT_RE = /\\A-?\\d+\\z/\n+\n+        include Enumerable\n+\n+        def [](operator)\n+          @dict[operator]\n+        end\n+\n+        def each(&block)\n+          @dict.each(&block)\n+        end\n+\n+        alias each_pair each\n+\n+        def encode\n+          ''.tap do |result|","path":"lib/ttfunk/table/cff/dict.rb","position":38,"original_position":38,"commit_id":"484339d8f94edc0973413cdb0e17991bb138e307","original_commit_id":"484339d8f94edc0973413cdb0e17991bb138e307","user":{"login":"pointlessone","id":7405,"avatar_url":"https://avatars3.githubusercontent.com/u/7405?v=4","gravatar_id":"","url":"https://api.github.com/users/pointlessone","html_url":"https://github.com/pointlessone","followers_url":"https://api.github.com/users/pointlessone/followers","following_url":"https://api.github.com/users/pointlessone/following{/other_user}","gists_url":"https://api.github.com/users/pointlessone/gists{/gist_id}","starred_url":"https://api.github.com/users/pointlessone/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pointlessone/subscriptions","organizations_url":"https://api.github.com/users/pointlessone/orgs","repos_url":"https://api.github.com/users/pointlessone/repos","events_url":"https://api.github.com/users/pointlessone/events{/privacy}","received_events_url":"https://api.github.com/users/pointlessone/received_events","type":"User","site_admin":false},"body":"Just heads up: this pattern will have to be replaced. You may have seen that Prawan master is updated to use Ruby 2.3. That entails frozen strings as we're trying to stay close to community style guide (and coincidentally Rubocop's default configuration). I haven't updated TTFunk yet to reflect the change but I will before the release. You can keep using string mutation trough out these PRs. I will handle the update after the merge. Or you can help me a bit and opt for immutable strings in your PRs.\r\n\r\nI'd suggest `.map{}.join('')` as a replacement pattern here.","created_at":"2018-05-09T17:04:06Z","updated_at":"2018-05-09T17:04:06Z","html_url":"https://github.com/prawnpdf/ttfunk/pull/59#discussion_r187108376","pull_request_url":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/59","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/comments/187108376"},"html":{"href":"https://github.com/prawnpdf/ttfunk/pull/59#discussion_r187108376"},"pull_request":{"href":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/59"}}},"pull_request":{"url":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/59","id":180165773,"html_url":"https://github.com/prawnpdf/ttfunk/pull/59","diff_url":"https://github.com/prawnpdf/ttfunk/pull/59.diff","patch_url":"https://github.com/prawnpdf/ttfunk/pull/59.patch","issue_url":"https://api.github.com/repos/prawnpdf/ttfunk/issues/59","number":59,"state":"open","locked":false,"title":"Add CFF core classes and data structures","user":{"login":"camertron","id":575280,"avatar_url":"https://avatars2.githubusercontent.com/u/575280?v=4","gravatar_id":"","url":"https://api.github.com/users/camertron","html_url":"https://github.com/camertron","followers_url":"https://api.github.com/users/camertron/followers","following_url":"https://api.github.com/users/camertron/following{/other_user}","gists_url":"https://api.github.com/users/camertron/gists{/gist_id}","starred_url":"https://api.github.com/users/camertron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/camertron/subscriptions","organizations_url":"https://api.github.com/users/camertron/orgs","repos_url":"https://api.github.com/users/camertron/repos","events_url":"https://api.github.com/users/camertron/events{/privacy}","received_events_url":"https://api.github.com/users/camertron/received_events","type":"User","site_admin":false},"body":"_**This pull request is part of a larger effort to bring OTF support to TTFunk. See https://github.com/prawnpdf/ttfunk/issues/53 for details.**_\r\n\r\nHighlights of this PR:\r\n1. The two CFF data structures added in this PR are `Index` and `Dict`. An index is essentially an array that can be accessed by index, and a dict is a dictionary of operator/operand (i.e. key/value) pairs. Operators have special meaning depending on the context. For example the CFF top and private dicts both use the dict structure but define different operators for the data they contain.\r\n2. The `Dict` class technically isn't used anywhere yet. Including it when it is actually used would make the corresponding PR too large in my opinion, so it is introduced here instead.\r\n3. The `Sci` class (couldn't come up with a better name, suggestions welcome) is supposed to represent a number in scientific notation (i.e. 5.2 x 10<sup>4</sup>). The `Dict` class uses it for a special type of operand that starts with a byte `30`. I could have stored it as a float, but it would then have been a lot more work to re-encode later.\r\n4. The `TTFunk::SubTable` class has been introduced to handle the case when table-like parsing behavior is desired but the table is not a top-level, directory-based font table.\r\n5. The beginnings of an incomplete CFF table are also present. Currently only the header and name index sub tables are supported, more coming soon. CFF is by far the most complicated table TTFunk supports to date and the centerpiece of the open-type font format.","created_at":"2018-04-08T15:44:08Z","updated_at":"2018-05-09T17:04:06Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a7ac0941bd71d6e21fd77635aa9488a7844facf1","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/59/commits","review_comments_url":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/59/comments","review_comment_url":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/comments{/number}","comments_url":"https://api.github.com/repos/prawnpdf/ttfunk/issues/59/comments","statuses_url":"https://api.github.com/repos/prawnpdf/ttfunk/statuses/484339d8f94edc0973413cdb0e17991bb138e307","head":{"label":"camertron:cff_core","ref":"cff_core","sha":"484339d8f94edc0973413cdb0e17991bb138e307","user":{"login":"camertron","id":575280,"avatar_url":"https://avatars2.githubusercontent.com/u/575280?v=4","gravatar_id":"","url":"https://api.github.com/users/camertron","html_url":"https://github.com/camertron","followers_url":"https://api.github.com/users/camertron/followers","following_url":"https://api.github.com/users/camertron/following{/other_user}","gists_url":"https://api.github.com/users/camertron/gists{/gist_id}","starred_url":"https://api.github.com/users/camertron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/camertron/subscriptions","organizations_url":"https://api.github.com/users/camertron/orgs","repos_url":"https://api.github.com/users/camertron/repos","events_url":"https://api.github.com/users/camertron/events{/privacy}","received_events_url":"https://api.github.com/users/camertron/received_events","type":"User","site_admin":false},"repo":{"id":108873328,"name":"ttfunk","full_name":"camertron/ttfunk","owner":{"login":"camertron","id":575280,"avatar_url":"https://avatars2.githubusercontent.com/u/575280?v=4","gravatar_id":"","url":"https://api.github.com/users/camertron","html_url":"https://github.com/camertron","followers_url":"https://api.github.com/users/camertron/followers","following_url":"https://api.github.com/users/camertron/following{/other_user}","gists_url":"https://api.github.com/users/camertron/gists{/gist_id}","starred_url":"https://api.github.com/users/camertron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/camertron/subscriptions","organizations_url":"https://api.github.com/users/camertron/orgs","repos_url":"https://api.github.com/users/camertron/repos","events_url":"https://api.github.com/users/camertron/events{/privacy}","received_events_url":"https://api.github.com/users/camertron/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/camertron/ttfunk","description":"Font Metrics Parser for Prawn","fork":true,"url":"https://api.github.com/repos/camertron/ttfunk","forks_url":"https://api.github.com/repos/camertron/ttfunk/forks","keys_url":"https://api.github.com/repos/camertron/ttfunk/keys{/key_id}","collaborators_url":"https://api.github.com/repos/camertron/ttfunk/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/camertron/ttfunk/teams","hooks_url":"https://api.github.com/repos/camertron/ttfunk/hooks","issue_events_url":"https://api.github.com/repos/camertron/ttfunk/issues/events{/number}","events_url":"https://api.github.com/repos/camertron/ttfunk/events","assignees_url":"https://api.github.com/repos/camertron/ttfunk/assignees{/user}","branches_url":"https://api.github.com/repos/camertron/ttfunk/branches{/branch}","tags_url":"https://api.github.com/repos/camertron/ttfunk/tags","blobs_url":"https://api.github.com/repos/camertron/ttfunk/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/camertron/ttfunk/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/camertron/ttfunk/git/refs{/sha}","trees_url":"https://api.github.com/repos/camertron/ttfunk/git/trees{/sha}","statuses_url":"https://api.github.com/repos/camertron/ttfunk/statuses/{sha}","languages_url":"https://api.github.com/repos/camertron/ttfunk/languages","stargazers_url":"https://api.github.com/repos/camertron/ttfunk/stargazers","contributors_url":"https://api.github.com/repos/camertron/ttfunk/contributors","subscribers_url":"https://api.github.com/repos/camertron/ttfunk/subscribers","subscription_url":"https://api.github.com/repos/camertron/ttfunk/subscription","commits_url":"https://api.github.com/repos/camertron/ttfunk/commits{/sha}","git_commits_url":"https://api.github.com/repos/camertron/ttfunk/git/commits{/sha}","comments_url":"https://api.github.com/repos/camertron/ttfunk/comments{/number}","issue_comment_url":"https://api.github.com/repos/camertron/ttfunk/issues/comments{/number}","contents_url":"https://api.github.com/repos/camertron/ttfunk/contents/{+path}","compare_url":"https://api.github.com/repos/camertron/ttfunk/compare/{base}...{head}","merges_url":"https://api.github.com/repos/camertron/ttfunk/merges","archive_url":"https://api.github.com/repos/camertron/ttfunk/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/camertron/ttfunk/downloads","issues_url":"https://api.github.com/repos/camertron/ttfunk/issues{/number}","pulls_url":"https://api.github.com/repos/camertron/ttfunk/pulls{/number}","milestones_url":"https://api.github.com/repos/camertron/ttfunk/milestones{/number}","notifications_url":"https://api.github.com/repos/camertron/ttfunk/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/camertron/ttfunk/labels{/name}","releases_url":"https://api.github.com/repos/camertron/ttfunk/releases{/id}","deployments_url":"https://api.github.com/repos/camertron/ttfunk/deployments","created_at":"2017-10-30T15:51:34Z","updated_at":"2017-10-30T15:51:36Z","pushed_at":"2018-05-09T15:51:54Z","git_url":"git://github.com/camertron/ttfunk.git","ssh_url":"git@github.com:camertron/ttfunk.git","clone_url":"https://github.com/camertron/ttfunk.git","svn_url":"https://github.com/camertron/ttfunk","homepage":"http://prawn.majesticseacreature.com","size":26643,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"prawnpdf:otf","ref":"otf","sha":"3b05519d8362eef1d59cb956fb421485460393e0","user":{"login":"prawnpdf","id":1440292,"avatar_url":"https://avatars0.githubusercontent.com/u/1440292?v=4","gravatar_id":"","url":"https://api.github.com/users/prawnpdf","html_url":"https://github.com/prawnpdf","followers_url":"https://api.github.com/users/prawnpdf/followers","following_url":"https://api.github.com/users/prawnpdf/following{/other_user}","gists_url":"https://api.github.com/users/prawnpdf/gists{/gist_id}","starred_url":"https://api.github.com/users/prawnpdf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/prawnpdf/subscriptions","organizations_url":"https://api.github.com/users/prawnpdf/orgs","repos_url":"https://api.github.com/users/prawnpdf/repos","events_url":"https://api.github.com/users/prawnpdf/events{/privacy}","received_events_url":"https://api.github.com/users/prawnpdf/received_events","type":"Organization","site_admin":false},"repo":{"id":69899,"name":"ttfunk","full_name":"prawnpdf/ttfunk","owner":{"login":"prawnpdf","id":1440292,"avatar_url":"https://avatars0.githubusercontent.com/u/1440292?v=4","gravatar_id":"","url":"https://api.github.com/users/prawnpdf","html_url":"https://github.com/prawnpdf","followers_url":"https://api.github.com/users/prawnpdf/followers","following_url":"https://api.github.com/users/prawnpdf/following{/other_user}","gists_url":"https://api.github.com/users/prawnpdf/gists{/gist_id}","starred_url":"https://api.github.com/users/prawnpdf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/prawnpdf/subscriptions","organizations_url":"https://api.github.com/users/prawnpdf/orgs","repos_url":"https://api.github.com/users/prawnpdf/repos","events_url":"https://api.github.com/users/prawnpdf/events{/privacy}","received_events_url":"https://api.github.com/users/prawnpdf/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/prawnpdf/ttfunk","description":"Font Metrics Parser for Prawn","fork":false,"url":"https://api.github.com/repos/prawnpdf/ttfunk","forks_url":"https://api.github.com/repos/prawnpdf/ttfunk/forks","keys_url":"https://api.github.com/repos/prawnpdf/ttfunk/keys{/key_id}","collaborators_url":"https://api.github.com/repos/prawnpdf/ttfunk/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/prawnpdf/ttfunk/teams","hooks_url":"https://api.github.com/repos/prawnpdf/ttfunk/hooks","issue_events_url":"https://api.github.com/repos/prawnpdf/ttfunk/issues/events{/number}","events_url":"https://api.github.com/repos/prawnpdf/ttfunk/events","assignees_url":"https://api.github.com/repos/prawnpdf/ttfunk/assignees{/user}","branches_url":"https://api.github.com/repos/prawnpdf/ttfunk/branches{/branch}","tags_url":"https://api.github.com/repos/prawnpdf/ttfunk/tags","blobs_url":"https://api.github.com/repos/prawnpdf/ttfunk/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/prawnpdf/ttfunk/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/prawnpdf/ttfunk/git/refs{/sha}","trees_url":"https://api.github.com/repos/prawnpdf/ttfunk/git/trees{/sha}","statuses_url":"https://api.github.com/repos/prawnpdf/ttfunk/statuses/{sha}","languages_url":"https://api.github.com/repos/prawnpdf/ttfunk/languages","stargazers_url":"https://api.github.com/repos/prawnpdf/ttfunk/stargazers","contributors_url":"https://api.github.com/repos/prawnpdf/ttfunk/contributors","subscribers_url":"https://api.github.com/repos/prawnpdf/ttfunk/subscribers","subscription_url":"https://api.github.com/repos/prawnpdf/ttfunk/subscription","commits_url":"https://api.github.com/repos/prawnpdf/ttfunk/commits{/sha}","git_commits_url":"https://api.github.com/repos/prawnpdf/ttfunk/git/commits{/sha}","comments_url":"https://api.github.com/repos/prawnpdf/ttfunk/comments{/number}","issue_comment_url":"https://api.github.com/repos/prawnpdf/ttfunk/issues/comments{/number}","contents_url":"https://api.github.com/repos/prawnpdf/ttfunk/contents/{+path}","compare_url":"https://api.github.com/repos/prawnpdf/ttfunk/compare/{base}...{head}","merges_url":"https://api.github.com/repos/prawnpdf/ttfunk/merges","archive_url":"https://api.github.com/repos/prawnpdf/ttfunk/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/prawnpdf/ttfunk/downloads","issues_url":"https://api.github.com/repos/prawnpdf/ttfunk/issues{/number}","pulls_url":"https://api.github.com/repos/prawnpdf/ttfunk/pulls{/number}","milestones_url":"https://api.github.com/repos/prawnpdf/ttfunk/milestones{/number}","notifications_url":"https://api.github.com/repos/prawnpdf/ttfunk/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/prawnpdf/ttfunk/labels{/name}","releases_url":"https://api.github.com/repos/prawnpdf/ttfunk/releases{/id}","deployments_url":"https://api.github.com/repos/prawnpdf/ttfunk/deployments","created_at":"2008-10-30T22:41:01Z","updated_at":"2018-05-04T13:28:37Z","pushed_at":"2018-05-09T15:51:56Z","git_url":"git://github.com/prawnpdf/ttfunk.git","ssh_url":"git@github.com:prawnpdf/ttfunk.git","clone_url":"https://github.com/prawnpdf/ttfunk.git","svn_url":"https://github.com/prawnpdf/ttfunk","homepage":"http://prawn.majesticseacreature.com","size":13072,"stargazers_count":92,"watchers_count":92,"language":"Ruby","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":70,"mirror_url":null,"archived":false,"open_issues_count":9,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":70,"open_issues":9,"watchers":92,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/59"},"html":{"href":"https://github.com/prawnpdf/ttfunk/pull/59"},"issue":{"href":"https://api.github.com/repos/prawnpdf/ttfunk/issues/59"},"comments":{"href":"https://api.github.com/repos/prawnpdf/ttfunk/issues/59/comments"},"review_comments":{"href":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/59/comments"},"review_comment":{"href":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/prawnpdf/ttfunk/pulls/59/commits"},"statuses":{"href":"https://api.github.com/repos/prawnpdf/ttfunk/statuses/484339d8f94edc0973413cdb0e17991bb138e307"}},"author_association":"NONE"}}
{"actor":{"display_login":"pointlessone"}}