From 68c39139f742315c9d8050383c91b736ce1d74e6 Mon Sep 17 00:00:00 2001
From: Paolo Capriotti
Date: Fri, 19 Jun 2009 21:27:21 +0200
Subject: [PATCH] Improved shogi theme. Add shadows.
---
lib/ext/loader.rb | 6 +++-
lib/mainwindow.rb | 4 +--
lib/qtutils.rb | 20 ++++++-----
lib/themes/celtic/celtic.rb | 11 +++---
lib/themes/fantasy/fantasy.rb | 11 +++---
lib/themes/loader.rb | 2 +-
lib/themes/shadow.rb | 46 +++++++++++++++++++++++++
lib/themes/shogi/nude_tile.svg | 76 ++++++++++++++++++++++++++++++++----------
lib/themes/shogi/shogi.rb | 44 +++++++++++++++++-------
lib/themes/svg_theme.rb | 14 +++++---
lib/themes/theme.rb | 2 +-
11 files changed, 181 insertions(+), 55 deletions(-)
create mode 100644 lib/themes/shadow.rb
diff --git a/lib/ext/loader.rb b/lib/ext/loader.rb
index 18a13e0..a9415c2 100644
--- a/lib/ext/loader.rb
+++ b/lib/ext/loader.rb
@@ -6,13 +6,17 @@ rescue LoadError => e
end
$ext = $qApp.findChild(Qt::Object, "kaya extensions") if $qApp
-unless $ext
+fake = unless $ext
# install fake implementations of the extension functions
$ext = Qt::Object.new
class << $ext
def exp_blur(img, radius)
end
end
+ true
+end
+$ext.metaclass_eval do
+ define_method(:fake) { fake }
end
# conveniently install extension functions in the appropriate places
diff --git a/lib/mainwindow.rb b/lib/mainwindow.rb
index d3d9bfa..70aea68 100644
--- a/lib/mainwindow.rb
+++ b/lib/mainwindow.rb
@@ -33,8 +33,8 @@ private
config = KDE::Global.config.group('themes')
theme = Theme.new
- theme.pieces = @loader.get_matching(nil, game,
- (game.keywords || []) + ['pieces'], [])
+ theme.pieces = @loader.get_matching('Celtic', game,
+ (game.keywords || []) + ['pieces'], [], :shadow => true)
theme.board = @loader.get_matching(nil, game,
['board'], game.keywords || [])
diff --git a/lib/qtutils.rb b/lib/qtutils.rb
index 9d854cf..475d702 100644
--- a/lib/qtutils.rb
+++ b/lib/qtutils.rb
@@ -43,6 +43,17 @@ class Qt::Image
Qt::Painter.new(img).paint(&blk)
end
end
+
+ def self.from_renderer(size, renderer, id = nil)
+ img = Qt::Image.painted(size) do |p|
+ if id
+ renderer.render(p, id)
+ else
+ renderer.render(p)
+ end
+ end
+ img
+ end
end
module PrintablePoint
@@ -95,14 +106,7 @@ class Qt::Pixmap
end
def self.from_renderer(size, renderer, id = nil)
- img = Qt::Image.painted(size) do |p|
- if id
- renderer.render(p, id)
- else
- renderer.render(p)
- end
- end
- img.to_pix
+ Qt::Image.from_renderer(size, renderer, id).to_pix
end
end
diff --git a/lib/themes/celtic/celtic.rb b/lib/themes/celtic/celtic.rb
index aea0c92..e55a387 100644
--- a/lib/themes/celtic/celtic.rb
+++ b/lib/themes/celtic/celtic.rb
@@ -1,12 +1,15 @@
require 'qtutils'
require 'themes/svg_theme'
-class CelticTheme
- include SvgTheme
-
+class CelticTheme < SvgTheme
+ include Theme
theme :name => 'Celtic',
:keywords => %w(chess pieces)
-
+
+ def initialize(opts = {})
+ super(opts)
+ end
+
def filename
File.join(File.dirname(__FILE__), 'celtic.svg')
end
diff --git a/lib/themes/fantasy/fantasy.rb b/lib/themes/fantasy/fantasy.rb
index 44c1475..f6671c9 100644
--- a/lib/themes/fantasy/fantasy.rb
+++ b/lib/themes/fantasy/fantasy.rb
@@ -1,12 +1,15 @@
require 'qtutils'
require 'themes/svg_theme'
-class FantasyTheme
- include SvgTheme
-
+class FantasyTheme < SvgTheme
+ include Theme
theme :name => 'Fantasy',
:keywords => %w(chess pieces)
-
+
+ def initialize(opts = {})
+ super(opts)
+ end
+
def filename
File.join(File.dirname(__FILE__), 'fantasy.svg')
end
diff --git a/lib/themes/loader.rb b/lib/themes/loader.rb
index b3b00d5..8555300 100644
--- a/lib/themes/loader.rb
+++ b/lib/themes/loader.rb
@@ -13,7 +13,7 @@ class ThemeLoader
@themes = {}
ObjectSpace::each_object(Class) do |k|
- if k.include? Theme
+ if k.include?(Theme) and k.theme_name
@themes[k.theme_name] = k
end
end
diff --git a/lib/themes/shadow.rb b/lib/themes/shadow.rb
new file mode 100644
index 0000000..4dbdbb8
--- /dev/null
+++ b/lib/themes/shadow.rb
@@ -0,0 +1,46 @@
+require 'ext/loader'
+
+module Shadower
+ ShadowData = Struct.new(:radius, :color, :grow, :offset)
+ DEFAULT_SHADOW_DATA =
+ ShadowData.new(7.0, Qt::Color.new(0x40, 0x40, 0x50), 5, Qt::PointF.new(6, 4))
+
+ def with_shadow(loader, data = DEFAULT_SHADOW_DATA)
+ lambda do |piece, size|
+ isz = size * 100 / (100 + data.grow) + Qt::PointF.new(0.5, 0.5)
+ off = Qt::PointF.new(
+ data.offset.x * isz.x / 200.0,
+ data.offset.y * isz.x / 200.0)
+ img = loader[piece, isz]
+ scaled_data = ShadowData.new(data.radius * isz.x / 100.0,
+ data.color,
+ size.x - isz.x,
+ off)
+ s = shadow(img, scaled_data)
+ Qt::Painter.new(s).paint do |p|
+ dst = Qt::RectF.new((size.x - isz.x) / 2 - off.x,
+ (size.y - isz.y) / 2 - off.y,
+ isz.x, isz.y)
+ p.draw_image(dst, img, Qt::RectF.new(Qt::PointF.new(0, 0), isz))
+ end
+ s
+ end
+ end
+
+ private
+
+ def shadow(img, data)
+ img = Qt::Image.painted(Qt::Point.new(img.width + data.grow,
+ img.height + data.grow)) do |p|
+ px = (data.grow * 0.5 + data.offset.x).to_i
+ py = (data.grow * 0.5 + data.offset.y).to_i
+
+ p.composition_mode = Qt::Painter::CompositionMode_Source
+ p.fill_rect Qt::Rect.new(px, py, img.width, img.height), data.color
+ p.composition_mode = Qt::Painter::CompositionMode_DestinationAtop
+ p.draw_image Qt::Point.new(px, py), img
+ end
+ img.exp_blur(data.radius)
+ img
+ end
+end
diff --git a/lib/themes/shogi/nude_tile.svg b/lib/themes/shogi/nude_tile.svg
index 0d1074e..cab3227 100644
--- a/lib/themes/shogi/nude_tile.svg
+++ b/lib/themes/shogi/nude_tile.svg
@@ -1,11 +1,12 @@
diff --git a/lib/themes/shogi/shogi.rb b/lib/themes/shogi/shogi.rb
index 2592b19..3ce8c76 100644
--- a/lib/themes/shogi/shogi.rb
+++ b/lib/themes/shogi/shogi.rb
@@ -1,30 +1,50 @@
require 'qtutils'
require 'themes/theme'
+require 'themes/shadow'
class ShogiTheme
include Theme
+ include Shadower
+
BASE_DIR = File.dirname(__FILE__)
TYPES = { :knight => 'n' }
NUDE_TILE = File.join(BASE_DIR, 'nude_tile.svg')
+ RATIOS = {
+ :king => 1.0,
+ :rook => 0.96,
+ :bishop => 0.93,
+ :gold => 0.9,
+ :silver => 0.9,
+ :knight => 0.86,
+ :lance => 0.83,
+ :pawn => 0.8 }
theme :name => 'Shogi',
:keywords => %w(shogi pieces)
- def initialize(opts)
+ def initialize(opts = {})
+ @loader = lambda do |piece, size|
+ tile = Qt::SvgRenderer.new(NUDE_TILE)
+ kanji = Qt::SvgRenderer.new(filename(piece))
+ ratio = RATIOS[piece.type] || 0.9
+ img = Qt::Image.painted(size) do |p|
+ p.scale(ratio, ratio)
+ p.translate(size * (1 - ratio) / 2)
+ if piece.color == :white
+ p.translate(size)
+ p.rotate(180)
+ end
+ tile.render(p)
+ kanji.render(p)
+ end
+ end
+ if opts.has_key? :shadow
+ @loader = with_shadow(@loader)
+ end
end
def pixmap(piece, size)
- tile = Qt::SvgRenderer.new(NUDE_TILE)
- kanji = Qt::SvgRenderer.new(filename(piece))
- img = Qt::Image.painted(size) do |p|
- if piece.color == :white
- p.translate(size)
- p.rotate(180)
- end
- kanji.render(p)
- tile.render(p)
- end
- img.to_pix
+ @loader[piece, size].to_pix
end
def filename(piece)
diff --git a/lib/themes/svg_theme.rb b/lib/themes/svg_theme.rb
index f4eec78..874ca51 100644
--- a/lib/themes/svg_theme.rb
+++ b/lib/themes/svg_theme.rb
@@ -1,14 +1,20 @@
require 'qtutils'
require 'themes/theme'
-module SvgTheme
- include Theme
+class SvgTheme
+ include Shadower
- def initialize(opts)
+ def initialize(opts = {})
+ @loader = lambda do |piece, size|
+ Qt::Image.from_renderer(size, renderer, piece_id(piece))
+ end
+ if opts.has_key?(:shadow)
+ @loader = with_shadow(@loader)
+ end
end
def pixmap(piece, size)
- Qt::Pixmap.from_renderer(size, renderer, piece_id(piece))
+ @loader[piece, size].to_pix
end
def renderer
diff --git a/lib/themes/theme.rb b/lib/themes/theme.rb
index 2217388..fadf3fc 100644
--- a/lib/themes/theme.rb
+++ b/lib/themes/theme.rb
@@ -15,7 +15,7 @@ module Theme
end
def theme_name
- (@theme_data || {})[:name] || name
+ @theme_data[:name] if @theme_data
end
def matches?(keywords)
--
2.11.4.GIT