class Lipstick::Images::LogoOnlyEmailBanner

Creates a logo-only email banner, with two elements.

  1. Logo, centered vertically and horizontally within the image.

  2. Environment string, stamped across the logo.

The math here seemed like it would be a lot simpler than the EmailBanner class, but then I went and made it all confusing by bringing trigonometry into it. I promise there was a good reason for doing it.

Constants

ANGLE_DEGREES
ANGLE_RADIANS
HEIGHT
MID_Y
WIDTH

Public Class Methods

new(image:, environment:, background_color:) click to toggle source
# File lib/lipstick/images/logo_only_email_banner.rb, line 14
def initialize(image:, environment:, background_color:)
  require 'rmagick'

  @environment = environment.upcase
  @image = image
  @background_color = background_color
end

Public Instance Methods

to_png() click to toggle source
# File lib/lipstick/images/logo_only_email_banner.rb, line 22
def to_png
  bgcolor = @background_color

  canvas = Magick::ImageList.new
  canvas.new_image(WIDTH, HEIGHT) do |f|
    f.format = 'PNG'
    f.background_color = bgcolor
  end

  canvas.composite!(logo, logo_x, logo_y, Magick::SrcOverCompositeOp)

  annotate_environment(canvas)

  canvas.to_blob
end

Private Instance Methods

annotate_environment(canvas) click to toggle source
# File lib/lipstick/images/logo_only_email_banner.rb, line 62
def annotate_environment(canvas)
  return if blank_environment?

  environment_format.annotate(canvas, 0, 0, env_x, env_y, @environment)
end
blank_environment?() click to toggle source
# File lib/lipstick/images/logo_only_email_banner.rb, line 58
def blank_environment?
  !@environment&.present?
end
env_metrics() click to toggle source
# File lib/lipstick/images/logo_only_email_banner.rb, line 90
def env_metrics
  return OpenStruct.new(width: 0, height: 0) if blank_environment?

  environment_format.get_type_metrics(@environment)
end
env_x() click to toggle source
# File lib/lipstick/images/logo_only_email_banner.rb, line 96
def env_x
  m = env_metrics

  # The horizontal width of the environment text is found by:
  # w cos(0) + h sin(0)
  #
  # w = text width
  # h = text ascent
  # 0 = angle of text rotation
  #
  # Contrary to the description in `EmailBanner`, since we're upper
  # casing the environment string here, we don't need to worry about text
  # descent.
  w = Math.cos(ANGLE_RADIANS) * m.width +
      Math.sin(ANGLE_RADIANS) * m.ascent

  # We center that the same as for `logo_x`
  ((WIDTH - w) / 2).round
end
env_y() click to toggle source
# File lib/lipstick/images/logo_only_email_banner.rb, line 116
def env_y
  m = env_metrics

  # The horizontal width of the environment text is found by:
  # w sin(0) + h cos(0)
  h = Math.sin(ANGLE_RADIANS) * m.width +
      Math.cos(ANGLE_RADIANS) * m.ascent

  # We use addition here instead of the usual subtraction, as the text
  # moves in the upward direction from the position we set.
  ((HEIGHT + h) / 2).round
end
environment_format() click to toggle source
# File lib/lipstick/images/logo_only_email_banner.rb, line 47
def environment_format
  @environment_format ||= Magick::Draw.new do |title|
    title.font_family = 'ArialB'
    title.font_weight = 900
    title.pointsize = 36
    title.gravity = Magick::ForgetGravity
    title.fill = '#bc2028'
    title.rotation = -1 * ANGLE_DEGREES
  end
end
gap() click to toggle source
# File lib/lipstick/images/logo_only_email_banner.rb, line 72
def gap
  @gap ||= environment_format.get_type_metrics('AAF').width
end
logo_w() click to toggle source
# File lib/lipstick/images/logo_only_email_banner.rb, line 76
def logo_w
  logo.bounding_box.width
end
logo_x() click to toggle source

x position to vertically center logo

# File lib/lipstick/images/logo_only_email_banner.rb, line 81
def logo_x
  ((WIDTH - logo.bounding_box.width) / 2).round
end
logo_y() click to toggle source

y position to vertically center logo

# File lib/lipstick/images/logo_only_email_banner.rb, line 86
def logo_y
  ((HEIGHT - logo.bounding_box.height) / 2).round
end