Skip to content

Commit

Permalink
refactor: rewrite colorlib, add type checking
Browse files Browse the repository at this point in the history
  • Loading branch information
anna328p committed Dec 17, 2023
1 parent dbe32db commit e693b67
Show file tree
Hide file tree
Showing 9 changed files with 408 additions and 63 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,8 @@ Style/CommandLiteral:
Style/AccessModifierDeclarations:
EnforcedStyle: inline

Style/DataInheritance:
Enabled: false

Style/ParallelAssignment:
Enabled: false
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,4 @@ group :development do
end

# Colors
gem 'matrix'
gem 'numo-narray'
12 changes: 6 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ GIT
GEM
remote: https://rubygems.org/
specs:
abbrev (0.1.1)
abbrev (0.1.2)
activejob (7.1.2)
activesupport (= 7.1.2)
globalid (>= 0.3.6)
Expand Down Expand Up @@ -120,7 +120,7 @@ GEM
domain_name (~> 0.5)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
io-console (0.7.0)
io-console (0.7.1)
jaro_winkler (1.5.6)
jsi (0.7.0)
addressable (~> 2.3)
Expand All @@ -137,7 +137,6 @@ GEM
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
matrix (0.4.2)
mediawiki_api (0.8.1)
faraday (~> 1)
faraday-cookie_jar
Expand All @@ -155,6 +154,7 @@ GEM
nokogiri (1.15.5)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
numo-narray (0.9.2.1)
open_uri_redirections (0.2.1)
opus-ruby (1.0.1)
ffi
Expand Down Expand Up @@ -234,7 +234,7 @@ GEM
rufus-scheduler (3.9.1)
fugit (~> 1.1, >= 1.1.6)
rutie (0.0.4)
securerandom (0.3.0)
securerandom (0.3.1)
solargraph (0.48.0)
backport (~> 1.2)
benchmark
Expand All @@ -250,7 +250,7 @@ GEM
thor (~> 1.0)
tilt (~> 2.0)
yard (~> 0.9, >= 0.9.24)
sorbet-runtime (0.5.11155)
sorbet-runtime (0.5.11156)
sqlite3 (1.6.9)
mini_portile2 (~> 2.8.0)
steep (1.6.0)
Expand Down Expand Up @@ -319,10 +319,10 @@ DEPENDENCIES
jsi
kramdown
kramdown-parser-gfm
matrix
mediawiki_api
narray
nokogiri
numo-narray
open_uri_redirections
paint
parser
Expand Down
33 changes: 33 additions & 0 deletions Steepfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
D = Steep::Diagnostic

Check warning on line 1 in Steepfile

View check run for this annotation

Check Run Reporter / Lint / lint

com.puppycrawl.tools.checkstyle.Style/FrozenStringLiteralComment

com.puppycrawl.tools.checkstyle.Style/FrozenStringLiteralComment: Style/FrozenStringLiteralComment: Missing frozen string literal comment.

target :lib do
signature 'sig'

check 'lib'
check 'modules'
check 'Gemfile'
# check "app/models/**/*.rb" # Glob
# ignore "lib/templates/*.rb"

# library "pathname" # Standard libraries
# library "strong_json" # Gems
# library 'numo-narray'

# configure_code_diagnostics(D::Ruby.default) # `default` diagnostics setting (applies by default)

Check warning on line 16 in Steepfile

View check run for this annotation

Check Run Reporter / Lint / lint

com.puppycrawl.tools.checkstyle.Layout/LineLength

com.puppycrawl.tools.checkstyle.Layout/LineLength: Layout/LineLength: Line is too long. [105/80]
# configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting

Check warning on line 17 in Steepfile

View check run for this annotation

Check Run Reporter / Lint / lint

com.puppycrawl.tools.checkstyle.Layout/LineLength

com.puppycrawl.tools.checkstyle.Layout/LineLength: Layout/LineLength: Line is too long. [83/80]
# configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting

Check warning on line 18 in Steepfile

View check run for this annotation

Check Run Reporter / Lint / lint

com.puppycrawl.tools.checkstyle.Layout/LineLength

com.puppycrawl.tools.checkstyle.Layout/LineLength: Layout/LineLength: Line is too long. [84/80]
# configure_code_diagnostics(D::Ruby.silent) # `silent` diagnostics setting

Check warning on line 19 in Steepfile

View check run for this annotation

Check Run Reporter / Lint / lint

com.puppycrawl.tools.checkstyle.Layout/LineLength

com.puppycrawl.tools.checkstyle.Layout/LineLength: Layout/LineLength: Line is too long. [83/80]
# configure_code_diagnostics do |hash| # You can setup everything yourself

Check warning on line 20 in Steepfile

View check run for this annotation

Check Run Reporter / Lint / lint

com.puppycrawl.tools.checkstyle.Layout/LineLength

com.puppycrawl.tools.checkstyle.Layout/LineLength: Layout/LineLength: Line is too long. [88/80]
# hash[D::Ruby::NoMethod] = :information
# end
end

# target :test do
# signature "sig", "sig-private"
#
# check "test"
#
# # library "pathname" # Standard libraries
# end

# vim: ft=ruby
38 changes: 18 additions & 20 deletions gemset.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 9 additions & 36 deletions lib/qbot/colorlib.rb
Original file line number Diff line number Diff line change
@@ -1,49 +1,19 @@
# frozen_string_literal: true

require 'matrix'

module QBot
# Library for working with RGB, XYZ, and LAB colorspaces
module ColorLib
def self.matrix_dim(mx)
raise('argument is not a matrix') \
if mx.empty? || mx.first&.empty?

raise('argument is not a matrix') \
unless mx.map(&:size).then { |sizes| sizes.all?(sizes.first) }

mfirst = mx.first || []

[mx.size, mfirst.size]
end

def self.mul_compat?(mx1, mx2)
_, c1 = matrix_dim(mx1)
r2, = matrix_dim(mx2)

c1 == r2
end

def self.dot_product(ary1, ary2)
ary1.zip(ary2).map { |a, b| a * (b || 0.0) }.sum
end

def self.matmul(mx1, mx2)
raise('matrices have incompatible dimensions') \
unless mul_compat?(mx1, mx2)

mx2t = mx2.transpose

mx1.map { |row| mx2t.zip(row).map { |c, _| dot_product(row, c) } }
end

# rubocop: disable Layout/SpaceInsideArrayLiteralBrackets
# rubocop: disable Layout/ExtraSpacing
RGB_XYZ_MATRIX = [
RGB_XYZ_MATRIX = Matrix[
[ 0.4124564, 0.3575761, 0.1804375 ],
[ 0.2126729, 0.7151522, 0.0721750 ],
[ 0.0193339, 0.1191920, 0.9503041 ]
].freeze

XYZ_RGB_MATRIX = [
XYZ_RGB_MATRIX = Matrix[
[ 3.2404542, -1.5371385, -0.4985314 ],
[ -0.9692660, 1.8760108, 0.0415560 ],
[ 0.0556434, -0.2040259, 1.0572252 ]
Expand All @@ -54,8 +24,10 @@ def self.matmul(mx1, mx2)
##
# A tristimulus value in the CIE 1931 space.
class XYZTristimulus < Data.define(:x, :y, :z)
# @dynamic x, y, z, initialize

def to_srgb_linear
r, g, b = ColorLib.matmul(XYZ_RGB_MATRIX, [[x], [y], [z]]).flatten
r, g, b = (XYZ_RGB_MATRIX * Matrix[[x], [y], [z]]).to_a.flatten

SRGBLinearColor.new(r:, g:, b:)
end
Expand Down Expand Up @@ -98,6 +70,7 @@ def to_a = to_ary
##
# An RGB value in the sRGB colorspace.
class SRGBColor < Data.define(:r, :g, :b)
# @dynamic r, g, b, initialize
def self.from_hex(hex)
r, g, b = hex.chars.last(6).each_slice(2)
.map { |c| c.join.to_i(16) / 255.0 }
Expand Down Expand Up @@ -139,7 +112,7 @@ def to_a = to_ary
# A gamma-expanded ("linear light") RGB value in the sRGB colorspace.
class SRGBLinearColor < Data.define(:r, :g, :b)
def to_xyz
x, y, z = ColorLib.matmul(RGB_XYZ_MATRIX, [[r], [g], [b]]).flatten
x, y, z = (RGB_XYZ_MATRIX * Matrix[[r], [g], [b]]).to_a.flatten
XYZTristimulus.new(x:, y:, z:)
end

Expand Down
Loading

0 comments on commit e693b67

Please sign in to comment.