gnome-games r8870 - trunk/gnome-sudoku/src/lib
- From: thomashpa svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-games r8870 - trunk/gnome-sudoku/src/lib
- Date: Fri, 20 Mar 2009 01:15:56 +0000 (UTC)
Author: thomashpa
Date: Fri Mar 20 01:15:56 2009
New Revision: 8870
URL: http://svn.gnome.org/viewvc/gnome-games?rev=8870&view=rev
Log:
Port to use gtk print instead of deprecated gnomeprint. Fixes bug #564655
Modified:
trunk/gnome-sudoku/src/lib/game_selector.py
trunk/gnome-sudoku/src/lib/main.py
trunk/gnome-sudoku/src/lib/printing.py
trunk/gnome-sudoku/src/lib/sudoku_thumber.py
Modified: trunk/gnome-sudoku/src/lib/game_selector.py
==============================================================================
--- trunk/gnome-sudoku/src/lib/game_selector.py (original)
+++ trunk/gnome-sudoku/src/lib/game_selector.py Fri Mar 20 01:15:56 2009
@@ -3,7 +3,6 @@
import sudoku, saver, sudoku_maker, random
from sudoku import DifficultyRating as DR
import sudoku_thumber
-import gnomeprint
from gettext import gettext as _
from timer import format_time,format_date,format_friendly_date,format_time_compact
from defaults import *
@@ -292,19 +291,15 @@
) for puzzle,d in sudokus]
from printing import SudokuPrinter
sp = SudokuPrinter(sudokus,
- sudokus_per_page=self.sudokusPerPageSpinButton.get_adjustment().get_value(),
- dialog_parent=self.dialog)
+ self.dialog,
+ sudokus_per_page=self.sudokusPerPageSpinButton.get_adjustment().get_value())
+
self.sudokus_printed = sudokus
- sp.run()
- sp.dialog.connect('response',
- self.print_dialog_response_cb)
+ response = sp.print_op.run(gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG, sp.main_window)
- def print_dialog_response_cb (self, dialog, response):
- if response == gnomeprint.ui.DIALOG_RESPONSE_CANCEL:
- pass
- elif response == gnomeprint.ui.DIALOG_RESPONSE_PREVIEW:
+ if response == gtk.PRINT_OPERATION_RESULT_ERROR:
pass
- elif response==gnomeprint.ui.DIALOG_RESPONSE_PRINT:
+ elif response == gtk.PRINT_OPERATION_RESULT_APPLY:
if self.markAsPlayedToggle.get_active():
for sud,lab in self.sudokus_printed:
jar = {}
@@ -316,6 +311,5 @@
self.dialog.hide()
def run_dialog (self):
- #self.setup_dialog()
self.dialog.show()
Modified: trunk/gnome-sudoku/src/lib/main.py
==============================================================================
--- trunk/gnome-sudoku/src/lib/main.py (original)
+++ trunk/gnome-sudoku/src/lib/main.py Fri Mar 20 01:15:56 2009
@@ -815,7 +815,7 @@
@simple_debug
def print_game (self, *args):
- printing.print_sudokus([self.gsd])
+ printing.print_sudokus([self.gsd], self.w)
@simple_debug
def print_multiple_games (self, *args):
Modified: trunk/gnome-sudoku/src/lib/printing.py
==============================================================================
--- trunk/gnome-sudoku/src/lib/printing.py (original)
+++ trunk/gnome-sudoku/src/lib/printing.py Fri Mar 20 01:15:56 2009
@@ -1,271 +1,9 @@
# -*- coding: utf-8 -*-
-import gtk, gnomeprint, gnomeprint.ui, math
+import gtk, cairo
import sudoku, gsudoku
from gettext import gettext as _
from gettext import ngettext
-class GridDrawer:
-
- X = 0
- Y = 1
-
- def __init__ (self,
- gpc,
- grid_size=9,
- grid_side_size=500,
- start_at=(800,50),
- default_color=(0,0,0),
- label=None,
- label_font=('Arial','12'),
- ):
- self.gpc = gpc
- self.grid_size = grid_size
- self.label = label
- self.label_font=gnomeprint.font_find_closest(*label_font)
- self.grid_side_size = grid_side_size
- self.start_at = start_at
- self.increment = float(grid_side_size) / grid_size
- self.left_upper = start_at
- self.right_lower = self.left_upper[0]+self.grid_side_size,self.left_upper[1]-self.grid_side_size
- self.box_size = math.sqrt(grid_size)
- # get the right font size for our increment...
- self.increment * 0.7
- # start with our maximum font...
- max_size=36
- self.font = gnomeprint.font_find_closest('Sans Bold',max_size)
- self.default_color = default_color
- while self.font.get_width_utf8('1')> (self.increment * 0.4) and\
- self.font.get_ascender()> (self.increment * 0.4):
- max_size = max_size - 1
- self.font = gnomeprint.font_find_closest('Helvetica',
- max_size)
- self.THICK_WIDTH = 1 + float(max_size) / 8
- self.gpc.setfont(
- self.font
- )
- self.gpc.setrgbcolor(*self.default_color)
-
- def finish (self):
- self.gpc.showpage()
-
- def draw_label (self, x, y, label, font=None, color=None):
- if label:
- if type(label)!=str: print 'Funny... label ',label,'is a ',type(label)
- self.gpc.moveto(x,y)
- self.gpc.setfont(self.label_font)
- self.gpc.show(label)
- self.gpc.setfont(self.font) #reset
-
- def draw_number (self, x, y, val, font=None, color=None):
- if not font: font = self.font
- self.gpc.setfont(font)
- if color: self.gpc.setrgbcolor(*color)
- move_to = list(self.left_upper)
- char_w=font.get_width_utf8(str(val))
- char_h = font.get_ascender()
- move_to[self.X] += (self.increment * x + (self.increment - char_w)/2)
- move_to[self.Y] = move_to[self.Y] - (((y+1) * self.increment) - (self.increment - char_h)/2)
- self.gpc.moveto(*move_to)
- self.gpc.show(str(val))
- if color: self.gpc.setrgbcolor(*self.default_color) #unset color
-
- def draw_grid (self):
- for direction in self.X,self.Y:
- opposite = int(not direction)
- for n in range(self.grid_size+1):
- start_pos = list(self.left_upper)
- if direction==self.Y:
- start_pos[direction]=self.left_upper[direction]-self.increment*n
- else:
- start_pos[direction]=self.left_upper[direction]+self.increment*n
- # double the thickness of our borders and box borders...
- # e.g. 0, 3, 6, 9
- length_adjustment = 0
- if n % self.box_size == 0:
- self.gpc.setlinewidth(self.THICK_WIDTH)
- # correct start position to take into account our
- # width so that corners don't look funny.
- if True or n==0 or n==self.box_size:
- length_adjustment = self.THICK_WIDTH/2
- if direction==self.X:
- start_pos[direction] = start_pos[direction]+length_adjustment
- else:
- start_pos[direction] = start_pos[direction]-length_adjustment
- # get in position...
- self.gpc.moveto(*start_pos)
- # draw our line...
- dest_pos = start_pos
- if direction==self.Y:
- dest_pos[opposite]=dest_pos[opposite]+self.grid_side_size+length_adjustment*2
- else:
- dest_pos[opposite]=dest_pos[opposite]-self.grid_side_size-length_adjustment*2
- self.gpc.lineto(*dest_pos)
- self.gpc.stroke()
- # Reset our width to normal if need be...
- if n % self.box_size == 0: self.gpc.setlinewidth(1)
-
-class SudokuDrawer (GridDrawer):
- def __init__ (self,
- sudoku_grid, # A SudokuGrid, a InteractiveSudoku/SudokuSolver, or a SudokuGridDisplay
- gpc,
- grid_size=9,
- grid_side_size=500,
- start_at=(800,50),
- label=None,
- label_font=('Arial',12),
- ):
- """Draw a sudoku grid.
-
- If we're labelling, we put our label above the start_at
- """
- if isinstance(sudoku_grid,gsudoku.SudokuGameDisplay):
- self.sudoku_grid = sudoku_grid.grid
- self.sgd = sudoku_grid
- else:
- self.sudoku_grid = sudoku_grid
- self.sgd = None
- GridDrawer.__init__(self,
- gpc,
- grid_size=grid_size,
- grid_side_size=grid_side_size,
- start_at=start_at,
- label=label,
- label_font=label_font,
- )
- self.alt_font = gnomeprint.font_find_closest('Sans Italic',
- self.font.get_size()*0.85
- )
-
- self.alt_color = .4,.4,.4
-
- def draw_sudoku (self):
- if self.label: self.draw_label(self.start_at[0],
- self.start_at[1]+self.label_font.get_ascender(),
- self.label,)
- for x in range(self.grid_size):
- for y in range(self.grid_size):
- if isinstance(self.sudoku_grid,sudoku.SudokuSolver):
- val = self.sudoku_grid.virgin._get_(x,y)
- if val: self.draw_number(x,y,val)
- elif self.sudoku_grid._get_(x,y):
- if not self.sgd:
- color=self.alt_color
- else:
- trackers=self.sgd.trackers_for_point(x,y)
- if trackers:
- tracker=trackers[0]
- color=self.sgd.get_tracker_color(tracker)
- else:
- color = self.alt_color
- self.draw_number(
- x,y,
- self.sudoku_grid._get_(x,y),
- self.alt_font,
- color,
- )
- else:
- val = self.sudoku_grid._get_(x,y)
- if val: self.draw_number(x,y,val)
-
-MINIMUM_SQUARE_SIZE=135
-
-class SudokuPrinter:
- def __init__ (self,
- sudokus,
- margin=50,
- sudokus_per_page=None,
- dialog_parent=None
- ):
- self.drawn = False
- self.margin = margin
- self.sudokus_per_page=sudokus_per_page
- self.dialog_parent = dialog_parent
- try:
- self.nsudokus = len(sudokus) # number of sudokus we're printing
- except TypeError,AttributeError:
- sudokus = [sudokus] # assume they passed us one sudoku by
- self.nsudokus = 1 # mistake and be nice
- self.sudokus = sudokus
- self.job = gnomeprint.Job(gnomeprint.config_default())
-
- def run (self):
- self.dialog = gnomeprint.ui.Dialog(self.job,
- ngettext("Print Sudoku","Print Sudokus",
- self.nsudokus),
- 0)
- if self.dialog_parent: self.dialog.set_transient_for(self.dialog_parent)
- self.dialog.connect('response',self.response_cb)
- self.dialog.show()
-
- def response_cb (self, dialog, response):
- if response == gnomeprint.ui.DIALOG_RESPONSE_CANCEL:
- dialog.hide()
- elif response == gnomeprint.ui.DIALOG_RESPONSE_PREVIEW:
- if not self.drawn: self.draw_sudokus()
- w=gnomeprint.ui.JobPreview(self.job,_('Print Preview'))
- w.set_transient_for(dialog)
- w.set_property('allow-grow',1)
- w.set_property('allow-shrink',1)
- w.show_all()
- w.present()
- elif response == gnomeprint.ui.DIALOG_RESPONSE_PRINT:
- if not self.drawn: self.draw_sudokus()
- self.job.print_()
- dialog.hide()
-
-
- def draw_sudokus (self):
- self.gpc = self.job.get_context()
- width,height = gnomeprint.job_get_page_size_from_config(self.job.get_config())
- self.margin = 50
- top = height-self.margin
- bottom = self.margin
- left = self.margin
- right = width
- if not self.sudokus_per_page:
- self.sudokus_per_page = self.nsudokus
- dimensions, square_size = fit_squares_in_rectangle(width,height,self.sudokus_per_page,self.margin)
- while square_size < MINIMUM_SQUARE_SIZE:
- self.sudokus_per_page = self.sudokus_per_page - 1
- dimensions, square_size = fit_squares_in_rectangle(width,height,self.sudokus_per_page,self.margin)
- else:
- dimensions,square_size = fit_squares_in_rectangle(width,height,self.sudokus_per_page,self.margin)
- count = 0
- for sudoku in self.sudokus:
- if type(sudoku)==tuple:
- label = sudoku[1]
- sudoku = sudoku[0]
- else:
- label = None
- if count % self.sudokus_per_page == 0:
- if count: self.gpc.showpage()
- self.gpc.beginpage('%s'%(count/self.sudokus_per_page+1))
- pos = [1,1]
- left_start,top_start=self.margin,top
- else:
- # move from left to right, top to bottom
- if pos[0] < dimensions[0]:
- left_start = left_start + square_size + self.margin
- pos[0] += 1
- else:
- top_start = top_start - square_size - self.margin # down ...
- left_start = self.margin # ...and to the left
- pos[0] = 1
- pos[1] += 1
- drawer = SudokuDrawer(sudoku,
- self.gpc,
- start_at=(left_start,top_start),
- grid_side_size=square_size,
- label=label
- )
- drawer.draw_grid()
- drawer.draw_sudoku()
- count += 1
- if count: self.gpc.showpage()
- self.job.close()
- self.drawn = True
-
-
def fit_squares_in_rectangle (width, height, n, margin=0):
"""Optimally fit squares into a rectangle.
@@ -294,8 +32,83 @@
best_fit = n_across,n_down
if best_fit:
return best_fit,best_square_size
-
+
+class SudokuPrinter:
+ def __init__ (self,
+ sudokus,
+ main_window,
+ margin=50,
+ sudokus_per_page=1,
+ ):
+ self.drawn = False
+ self.margin = margin
+ self.sudokus_per_page=sudokus_per_page
+ self.n_sudokus = len(sudokus)
+ self.sudokus = sudokus
+ self.print_op = gtk.PrintOperation()
+ self.print_op.connect( "begin-print", self.begin_print)
+ self.print_op.connect("draw-page", self.draw_page)
+ self.main_window = main_window
+
+ def begin_print(self, operation, context):
+ import math
+ pages = int(math.ceil(self.n_sudokus / self.sudokus_per_page))
+ operation.set_n_pages(pages)
+
+ def draw_page(self, operation, context, page_nr):
+ import pango
+ import sudoku_thumber
+
+ margin = 25
+ cr = context.get_cairo_context()
+ width = context.get_width()
+ height = context.get_height()
+
+ best_fit,best_square_size = fit_squares_in_rectangle(width, height, self.sudokus_per_page, margin)
+
+ start = int(page_nr*self.sudokus_per_page)
+ sudokus_on_page = self.sudokus[start : start+int(self.sudokus_per_page)]
+
+ left = margin
+ top = margin
+ pos = [1,1]
+ for sudoku in sudokus_on_page:
+ if type(sudoku)==tuple:
+ label = sudoku[1]
+ sudoku = sudoku[0]
+ else:
+ label = ""
+
+ cr.set_font_size(12)
+ cr.select_font_face("", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
+ cr.set_source_rgb(0,0,0)
+ xbearing, ybearing, width, height, xadvance, yadvance = cr.text_extents(label)
+ cr.move_to(left, top-height/2)
+ cr.show_text(label)
+
+ if isinstance(sudoku, gsudoku.SudokuGameDisplay):
+ sudoku = sudoku.grid
+
+ sudoku_thumber.draw_sudoku (cr, sudoku.grid, None, best_square_size, left, top)
+ if pos[0] < best_fit[0]:
+ left = left + best_square_size + margin
+ pos[0] += 1
+ else:
+ top = top + best_square_size + margin
+ left = margin
+ pos[0] = 1
+ pos[1] += 1
+
+
def print_sudokus(*args,**kwargs):
sp = SudokuPrinter(*args,**kwargs)
- sp.run()
+ res = sp.print_op.run(gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG, sp.main_window)
+ if res == gtk.PRINT_OPERATION_RESULT_ERROR:
+ error_dialog = gtk.MessageDialog(main_window,
+ gtk.DIALOG_DESTROY_WITH_PARENT,
+ gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_CLOSE,
+ "Error printing file:\n")
+ error_dialog.connect("response", lambda w,id: w.destroy())
+ error_dialog.show()
Modified: trunk/gnome-sudoku/src/lib/sudoku_thumber.py
==============================================================================
--- trunk/gnome-sudoku/src/lib/sudoku_thumber.py (original)
+++ trunk/gnome-sudoku/src/lib/sudoku_thumber.py Fri Mar 20 01:15:56 2009
@@ -5,54 +5,75 @@
SUDOKU_SIZE = 9
N_BOXES = 3
-FONT_SIZE = 9
-SQUARE_SIZE = 11
-THICK = 2 #SIZE/33 or 1
-BORDER = THICK*2
-THIN = 1 #SIZE/100 or 1
+
PENCIL_GREY = (0.3,0.3,0.3)
-LINE_GREY = (0.4,0.4,0.4)
-SIZE = (
- (2 * (BORDER+THICK)) # OUTER BORDER
- +
- ((N_BOXES - 1) * THICK) # INNER THICK LINES
- +
- (SQUARE_SIZE * SUDOKU_SIZE) # WHITE SPACE IN SQUARES
- +
- (SUDOKU_SIZE - N_BOXES - 1)
- )
-
-(SQUARE_SIZE * SUDOKU_SIZE) + (N_BOXES)*THICK + (SUDOKU_SIZE-N_BOXES)*THIN
+BACKGROUND_COLOR = (1.,1.,1.)
-sudoku = [[0, 0, 2, 3, 4, 5, 6, 0, 0]]*SUDOKU_SIZE
-played = [[1,2,0,0,0,0,0,0,0,0]]+[[0,0,0,0,0,0,0,0,0,0]]*8
+def draw_sudoku (cr, sudoku, played, size, offset_x=0, offset_y=0, border_color=(1.0,1.0,1.0), line_color=(0.0,0.0,0.0)):
-def make_image_surface (sudoku, played, highlight_color):
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, SIZE, SIZE)
- cr = cairo.Context(surface)
- cr.set_line_width(BORDER)
+ THIN = size / 100.
+ THICK = THIN * 2.
+ BORDER = THICK
+
+ WHITE_SPACE = (size
+ - 2 * BORDER
+ - 2 * THICK
+ - (N_BOXES - 1) * THICK
+ - (N_BOXES * 2) * THIN
+ )
+
+ SQUARE_SIZE = WHITE_SPACE / SUDOKU_SIZE
+ FONT_SIZE = SQUARE_SIZE
+
+ outer = {}
+ outer["left"] = offset_x
+ outer["right"] = offset_x + size
+ outer["top"] = offset_y
+ outer["bottom"] = offset_y + size
+
+ # Entire background
+ cr.set_source_rgb(1.,1.,1.)
+ cr.rectangle(outer["left"],
+ outer["top"],
+ size,
+ size)
+ cr.fill()
+
+ # Outer border
cr.set_line_join(cairo.LINE_JOIN_ROUND)
- cr.rectangle(BORDER*.5,
- BORDER*.5,
- (SIZE-(BORDER)),
- (SIZE-(BORDER)),
- )
- cr.set_source_rgb(1,1,1)
+ cr.set_line_width(BORDER)
+ cr.rectangle(outer["left"] + BORDER/2.0,
+ outer["top"] + BORDER/2.0,
+ size - BORDER,
+ size - BORDER)
+
+ # Inner background
+ cr.set_source_rgb(*BACKGROUND_COLOR)
cr.fill_preserve()
- cr.set_source_rgb(*highlight_color)
+ #Border box
+ cr.set_source_rgb(*border_color)
cr.stroke()
- cr.set_source_rgb(*LINE_GREY)
+
+ #Outer thick lines
+ cr.set_line_join(cairo.LINE_JOIN_MITER)
cr.set_line_width(THICK)
- cr.rectangle(BORDER,
- BORDER,
- (SIZE-(BORDER+2*THICK)),
- (SIZE-(BORDER+2*THICK)),
- )
+ cr.rectangle(outer["left"] + BORDER + THICK/2.0,
+ outer["top"] + BORDER + THICK/2.0,
+ size - BORDER*2 - THICK,
+ size - BORDER*2 - THICK)
+
+ cr.set_source_rgb(*line_color)
cr.stroke()
- small_size = SIZE / float(SUDOKU_SIZE)
- position = BORDER + THICK
+
+ inner = {}
+ inner["left"] = outer["left"] + BORDER + THICK
+ inner["right"] = outer["right"] - BORDER - THICK
+ inner["top"] = outer["top"] + BORDER + THICK
+ inner["bottom"] = outer["bottom"] - BORDER - THICK
+
pos = {}
- pos[0] = position + (SQUARE_SIZE/2.0)
+ position = BORDER + THICK
+ pos[0] = position + SQUARE_SIZE/2.
last_line = 0
for n in range(1,SUDOKU_SIZE):
if n % N_BOXES == 0:
@@ -63,18 +84,18 @@
cr.set_line_width(THIN)
position += SQUARE_SIZE + last_line/2.0 + THIN/2.0
last_line = THIN
- pos[n] = position + ((last_line + SQUARE_SIZE)/2.0)
- cr.move_to(BORDER,position)
- cr.line_to(SIZE-BORDER,position)
- cr.move_to(position,BORDER)
- cr.line_to(position,SIZE-BORDER)
+ pos[n] = position + last_line/2. + SQUARE_SIZE/2.0
+ cr.move_to(BORDER+THICK/2.+offset_x, position+offset_y)
+ cr.line_to(size-BORDER-THICK/2.+offset_x, position+offset_y)
+ cr.move_to(position+offset_x, BORDER+THICK/2.+offset_y)
+ cr.line_to(position+offset_x, size-BORDER-THICK/2.+offset_y)
cr.stroke()
cr.set_font_size(FONT_SIZE)
for x in range(SUDOKU_SIZE):
for y in range(SUDOKU_SIZE):
- cr.move_to(pos[x],pos[y])
+ cr.move_to(pos[x]+offset_x,pos[y]+offset_y)
letter = None
- if sudoku[y][x]:
+ if sudoku and sudoku[y][x]:
letter = str(sudoku[y][x])
cr.select_font_face("",
cairo.FONT_SLANT_NORMAL,
@@ -94,15 +115,40 @@
cr.text_extents(letter)
)
if letter:
- cr.move_to(pos[x]-(xadvance/2.0),
- pos[y]+(height/2.0))
+ cr.move_to(pos[x]+offset_x-(xadvance/2.0),
+ pos[y]+offset_y+(height/2.0))
cr.show_text(letter)
- return surface
-def make_pixbuf (sudoku, played, highlight_color):
- surf = make_image_surface(sudoku,played,highlight_color)
- pixbuf = gtk.gdk.pixbuf_new_from_data(surf.get_data(), gtk.gdk.COLORSPACE_RGB,
- True, 8, SIZE, SIZE, SIZE*4)
- del surf
+def make_pixbuf (sudoku, played, border_color, line_color=(0.4,0.4,0.4)):
+ size = 120
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, size, size)
+ cr = cairo.Context(surface)
+ draw_sudoku(cr, sudoku, played, size, 0, 0, border_color, line_color)
+ pixbuf = gtk.gdk.pixbuf_new_from_data(surface.get_data(), gtk.gdk.COLORSPACE_RGB,
+ True, 8, surface.get_width(), surface.get_height(), surface.get_stride())
+ del surface
return pixbuf
+if __name__ == "__main__":
+ sudoku = [[0, 0, 2, 3, 4, 5, 6, 0, 0]]*SUDOKU_SIZE
+ played = [[1,2,0,0,0,0,0,0,0,0]]+[[0,0,0,0,0,0,0,0,0,0]]*8
+
+
+ size = 250
+ line_color=(0.0,0.0,0.0)
+ border_color=(1.0,0.0,0.0)
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 750, 750)
+ cr = cairo.Context(surface)
+ draw_sudoku(cr, sudoku, played, size, 100, 250, border_color, line_color)
+ pb = gtk.gdk.pixbuf_new_from_data(surface.get_data(), gtk.gdk.COLORSPACE_RGB,
+ True, 8, surface.get_width(), surface.get_height(), surface.get_stride())
+ del surface
+
+
+ w = gtk.Window()
+ img = gtk.Image()
+ img.set_from_pixbuf(pb)
+ w.add(img)
+ w.show_all()
+ gtk.main()
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]