diff --git a/data/images/cards/bottoms/french/bottom03-n.png b/data/images/cards/bottoms/french/bottom03-n.png new file mode 100644 index 00000000..c3b8ef87 Binary files /dev/null and b/data/images/cards/bottoms/french/bottom03-n.png differ diff --git a/data/images/cards/bottoms/french/bottom03.png b/data/images/cards/bottoms/french/bottom03.png new file mode 100644 index 00000000..f4ed9636 Binary files /dev/null and b/data/images/cards/bottoms/french/bottom03.png differ diff --git a/data/images/cards/bottoms/french/bottom04-n.png b/data/images/cards/bottoms/french/bottom04-n.png new file mode 100644 index 00000000..5606124a Binary files /dev/null and b/data/images/cards/bottoms/french/bottom04-n.png differ diff --git a/data/images/cards/bottoms/french/bottom04.png b/data/images/cards/bottoms/french/bottom04.png new file mode 100644 index 00000000..2a7859c9 Binary files /dev/null and b/data/images/cards/bottoms/french/bottom04.png differ diff --git a/data/images/cards/bottoms/french/bottom05-n.png b/data/images/cards/bottoms/french/bottom05-n.png new file mode 100644 index 00000000..b0d9380a Binary files /dev/null and b/data/images/cards/bottoms/french/bottom05-n.png differ diff --git a/data/images/cards/bottoms/french/bottom05.png b/data/images/cards/bottoms/french/bottom05.png new file mode 100644 index 00000000..c529dfaa Binary files /dev/null and b/data/images/cards/bottoms/french/bottom05.png differ diff --git a/data/images/cards/bottoms/french/bottom06-n.png b/data/images/cards/bottoms/french/bottom06-n.png new file mode 100644 index 00000000..b4571ca7 Binary files /dev/null and b/data/images/cards/bottoms/french/bottom06-n.png differ diff --git a/data/images/cards/bottoms/french/bottom06.png b/data/images/cards/bottoms/french/bottom06.png new file mode 100644 index 00000000..37346fb7 Binary files /dev/null and b/data/images/cards/bottoms/french/bottom06.png differ diff --git a/data/images/cards/bottoms/french/bottom07-n.png b/data/images/cards/bottoms/french/bottom07-n.png new file mode 100644 index 00000000..3c62c3f7 Binary files /dev/null and b/data/images/cards/bottoms/french/bottom07-n.png differ diff --git a/data/images/cards/bottoms/french/bottom07.png b/data/images/cards/bottoms/french/bottom07.png new file mode 100644 index 00000000..aa950160 Binary files /dev/null and b/data/images/cards/bottoms/french/bottom07.png differ diff --git a/data/images/cards/bottoms/french/l01-n.png b/data/images/cards/bottoms/french/l01-n.png new file mode 100644 index 00000000..7a3ca2d4 Binary files /dev/null and b/data/images/cards/bottoms/french/l01-n.png differ diff --git a/data/images/cards/bottoms/french/l01.png b/data/images/cards/bottoms/french/l01.png new file mode 100644 index 00000000..02bd14a6 Binary files /dev/null and b/data/images/cards/bottoms/french/l01.png differ diff --git a/data/images/cards/bottoms/french/l02-n.png b/data/images/cards/bottoms/french/l02-n.png new file mode 100644 index 00000000..cd9da745 Binary files /dev/null and b/data/images/cards/bottoms/french/l02-n.png differ diff --git a/data/images/cards/bottoms/french/l02.png b/data/images/cards/bottoms/french/l02.png new file mode 100644 index 00000000..2a96f794 Binary files /dev/null and b/data/images/cards/bottoms/french/l02.png differ diff --git a/data/images/cards/bottoms/french/l03-n.png b/data/images/cards/bottoms/french/l03-n.png new file mode 100644 index 00000000..e812ca9b Binary files /dev/null and b/data/images/cards/bottoms/french/l03-n.png differ diff --git a/data/images/cards/bottoms/french/l03.png b/data/images/cards/bottoms/french/l03.png new file mode 100644 index 00000000..8287d3a6 Binary files /dev/null and b/data/images/cards/bottoms/french/l03.png differ diff --git a/data/images/cards/bottoms/french/l04-n.png b/data/images/cards/bottoms/french/l04-n.png new file mode 100644 index 00000000..d2ca90b6 Binary files /dev/null and b/data/images/cards/bottoms/french/l04-n.png differ diff --git a/data/images/cards/bottoms/french/l04.png b/data/images/cards/bottoms/french/l04.png new file mode 100644 index 00000000..493a0f56 Binary files /dev/null and b/data/images/cards/bottoms/french/l04.png differ diff --git a/pysollib/game.py b/pysollib/game.py index 3c7161db..efe15ec8 100644 --- a/pysollib/game.py +++ b/pysollib/game.py @@ -78,9 +78,10 @@ class Game: S_INIT = 0x00 S_DEAL = 0x10 S_FILL = 0x20 - S_PLAY = 0x30 - S_UNDO = 0x40 - S_REDO = 0x50 + S_RESTORE = 0x30 + S_PLAY = 0x40 + S_UNDO = 0x50 + S_REDO = 0x60 # for loading and saving - subclasses should override if # the format for a saved game changed (see also canLoadGame()) @@ -504,6 +505,8 @@ class Game: self.snapshots = game.snapshots # 3) move cards to stacks assert len(self.allstacks) == len(game.loadinfo.stacks) + old_state = game.moves.state + game.moves.state = self.S_RESTORE for i in range(len(self.allstacks)): for t in game.loadinfo.stacks[i]: card_id, face_up = t @@ -513,6 +516,7 @@ class Game: else: card.showBack() self.allstacks[i].addCard(card) + game.moves.state = old_state # 4) update settings for stack_id, cap in self.saveinfo.stack_caps: ##print stack_id, cap diff --git a/pysollib/games/picturegallery.py b/pysollib/games/picturegallery.py index 7adfb95a..05384854 100644 --- a/pysollib/games/picturegallery.py +++ b/pysollib/games/picturegallery.py @@ -137,7 +137,7 @@ class PictureGallery_Foundation(RK_FoundationStack): def closeStack(self): if len(self.cards) == 8: - if not self.game.moves.state == self.game.S_REDO: + if self.game.moves.state not in (self.game.S_REDO, self.game.S_RESTORE): self.game.flipAllMove(self) def canFlipCard(self): diff --git a/pysollib/images.py b/pysollib/images.py index 4a1fb46e..4377ac32 100644 --- a/pysollib/images.py +++ b/pysollib/images.py @@ -24,13 +24,15 @@ # imports import os +import traceback # PySol imports +from resource import CSI from settings import TOOLKIT from mfxutil import Image, ImageTk # Toolkit imports -from pysoltk import loadImage, copyImage, createImage, shadowImage +from pysoltk import loadImage, copyImage, createImage, shadowImage, createBottom # ************************************************************************ @@ -54,6 +56,9 @@ class Images: self.reduced = r if cs is None: return + self.use_pil = False + if TOOLKIT == 'tk' and Image and Image.VERSION >= '1.1.7': + self.use_pil = True # copy from cardset self.CARDW, self.CARDH, self.CARDD = cs.CARDW/r, cs.CARDH/r, cs.CARDD/r self.CARD_XOFFSET = cs.CARD_XOFFSET @@ -89,7 +94,10 @@ class Images: f = os.path.join(self.cs.dir, filename) if not os.path.exists(f): return None - img = loadImage(file=f) + try: + img = loadImage(file=f) + except: + return None w, h = img.width(), img.height() if self.CARDW < 0: self.CARDW, self.CARDH = w, h @@ -99,6 +107,26 @@ class Images: raise ValueError("Invalid size %dx%d of image %s" % (w, h, f)) return img + def __loadBottom(self, filename, check_w=1, check_h=1, color='white'): + cs_type = CSI.TYPE_ID[self.cs.type] + imagedir = None + d = os.path.join('images', 'cards', 'bottoms') + try: + imagedir = self.d.findDir(cs_type, d) + except: + pass + if not self.use_pil or imagedir is None: + # load image + return self.__loadCard(filename+self.cs.ext, check_w, check_h) + # create image + d = os.path.join('images', 'cards', 'bottoms', cs_type) + try: + fn = self.d.findImage(filename, d) + except: + fn = None + img = createBottom(self._card[0], color, fn) + return img + def __addBack(self, im1, name): r = max(self.CARDW / 40.0, self.CARDH / 60.0) r = max(2, int(round(r))) @@ -133,20 +161,12 @@ class Images: self._letter_negative.append(neg_bottom) self._blank_bottom = createImage(self.CARDW, self.CARDH, fill=None, outline=None) - def load(self, app, progress=None, fast=0): - ##fast = 1 - ##fast = 2 - if fast > 1: - # only for testing - self.cs.backnames = () - self.cs.nbottoms = 0 - self.cs.nletters = 0 + def load(self, app, progress=None): ext = self.cs.ext[1:] pstep = 0 if progress: pstep = self.cs.ncards + len(self.cs.backnames) + self.cs.nbottoms + self.cs.nletters - if not fast: - pstep = pstep + self.cs.nshadows + 1 # shadows & shade + pstep += self.cs.nshadows + 1 # shadows & shade pstep = max(0, (80.0 - progress.percent) / pstep) # load face cards for n in self.cs.getFaceCardNames(): @@ -157,73 +177,41 @@ class Images: # load backgrounds for name in self.cs.backnames: if name: - try: - im = self.__loadCard(name) - self.__addBack(im, name) - except: - pass + im = self.__loadCard(name) + self.__addBack(im, name) if progress: progress.update(step=1) # load bottoms for i in range(self.cs.nbottoms): - try: - name = "bottom%02d.%s" % (i + 1, ext) - self._bottom_positive.append(self.__loadCard(name)) - except: - pass + name = "bottom%02d" % (i + 1) + self._bottom_positive.append(self.__loadBottom(name, color='black')) if progress: progress.update(step=pstep) # load negative bottoms - try: - name = "bottom%02d-n.%s" % (i + 1, ext) - self._bottom_negative.append(self.__loadCard(name)) - except: - pass + name = "bottom%02d-n" % (i + 1) + self._bottom_negative.append(self.__loadBottom(name, color='white')) if progress: progress.update(step=pstep) # load letters for rank in range(self.cs.nletters): - try: - name = "l%02d.%s" % (rank + 1, ext) - self._letter_positive.append(self.__loadCard(name)) - except: - pass + name = "l%02d" % (rank + 1) + self._letter_positive.append(self.__loadBottom(name, color='black')) if progress: progress.update(step=pstep) # load negative letters - try: - name = "l%02d-n.%s" % (rank + 1, ext) - self._letter_negative.append(self.__loadCard(name)) - except: - pass + name = "l%02d-n" % (rank + 1) + self._letter_negative.append(self.__loadBottom(name, color='white')) if progress: progress.update(step=pstep) # shadow - if TOOLKIT == 'tk' and Image and Image.VERSION >= '1.1.7': - if 0: - fn = self.d.findImage('shadow', 'images') - self._pil_shadow_image = Image.open(fn).convert('RGBA') - else: + if not self.use_pil: for i in range(self.cs.nshadows): - if fast: - self._shadow.append(None) - else: - name = "shadow%02d.%s" % (i, ext) - try: - im = self.__loadCard(name, check_w=0, check_h=0) - except: - im = None - self._shadow.append(im) - - if fast: - self._xshadow.append(None) - elif i > 0: # skip 0 + name = "shadow%02d.%s" % (i, ext) + im = self.__loadCard(name, check_w=0, check_h=0) + self._shadow.append(im) + if i > 0: # skip 0 name = "xshadow%02d.%s" % (i, ext) - try: - im = self.__loadCard(name, check_w=0, check_h=0) - except: - im = None + im = self.__loadCard(name, check_w=0, check_h=0) self._xshadow.append(im) - if progress: progress.update(step=pstep) # shade - if fast: - self._shade.append(None) + if self.use_pil: + self._shade.append(self._getShadow(self._card[0], None, '#3896f8')) else: self._shade.append(self.__loadCard("shade." + ext)) if progress: progress.update(step=pstep) @@ -233,7 +221,6 @@ class Images: self._bottom = self._bottom_positive self._letter = self._letter_positive # - return 1 def getFace(self, deck, suit, rank): @@ -304,46 +291,13 @@ class Images: im = c._active_image._pil_image mask.paste(im, (x, y), im) # create shadow - if 0: - sh = self._pil_shadow_image - shw, shh = sh.size - shadow = Image.new('RGBA', (w, h)) - x = 0 - while x < w: - y = 0 - while y < h: - shadow.paste(sh, (x,y)) - y += shh - x += shw - shadow = Image.composite(shadow, mask, mask) - # crop image (for speed) - sx, sy = self.SHADOW_XOFFSET, self.SHADOW_YOFFSET - mask = mask.crop((sx,sy,w,h)) - tmp = Image.new('RGBA', (w-sx,h-sy)) - shadow.paste(tmp, (0,0), mask) - elif 0: - import ImageFilter - dx, dy = 5, 5 - sh_color = (0x00,0x00,0x00,0x80) - shadow = Image.new('RGBA', (w+dx, h+dy)) - sx, sy = self.SHADOW_XOFFSET, self.SHADOW_YOFFSET - shadow.paste(sh_color, (0, 0, w, h), mask) - for i in range(3): - shadow = shadow.filter(ImageFilter.BLUR) - shadow = shadow.crop((dx,dy,w,h)) - sx, sy = self.SHADOW_XOFFSET, self.SHADOW_YOFFSET - mask = mask.crop((sx,sy,w,h)) - tmp = Image.new('RGBA', (w-sx,h-sy)) - shadow.paste(tmp, (0,0), mask) - else: - sh_color = (0x00,0x00,0x00,0x50) - shadow = Image.new('RGBA', (w, h)) - shadow.paste(sh_color, (0, 0, w, h), mask) - sx, sy = self.SHADOW_XOFFSET, self.SHADOW_YOFFSET - mask = mask.crop((sx,sy,w,h)) - tmp = Image.new('RGBA', (w-sx,h-sy)) - shadow.paste(tmp, (0,0), mask) - + sh_color = (0x00,0x00,0x00,0x50) + shadow = Image.new('RGBA', (w, h)) + shadow.paste(sh_color, (0, 0, w, h), mask) + sx, sy = self.SHADOW_XOFFSET, self.SHADOW_YOFFSET + mask = mask.crop((sx,sy,w,h)) + tmp = Image.new('RGBA', (w-sx,h-sy)) + shadow.paste(tmp, (0,0), mask) # shadow = ImageTk.PhotoImage(shadow) self._pil_shadow[(w,h)] = shadow @@ -353,7 +307,7 @@ class Images: return self._shade[self._shade_index] def _getShadow(self, image, card, color='#3896f8', factor=0.3): - if TOOLKIT == 'tk' and Image and Image.VERSION >= '1.1.7': + if self.use_pil: # use alpha image; one for each color if color in self._shadow_cards: shade = self._shadow_cards[color] diff --git a/pysollib/resource.py b/pysollib/resource.py index 49e7f835..26625a3c 100644 --- a/pysollib/resource.py +++ b/pysollib/resource.py @@ -200,6 +200,18 @@ class CSI: 9: _("Trumps only"), } + TYPE_ID = { + 1: "french", + 2: "hanafuda", + 3: "tarock", + 4: "mahjongg", + 5: "hex-a-deck", + 6: "mughal-ganjifa", + 7: "navagraha-ganjifa", + 8: "dashavatara-ganjifa", + 9: "trumps-only", + } + # cardset styles STYLE = { 1: _("Adult"), # diff --git a/pysollib/tile/tkutil.py b/pysollib/tile/tkutil.py index 78d5952f..a698a4a0 100644 --- a/pysollib/tile/tkutil.py +++ b/pysollib/tile/tkutil.py @@ -40,6 +40,7 @@ __all__ = ['wm_withdraw', 'createImage', 'shadowImage', 'markImage', + 'createBottom', 'get_text_width', ] @@ -359,6 +360,32 @@ def markImage(image): out = Image.composite(tmp, image, image) return out +def createBottom(image, color='white', backfile=None): + if not hasattr(image, '_pil_image'): + return None + im = image._pil_image + th = 1 # thickness + sh = Image.new('RGBA', im.size, color) + out = Image.composite(sh, im, im) + w, h = im.size + size = (w-th*2, h-th*2) + tmp = Image.new('RGBA', size, color) + tmp.putalpha(40) + mask = out.resize(size, Image.ANTIALIAS) + out.paste(tmp, (th,th), mask) + if backfile: + back = Image.open(backfile).convert('RGBA') + w0, h0 = back.size + w1, h1 = im.size + a = min(float(w1)/w0, float(h1)/h0) + a = a*0.9 + w0, h0 = int(w0*a), int(h0*a) + back = back.resize((w0,h0), Image.ANTIALIAS) + x, y = (w1 - w0) / 2, (h1 - h0) / 2 + out.paste(back, (x,y), back) + return PIL_Image(image=out) + + # ************************************************************************ # * font utils # ************************************************************************ diff --git a/pysollib/tk/tkutil.py b/pysollib/tk/tkutil.py index 78d5952f..a698a4a0 100644 --- a/pysollib/tk/tkutil.py +++ b/pysollib/tk/tkutil.py @@ -40,6 +40,7 @@ __all__ = ['wm_withdraw', 'createImage', 'shadowImage', 'markImage', + 'createBottom', 'get_text_width', ] @@ -359,6 +360,32 @@ def markImage(image): out = Image.composite(tmp, image, image) return out +def createBottom(image, color='white', backfile=None): + if not hasattr(image, '_pil_image'): + return None + im = image._pil_image + th = 1 # thickness + sh = Image.new('RGBA', im.size, color) + out = Image.composite(sh, im, im) + w, h = im.size + size = (w-th*2, h-th*2) + tmp = Image.new('RGBA', size, color) + tmp.putalpha(40) + mask = out.resize(size, Image.ANTIALIAS) + out.paste(tmp, (th,th), mask) + if backfile: + back = Image.open(backfile).convert('RGBA') + w0, h0 = back.size + w1, h1 = im.size + a = min(float(w1)/w0, float(h1)/h0) + a = a*0.9 + w0, h0 = int(w0*a), int(h0*a) + back = back.resize((w0,h0), Image.ANTIALIAS) + x, y = (w1 - w0) / 2, (h1 - h0) / 2 + out.paste(back, (x,y), back) + return PIL_Image(image=out) + + # ************************************************************************ # * font utils # ************************************************************************ diff --git a/scripts/cardset_viewer.py b/scripts/cardset_viewer.py index afd30417..b1ea6a1b 100755 --- a/scripts/cardset_viewer.py +++ b/scripts/cardset_viewer.py @@ -64,8 +64,8 @@ def show_cardset(*args): ls = glob(os.path.join(cs.dir, '[0-9][0-9][a-z]'+cs.ext)) ls += glob(os.path.join(cs.dir, 'back*'+cs.ext)) if all_imgs: - ls += glob(os.path.join(cs.dir, 'bottom*.gif')) - ls += glob(os.path.join(cs.dir, 'l*.gif')) + ls += glob(os.path.join(cs.dir, 'bottom*'+cs.ext)) + ls += glob(os.path.join(cs.dir, 'l*'+cs.ext)) #ls = glob(os.path.join(cs.dir, '*.gif')) ##if not ls: return ls.sort()