Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Ability to Use Color Class #796

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions lib/prawn/color/color.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# encoding: utf-8
module Prawn
module Color
class Color
def normalize_color(color)
raise NotImplementedError
end

def color_space
raise NotImplementedError
end

def color_to_s
normalize_color.map { |c| '%.3f' % c }.join(' ')
end

def base_representation
@color
end
end
end
end

21 changes: 21 additions & 0 deletions lib/prawn/color/color_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# encoding: utf-8
module Prawn
module Color
class ColorFactory
def self.build(*color)
return color[0] if color[0].is_a? ::Prawn::Color::Color
case(color.size)
when 1
raise ArgumentError, 'Provided color must be a string' unless color[0].class == String
RGBColor.new(color[0])
when 4
CYMKColor.new(color)
else
raise ArgumentError, 'wrong number of arguments supplied'
end
end
end
end
end


19 changes: 19 additions & 0 deletions lib/prawn/color/cymk_color.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# encoding: utf-8
module Prawn
module Color
class CYMKColor < Color
def initialize(color)
@color = color
end

def normalize_color
c,m,y,k = @color
[c / 100.0, m / 100.0, y / 100.0, k / 100.0]
end

def color_space
:DeviceCMYK
end
end
end
end
28 changes: 28 additions & 0 deletions lib/prawn/color/rgb_color.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# encoding: utf-8
module Prawn
module Color
class RGBColor < Color
def initialize(color)
@color = color
end

def to_rgb
hex2rgb
end

def normalize_color
r,g,b = hex2rgb
[r / 255.0, g / 255.0, b / 255.0]
end

def hex2rgb
r,g,b = @color[0..1], @color[2..3], @color[4..5]
[r,g,b].map { |e| e.to_i(16) }
end

def color_space
:DeviceRGB
end
end
end
end
4 changes: 2 additions & 2 deletions lib/prawn/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -649,8 +649,8 @@ def page
# setting override_settings to true ensures that a new graphic state does not end up using
# previous settings.
def use_graphic_settings(override_settings = false)
set_fill_color if current_fill_color != "000000" || override_settings
set_stroke_color if current_stroke_color != "000000" || override_settings
set_fill_color if current_fill_color.to_rgb != [0, 0, 0] || override_settings
set_stroke_color if current_stroke_color.to_rgb != [0, 0, 0] || override_settings
write_line_width if line_width != 1 || override_settings
write_stroke_cap_style if cap_style != :butt || override_settings
write_stroke_join_style if join_style != :miter || override_settings
Expand Down
7 changes: 6 additions & 1 deletion lib/prawn/graphics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
require_relative "graphics/transformation"
require_relative "graphics/patterns"

require_relative "color/color_factory"
require_relative "color/color"
require_relative "color/rgb_color"
require_relative "color/cymk_color"

module Prawn

# Implements the drawing facilities for Prawn::Document.
Expand Down Expand Up @@ -327,7 +332,7 @@ def stroke_axis(options = {})
:width => bounds.width.to_i - (options[:at] || [0,0])[0],
:step_length => 100,
:negative_axes_length => 20,
:color => "000000",
:color => ::Prawn::Color::ColorFactory.build("000000")
}.merge(options)

Prawn.verify_options([:at, :width, :height, :step_length,
Expand Down
127 changes: 63 additions & 64 deletions lib/prawn/graphics/color.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ module Color
#
def fill_color(*color)
return current_fill_color if color.empty?
self.current_fill_color = process_color(*color)
self.current_fill_color = ::Prawn::Color::ColorFactory.build(*color)
set_fill_color
end

Expand All @@ -49,9 +49,8 @@ def fill_color(*color)
#
def stroke_color(*color)
return current_stroke_color if color.empty?
color = process_color(*color)
self.current_stroke_color = color
set_stroke_color(color)
self.current_stroke_color = ::Prawn::Color::ColorFactory.build(*color)
set_stroke_color
end

alias_method :stroke_color=, :stroke_color
Expand All @@ -74,62 +73,65 @@ def rgb2hex(rgb)
# => [255, 120, 8]
#
def hex2rgb(hex)
hex = hex.respond_to?(:to_str) ? hex.to_str : hex.color_str
r,g,b = hex[0..1], hex[2..3], hex[4..5]
[r,g,b].map { |e| e.to_i(16) }
end

private

def process_color(*color)
case(color.size)
when 1
color[0]
when 4
color
else
raise ArgumentError, 'wrong number of arguments supplied'
end
end

def color_type(color)
case color
when String
:RGB
when Array
case color.length
when 3
:RGB
when 4
:CMYK
else
raise ArgumentError, "Unknown type of color: #{color.inspect}"
end
end
end

def normalize_color(color)
case color_type(color)
when :RGB
r,g,b = hex2rgb(color)
[r / 255.0, g / 255.0, b / 255.0]
when :CMYK
c,m,y,k = *color
[c / 100.0, m / 100.0, y / 100.0, k / 100.0]
end
end

def color_to_s(color)
normalize_color(color).map { |c| '%.3f' % c }.join(' ')
end

def color_space(color)
case color_type(color)
when :RGB
:DeviceRGB
when :CMYK
:DeviceCMYK
end
end
#def process_color(*color)
#case(color.size)
#when 1
#color[0]
#when 4
#color
#else
#raise ArgumentError, 'wrong number of arguments supplied'
#end
#end

#def color_type(color)
#case color
#when ->(color) { color.respond_to?(:to_str) }
#:RGB
#when ->(color) { color.respond_to?(:color_str) }
#:RGB
#when ->(color) { color.respond_to?(:to_ary) }
#case color.length
#when 3
#:RGB
#when 4
#:CMYK
#else
#raise ArgumentError, "Unknown type of color: #{color.inspect}"
#end
#end
#end

#def normalize_color(color)
#case color_type(color)
#when :RGB
#r,g,b = hex2rgb(color)
#[r / 255.0, g / 255.0, b / 255.0]
#when :CMYK
#c,m,y,k = *color
#[c / 100.0, m / 100.0, y / 100.0, k / 100.0]
#end
#end

#def color_to_s(color)
#normalize_color(color).map { |c| '%.3f' % c }.join(' ')
#end

#def color_space(color)
#case color_type(color)
#when :RGB
#:DeviceRGB
#when :CMYK
#:DeviceCMYK
#end
#end

COLOR_SPACES = [:DeviceRGB, :DeviceCMYK, :Pattern]

Expand Down Expand Up @@ -166,11 +168,10 @@ def set_color(type, color, options = {})

if options[:pattern]
set_color_space type, :Pattern
renderer.add_content "/#{color} #{operator}"
renderer.add_content "/#{color.base_representation} #{operator}"
else
set_color_space type, color_space(color)
color = color_to_s(color)
write_color(color, operator)
set_color_space type, color.color_space
write_color(color.color_to_s, operator)
end
end

Expand Down Expand Up @@ -199,19 +200,19 @@ def set_current_color_space(color_space, type)
end

def current_fill_color
graphic_state.fill_color
::Prawn::Color::ColorFactory.build(*graphic_state.fill_color)
end

def current_fill_color=(color)
graphic_state.fill_color = color
graphic_state.fill_color = color.base_representation
end

def current_stroke_color
graphic_state.stroke_color
::Prawn::Color::ColorFactory.build(*graphic_state.stroke_color)
end

def current_stroke_color=(color)
graphic_state.stroke_color = color
graphic_state.stroke_color = color.base_representation
end

def write_fill_color
Expand All @@ -225,8 +226,6 @@ def write_stroke_color
def write_color(color, operator)
renderer.add_content "#{color} #{operator}"
end

end
end
end

15 changes: 6 additions & 9 deletions lib/prawn/graphics/patterns.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,27 +86,24 @@ def gradient(*args)
raise ArgumentError, "Unknown type of gradient: #{args.inspect}"
end

color1 = normalize_color(args[-2]).dup.freeze
color2 = normalize_color(args[-1]).dup.freeze
color1 = ::Prawn::Color::ColorFactory.build(args[-2])
color2 = ::Prawn::Color::ColorFactory.build(args[-1])

if color_type(color1) != color_type(color2)
if color1.class != color2.class
raise ArgumentError, "Both colors must be of the same color space: #{color1.inspect} and #{color2.inspect}"
end

process_color color1
process_color color2

shader = ref!({
:FunctionType => 2,
:Domain => [0.0, 1.0],
:C0 => color1,
:C1 => color2,
:C0 => color1.normalize_color,
:C1 => color2.normalize_color,
:N => 1.0,
})

shading = ref!({
:ShadingType => args.length == 4 ? 2 : 3, # axial : radial shading
:ColorSpace => color_space(color1),
:ColorSpace => color1.color_space,
:Coords => args.length == 4 ?
[0, 0, args[1].first - args[0].first, args[1].last - args[0].last] :
[0, 0, args[1], args[2].first - args[0].first, args[2].last - args[0].last, args[3]],
Expand Down
4 changes: 2 additions & 2 deletions lib/prawn/grid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def row_height
end

# Diagnostic tool to show all of the grids. Defaults to gray.
def show_all(color = "CCCCCC")
def show_all(color = ::Prawn::Color::ColorFactory.build(*'cccccc'))
self.rows.times do |i|
self.columns.times do |j|
pdf.grid(i,j).show(color)
Expand Down Expand Up @@ -186,7 +186,7 @@ def bounding_box(&blk)
end

# Diagnostic method
def show(grid_color = "CCCCCC")
def show(grid_color = ::Prawn::Color::ColorFactory.build(*'CCCCCC'))
self.bounding_box do
original_stroke_color = pdf.stroke_color

Expand Down
18 changes: 18 additions & 0 deletions spec/graphics_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,31 @@
colors.stroke_color.should == [1.0, 0.8, 0.8]
end

#it "should accept stroke colors from objects that support color_str" do
#color = mock('color')
#color.expects(:color_str).returns("ffcccc")
#@pdf.stroke_color color #"ffcccc"
#colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
## 100% red, 80% green, 80% blue
#colors.stroke_color.should == [1.0, 0.8, 0.8]
#end

it "should set fill colors" do
@pdf.fill_color "ccff00"
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
# 80% red, 100% green, 0% blue
colors.fill_color.should == [0.8,1.0,0]
end

#it "should accept fill colors from objects that support color_str" do
#color = mock('color')
#color.expects(:color_str).returns("ccffcc")
#@pdf.fill_color color #"ffcccc"
#colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
## 100% red, 80% green, 80% blue
#colors.fill_color.should == [0.8, 1.0, 0.8]
#end

it "should reset the colors on each new page if they have been defined" do
@pdf.fill_color "ccff00"
#colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
Expand Down
Loading