Skip to content

Commit

Permalink
Merge remote-tracking branch 'mainstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
hoanghiep90 committed Jan 27, 2016
2 parents 7b0fd66 + 7aa777f commit f8d75ff
Show file tree
Hide file tree
Showing 26 changed files with 369 additions and 217 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
.*.sw?
nbproject
pkg
pkg
.rvmrc
.bundle
Gemfile.lock
drop_to_console.rb
manual.pdf
/.idea
/doc
/bin
.DS_Store
*.pdf
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ rvm:
- 2.1.8
- 2.2.0-p0
- 2.2.4
- 2.3.0
- rbx-2
- jruby-9.0.4.0
matrix:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ for more information.

(Roger Nesbitt, [#891](https://github.com/prawnpdf/prawn/issues/891), [#894](https://github.com/prawnpdf/prawn/pull/894))

### Prawn::Graphics::BlendMode#blend_mode added
Blend modes can be used to change the way two layers are blended together. The
BM key is added to the External Graphics State based on the v1.4 PDF spec. `blend_mode`
accepts a single blend mode or array of blend modes. If an array is passed, the
PDF viewer blends layers based on the first valid blend mode.

## PrawnPDF 2.0.2 -- 2015-07-15

### Links in repeaters/stamps are now clickable
Expand Down
Binary file added data/images/blend_modes_bottom_layer.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/images/blend_modes_top_layer.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions lib/prawn/graphics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#
# This is free software. Please see the LICENSE and COPYING files for details.

require_relative "graphics/blend_mode"
require_relative "graphics/color"
require_relative "graphics/dash"
require_relative "graphics/cap_style"
Expand All @@ -22,6 +23,7 @@ module Prawn
# ruby-pdf.rubyforge.org
#
module Graphics
include BlendMode
include Color
include Dash
include CapStyle
Expand Down
64 changes: 64 additions & 0 deletions lib/prawn/graphics/blend_mode.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# encoding: utf-8
#
# blend_mode.rb : Implements blend modes
#
# Contributed by John Ford. October, 2015
#
# This is free software. Please see the LICENSE and COPYING files for details.
#

module Prawn
module Graphics
# The Prawn::BlendMode module is used to change the way
# two layers are blended together.
#
# Passing an array of blend modes is allowed. PDF viewers should
# blend layers based on the first recognized blend mode.
#
# Valid blend modes in v1.4 of the PDF spec include :Normal, :Multiply, :Screen,
# :Overlay, :Darken, :Lighten, :ColorDodge, :ColorBurn, :HardLight, :SoftLight,
# :Difference, :Exclusion, :Hue, :Saturation, :Color, and :Luminosity.
#
# Example:
# pdf.fill_color('0000ff')
# pdf.fill_rectangle([x, y+25], 50, 50)
# pdf.blend_mode(:Multiply) do
# pdf.fill_color('ff0000')
# pdf.fill_circle([x, y], 25)
# end
#
module BlendMode
# @group Stable API

def blend_mode(blend_mode = :Normal)
renderer.min_version(1.4)

save_graphics_state if block_given?
renderer.add_content "/#{blend_mode_dictionary_name(blend_mode)} gs"
if block_given?
yield
restore_graphics_state
end
end

private

def blend_mode_dictionary_registry
@blend_mode_dictionary_registry ||= {}
end

def blend_mode_dictionary_name(blend_mode)
key = Array(blend_mode).join('')
dictionary_name = "BM#{key}"

dictionary = blend_mode_dictionary_registry[dictionary_name] ||= ref!(
:Type => :ExtGState,
:BM => blend_mode
)

page.ext_gstates.merge!(dictionary_name => dictionary)
dictionary_name
end
end
end
end
5 changes: 4 additions & 1 deletion lib/prawn/images/png.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ def split_alpha_channel!
end

def alpha_channel?
[3, 4, 6].include? color_type
return true if color_type == 4 || color_type == 6
return @transparency.any? if color_type == 3

false
end

# Build a PDF object representing this image in +document+, and return
Expand Down
49 changes: 49 additions & 0 deletions manual/graphics/blend_mode.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# encoding: utf-8
#
# Blend modes can be used to change the way two layers (images, graphics,
# text, etc.) are blended together. The <code>blend_mode</code> method
# accepts a single blend mode or an array of blend modes. PDF viewers should
# blend the layers based on the first recognized blend mode.
#
# Valid blend modes in v1.4 of the PDF spec include :Normal, :Multiply, :Screen,
# :Overlay, :Darken, :Lighten, :ColorDodge, :ColorBurn, :HardLight, :SoftLight,
# :Difference, :Exclusion, :Hue, :Saturation, :Color, and :Luminosity.
#
require File.expand_path(File.join(File.dirname(__FILE__),
%w[.. example_helper]))

filename = File.basename(__FILE__).gsub('.rb', '.pdf')
Prawn::ManualBuilder::Example.generate(filename) do
start_new_page

# https://commons.wikimedia.org/wiki/File:Blend_modes_2.-bottom-layer.jpg#/media/File:Blend_modes_2.-bottom-layer.jpg
bottom_layer = "#{Prawn::DATADIR}/images/blend_modes_bottom_layer.jpg"

# https://commons.wikimedia.org/wiki/File:Blend_modes_1.-top-layer.jpg#/media/File:Blend_modes_1.-top-layer.jpg
top_layer = "#{Prawn::DATADIR}/images/blend_modes_top_layer.jpg"

blend_modes = [:Normal, :Multiply, :Screen, :Overlay, :Darken, :Lighten, :ColorDodge, :ColorBurn, :HardLight, :SoftLight, :Difference, :Exclusion, :Hue, :Saturation, :Color, :Luminosity]
blend_modes.each_with_index do |blend_mode, index|
x = index % 4 * 135
y = cursor - (index / 4 * 200)

image bottom_layer, :at => [x, y], :fit => [125, 125]
blend_mode(blend_mode) do
image top_layer, :at => [x, y], :fit => [125, 125]
end

y -= 130

fill_color '009ddc'
fill_rectangle [x, y], 75, 25
blend_mode(blend_mode) do
fill_color 'fdb827'
fill_rectangle [x + 50, y], 75, 25
end

y -= 30

fill_color '000000'
text_box blend_mode.to_s, :at => [x, y]
end
end
1 change: 1 addition & 0 deletions manual/graphics/graphics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
s.example "gradients"
s.example "transparency"
s.example "soft_masks"
s.example "blend_mode"
s.example "fill_rules"
end

Expand Down
2 changes: 1 addition & 1 deletion manual/graphics/soft_masks.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# encoding: utf-8
#
# Soft masks are user for more complex alpha channel manipulations. You can use
# Soft masks are used for more complex alpha channel manipulations. You can use
# arbitrary drawing functions for creation of soft masks. The resulting alpha
# channel is made of greyscale version of the drawing (luminosity channel to be
# precise). So while you can use any combination of colors for soft masks it's
Expand Down
1 change: 0 additions & 1 deletion prawn.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ Gem::Specification.new do |spec|
spec.add_development_dependency('pdf-inspector', '~> 1.2.1')
spec.add_development_dependency('yard')
spec.add_development_dependency('rspec', '~> 3.0')
spec.add_development_dependency('mocha')
spec.add_development_dependency('rake')
spec.add_development_dependency('simplecov')
spec.add_development_dependency('prawn-manual_builder', ">= 0.2.0")
Expand Down
24 changes: 0 additions & 24 deletions spec/acceptance/png.rb

This file was deleted.

35 changes: 35 additions & 0 deletions spec/acceptance/png_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# encoding: utf-8

require_relative "../../spec/spec_helper"

describe "When making a pdf file with png images" do
image_dir = "#{Prawn::BASEDIR}/data/images"
images = [
["Type 0", "#{image_dir}/web-links.png"],
["Type 0 with transparency", "#{image_dir}/ruport_type0.png"],
["Type 2", "#{image_dir}/ruport.png"],
["Type 2 with transparency", "#{image_dir}/arrow2.png"],
["Type 3", "#{image_dir}/indexed_color.png"],
["Type 3 with transparency", "#{image_dir}/indexed_transparency.png"],
["Type 4", "#{image_dir}/page_white_text.png"],
["Type 6", "#{image_dir}/dice.png"],
["Type 6 in 16bit", "#{image_dir}/16bit.png"]
]

images.each do |header, file|
describe "and the image is #{header}" do
it "does not error" do
expect do
Prawn::Document.generate("#{header}.pdf", :page_size => "A5") do
fill_color "00FF00"

fill_rectangle bounds.top_left, bounds.width, bounds.height
text header

image file, :at => [50, 450]
end
end.to_not raise_error
end
end
end
end
71 changes: 71 additions & 0 deletions spec/blend_mode_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# encoding: utf-8

require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")

module BlendModeHelper
def make_blend_mode(blend_mode)
@pdf.blend_mode(blend_mode) do
yield if block_given?
end
end
end

describe "Document with with blend_mode" do
include BlendModeHelper

it "the PDF version should be at least 1.4" do
create_pdf
make_blend_mode(:Multiply)
str = @pdf.render
expect(str[0, 8]).to eq("%PDF-1.4")
end

it "a new extended graphics state should be created for " \
"each unique blend mode setting" do
create_pdf
make_blend_mode(:Multiply) do
make_blend_mode(:Screen)
end
extgstates = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates
expect(extgstates.length).to eq(2)
end

it "a new extended graphics state should not be created for " \
"each duplicate blend mode setting" do
create_pdf
make_blend_mode(:Multiply) do
make_blend_mode(:Multiply)
end
extgstates = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates
expect(extgstates.length).to eq(1)
end

it "setting the blend mode with only one parameter sets a single blend mode value" do
create_pdf
make_blend_mode(:Multiply)
extgstate = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates.first
expect(extgstate[:blend_mode]).to eq(:Multiply)
end

it "setting the blend mode with multiple parameters sets an array of blend modes" do
create_pdf
make_blend_mode([:Multiply, :Screen, :Overlay])
extgstate = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates.first
expect(extgstate[:blend_mode]).to eq([:Multiply, :Screen, :Overlay])
end

describe "with more than one page" do
include BlendModeHelper

it "the extended graphic state resource should be added to both pages" do
create_pdf
make_blend_mode(:Multiply)
@pdf.start_new_page
make_blend_mode(:Multiply)
extgstates = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates
extgstate = extgstates[0]
expect(extgstates.length).to eq(2)
expect(extgstate[:blend_mode]).to eq(:Multiply)
end
end
end
Loading

0 comments on commit f8d75ff

Please sign in to comment.