Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7422fe43b8 | |||
| 879c45a5b3 | |||
| db0d205374 | |||
| f20594a2b5 | |||
| ee017f4bc6 | |||
| 4d089f9a0e | |||
| e7f9c5c2ac | |||
| 2df8d38c2f | |||
| 17ac44d610 | |||
| 3c52c2ae3f | |||
| 5a5115e29f | |||
| 5c7ff1c97b | |||
| cc820a3595 | |||
| 48fff48d28 |
+15
@@ -13,3 +13,18 @@ jedit
|
||||
lint.txt
|
||||
renpy.code
|
||||
traceback.txt
|
||||
doc/common.css
|
||||
doc/images
|
||||
doc/index.html
|
||||
doc/monobook.css
|
||||
doc/monobook2.css
|
||||
doc/reference
|
||||
doc/shared.css
|
||||
doc/tutorials
|
||||
doc/www.renpy.org
|
||||
testing
|
||||
translations.rpy
|
||||
launchertrans.rpy
|
||||
jcc
|
||||
scite/scite.zip
|
||||
screenshot*
|
||||
|
||||
+15
-4
@@ -21,6 +21,12 @@ to have additional whitespace inserted between words so that the left
|
||||
and right margins are even, except on the last line of a paragraph.
|
||||
|
||||
|
||||
Ren'Py now supports the MudgeFont and BMFont image-based font file
|
||||
formats. The new renpy.register_mudgefont function is used to register
|
||||
a MudgeFont, and the renpy.register_bmfon function is used to register
|
||||
a BMFont.
|
||||
|
||||
|
||||
Newly-created games will have a Help option on the main and game
|
||||
menus. This is controlled by the config.help variable. By default
|
||||
the help system shows the README.html file in the game's base directory.
|
||||
@@ -48,9 +54,10 @@ Game", for consistency with the game menu.
|
||||
|
||||
When config.developer is set and an undefined image is used in a show
|
||||
or scene statement, a list of undefined images will appear centered at
|
||||
the top of the screen. A black screen will be show instead of any missing
|
||||
background. This makes it easier to write a script before all images are
|
||||
present.
|
||||
the top of the screen. A black screen (configurable with
|
||||
config.missing_background) will be shown instead of any missing
|
||||
background. This makes it easier to write a script before all images
|
||||
are present.
|
||||
|
||||
|
||||
The newly-documented Style.set_parent method lets you change the
|
||||
@@ -74,7 +81,7 @@ Alt-F4 and Command-Q now trigger the quit event, as if you pressed the
|
||||
quit button on the top of the window. The first press brings up the
|
||||
quit prompt, and a second press forcibly terminates the game.
|
||||
|
||||
Alt-H and Command-H hide (iconify) the window.
|
||||
Alt-M and Command-M iconify the window.
|
||||
|
||||
|
||||
The new RENPY_SCREENSHOT_PATTERN environment variable lets you
|
||||
@@ -91,6 +98,10 @@ The presplash code now looks for presplash.jpg in the game directory
|
||||
if presplash.png is not found.
|
||||
|
||||
|
||||
On Windows, config.window_icon will be scaled to 32x32 if it is wider
|
||||
than 32 pixels. This allows the same icon to be used across platforms.
|
||||
|
||||
|
||||
Custom mouse cursors should now be properly hidden when the mouse
|
||||
leaves the window. Previously, this failed to work on the Mac OS X
|
||||
platform.
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
This file contains boilerplate information about running Ren'Py that
|
||||
can be included into the README for your game. It may be necessary to
|
||||
change some of the filenames in this document, to make it specific to
|
||||
your game.
|
||||
|
||||
Feel free to use this in your projects.
|
||||
|
||||
|
||||
|
||||
Running the Game
|
||||
================
|
||||
|
||||
(Windows)
|
||||
|
||||
If this game was installed on Windows using an installer, then you can
|
||||
run it by choosing the shortcut left by the installer. If this game
|
||||
was installed on Windows using the cross-platform zip file, then it
|
||||
can be run by executing the run_game.exe file.
|
||||
|
||||
(Macintosh)
|
||||
|
||||
For information about running Ren'Py games on Mac OS 10.3 or higher,
|
||||
please go to http://www.bishoujo.us/renpy/mac.html .
|
||||
|
||||
(Linux/Unix)
|
||||
|
||||
For information about running Ren'Py games under Linux and Unix,
|
||||
please go to http://www.bishoujo.us/renpy/linux.html . At the very
|
||||
least, you will need to compile the _renpy module. Read
|
||||
the file module/README.txt for details.
|
||||
|
||||
|
||||
Playing the Game
|
||||
================
|
||||
|
||||
By default, the game starts running in full screen mode. On some
|
||||
computers, especially some virtual machines, this can lead to mouse
|
||||
problems. To fix this, press 'f'.
|
||||
|
||||
Some of the more interesting game actions can be performed as follows:
|
||||
|
||||
- The left mouse button is used to advance to the next line of
|
||||
dialogue, or to pick menu options.
|
||||
|
||||
- The right mouse button brings you into a menu screen where you can
|
||||
save the game, load the game, change preferences, return to the main
|
||||
menu, or quit entirely.
|
||||
|
||||
- Scrolling the mouse wheel up or pushing page up returns you to the
|
||||
previous screen.
|
||||
|
||||
- Holding down the CTRL key skips dialogue. By default, it only
|
||||
skips read dialogue, but this can be changed by a preference. Tab
|
||||
toggles skip mode.
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
A version of dissolve that only draws the pixels that are being
|
||||
dissolved, while doing a straight-blit on pixels that remain the same
|
||||
between the two images.
|
||||
|
||||
Figure out some way of having variables updated in a new context saved
|
||||
permanently, even if we return to the outer context because of a
|
||||
rollback or something. Need to be very careful here.
|
||||
|
||||
Dynamic variables, parameterized labels, etc.
|
||||
|
||||
Implement an extension mechanism of some sort, so that users can drop
|
||||
packages of Ren'Py code into the Ren'Py directory, and get stuff like
|
||||
speech support.
|
||||
|
||||
Implement speech control support.
|
||||
|
||||
BPP conversion (perhaps as a package).
|
||||
|
||||
Automatically scale to a fixed size.
|
||||
|
||||
Hide picture-mouse when leaving window, restore it when entering window.
|
||||
+2
-1
@@ -18,7 +18,8 @@ def main():
|
||||
setup(name="RenPy",
|
||||
windows=[ dict(script="renpy.py",
|
||||
dest_base="renpy",
|
||||
icon_resources=[ (1, "newicon.ico") ] ) ],
|
||||
icon_resources=[ (1, "newicon.ico") ] ),
|
||||
],
|
||||
|
||||
console=[ dict(script="renpy.py", dest_base="console") ],
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
1#!/usr/bin/env python
|
||||
|
||||
import glob
|
||||
import re
|
||||
from sets import Set as set
|
||||
import sys
|
||||
|
||||
seen_files = set()
|
||||
seen_strings = set()
|
||||
|
||||
def tl(fn, s):
|
||||
|
||||
s = eval(s)
|
||||
|
||||
if len(s) < 3:
|
||||
return
|
||||
|
||||
if s in seen_strings:
|
||||
return
|
||||
|
||||
if fn not in seen_files:
|
||||
print >>out
|
||||
print >>out, " # Translatable strings found in", fn
|
||||
print >>out
|
||||
seen_files.add(fn)
|
||||
|
||||
print >>out, " config.translations[%r] = %r" % (s, s)
|
||||
seen_strings.add(s)
|
||||
|
||||
def process(fn):
|
||||
|
||||
data = file(fn).read()
|
||||
|
||||
for m in re.finditer(r'\bu\"(\\"|[^"])+\"', data):
|
||||
tl(fn, m.group(0))
|
||||
|
||||
for m in re.finditer(r"\bu\'(\\'|[^'])+\'", data):
|
||||
tl(fn, m.group(0))
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# out = file("extras/translations.rpy", "w")
|
||||
out = sys.stdout
|
||||
|
||||
print >>out, "# This file contains a list of all of the phrases you can translate"
|
||||
print >>out, "# from the Ren'Py launcher."
|
||||
print >>out, ""
|
||||
print >>out, "init python:"
|
||||
|
||||
for fn in glob.glob("launcher/*.rpy"):
|
||||
process(fn)
|
||||
@@ -196,6 +196,9 @@ label _style_hierarchy:
|
||||
jump _developer_screen
|
||||
|
||||
|
||||
init -1050 python:
|
||||
config.missing_background = "black"
|
||||
|
||||
init 1050 python:
|
||||
|
||||
if renpy.game.options.remote:
|
||||
@@ -238,7 +241,7 @@ init 1050 python:
|
||||
|
||||
global __missing_scene
|
||||
if __missing_scene:
|
||||
renpy.show(name, what="black")
|
||||
renpy.show(name, what=config.missing_background)
|
||||
__missing_scene = False
|
||||
|
||||
what = " ".join(what).replace("{", "{{")
|
||||
|
||||
@@ -182,7 +182,8 @@ init -1180 python hide:
|
||||
filename, line = renpy.get_filename_line()
|
||||
renpy.launch_editor([ filename ], line)
|
||||
|
||||
# The default keymap.
|
||||
# The default keymap. We might also want to put some of this into
|
||||
# the launcher.
|
||||
km = renpy.Keymap(
|
||||
rollback = renpy.rollback,
|
||||
screenshot = screenshot,
|
||||
|
||||
@@ -22,7 +22,7 @@ init python:
|
||||
style.prefs_column.box_spacing = 5
|
||||
style.prefs_frame.top_margin = 5
|
||||
|
||||
style.prefs_left.xpos = 100
|
||||
style.prefs_left.xpos = 110
|
||||
style.prefs_center.xpos = 320
|
||||
style.prefs_right.xpos = 530
|
||||
|
||||
|
||||
@@ -203,10 +203,9 @@ init -1 python hide:
|
||||
## - A label in the script, in which case that label is called to
|
||||
## show help to the user.
|
||||
## - A file name relative to the base directory, which is opened in a
|
||||
## web browser. The filename may be followed by an # to specifiy an
|
||||
## anchor inside an html file.
|
||||
## web browser.
|
||||
## - None, to disable help.
|
||||
config.help = "README.html#renpy_help"
|
||||
config.help = "README.html"
|
||||
|
||||
|
||||
#########################################
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
import Image
|
||||
except ImportError:
|
||||
print "Could not import the Image module. Please ensure that the Python Imaging"
|
||||
print "Library (PIL) is properly installed."
|
||||
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@ init python:
|
||||
dfn = destdir + "/" + fn
|
||||
else:
|
||||
dfn = fn
|
||||
|
||||
dfn = dfn.replace("\\", "/")
|
||||
|
||||
rv.append((sfn, dfn))
|
||||
|
||||
@@ -280,7 +282,7 @@ label distribute:
|
||||
|
||||
win_data = { }
|
||||
if os.path.exists(project.path + "/icon.ico"):
|
||||
win_data[config.renpy_base + "/renpy.exe"] = pefile.change_icons(
|
||||
win_data[project.name + ".exe"] = pefile.change_icons(
|
||||
config.renpy_base + "/renpy.exe",
|
||||
project.path + "/icon.ico",
|
||||
)
|
||||
@@ -306,7 +308,7 @@ label distribute:
|
||||
zi.external_attr = long(0100666) << 16
|
||||
data = file(fn, "rb").read()
|
||||
|
||||
data = win_data.get(fn, data)
|
||||
data = win_data.get(an, data)
|
||||
|
||||
zf.writestr(zi, data)
|
||||
|
||||
@@ -379,11 +381,11 @@ label distribute:
|
||||
|
||||
quoted_name = project.name.replace("&", "&").replace("<", "<")
|
||||
info_plist = file(config.renpy_base + "/renpy.app/Contents/Info.plist", "rb").read().replace("Ren'Py Launcher", quoted_name)
|
||||
mac_data[config.renpy_base + "/renpy.app/Contents/Info.plist"] = info_plist
|
||||
mac_data[project.name + ".app/Contents/Info.plist"] = info_plist
|
||||
|
||||
if os.path.exists(project.path + "/icon.icns"):
|
||||
icon_data = file(project.path + "/icon.icns", "rb").read()
|
||||
mac_data[config.renpy_base + "/renpy.app/Contents/Resources/launcher.icns"] = icon_data
|
||||
mac_data[project.name + ".app/Contents/Resources/launcher.icns"] = icon_data
|
||||
|
||||
zf = zipfile.ZipFile(name + "-mac.zip", "w", zipfile.ZIP_DEFLATED)
|
||||
|
||||
@@ -411,7 +413,7 @@ label distribute:
|
||||
zi.external_attr = long(0100666) << 16
|
||||
data = file(fn, "rb").read()
|
||||
|
||||
data = mac_data.get(fn, data)
|
||||
data = mac_data.get(an, data)
|
||||
zf.writestr(zi, data)
|
||||
|
||||
zf.close()
|
||||
|
||||
+14
-3
@@ -36,6 +36,13 @@ init:
|
||||
|
||||
style.hyperlink_text.color = "#0ff"
|
||||
|
||||
config.underlay = [
|
||||
renpy.Keymap(
|
||||
quit = renpy.quit_event,
|
||||
iconify = renpy.iconify,
|
||||
)
|
||||
]
|
||||
|
||||
def quote(c):
|
||||
n = ord(c)
|
||||
if 0x20 <= n <= 0x7f:
|
||||
@@ -58,13 +65,14 @@ init:
|
||||
ui.add(DynamicDisplayable("Text(_(store.message), size=14, color='#fff', xpos=100, ypos=375, xmaximum=240)"))
|
||||
ui.text(renpy.version(), xalign=0, yalign=1.0, size=12, color='#000')
|
||||
|
||||
return ui.interact(suppress_underlay=True)
|
||||
return ui.interact()
|
||||
|
||||
def title(name):
|
||||
ui.window(style='mm_root')
|
||||
ui.null()
|
||||
|
||||
ui.frame(xminimum=350, yminimum=370)
|
||||
ui.viewport(child_size=(2000, None), draggable=True, ymaximum=34)
|
||||
_label_factory(name, "launcher_title", size=28)
|
||||
|
||||
# ui.text(name, xpos=4, ypos=4, size=30, color="#559")
|
||||
@@ -93,7 +101,7 @@ init:
|
||||
|
||||
# ui.button(clicked=clicked, hovered=hovered)
|
||||
# ui.text(text, style="button_text")
|
||||
_button_factory(text, 'launcher', clicked=clicked, hovered=hovered, selected=selected)
|
||||
_button_factory(text, 'launcher', clicked=clicked, hovered=hovered, selected=selected, xmaximum=200)
|
||||
|
||||
|
||||
def prompt(name, message, cancel, default='', hint=''):
|
||||
@@ -151,6 +159,8 @@ init:
|
||||
mid(focus="paged_menu")
|
||||
|
||||
for name, desc, ret, hovered, selected in choices[page * per_page:(page + 1) * per_page]:
|
||||
if len(name) > 19:
|
||||
name = name[:18] + u"\u2026"
|
||||
button(name, desc, clicked=ui.returns(("return", ret)), hovered=hovered, selected=selected)
|
||||
|
||||
ui.close()
|
||||
@@ -483,7 +493,8 @@ label edit:
|
||||
files.remove(i)
|
||||
files.insert(0, i)
|
||||
|
||||
renpy.launch_editor(files)
|
||||
if not renpy.launch_editor(files):
|
||||
error(u"Error", u"Launching the editor failed. You may need Java, which can be downloaded for free from {a=http://www.java.com}java.com{/a}.", "start")
|
||||
|
||||
store.message = _(u"Launched editor with %d script files.") % len(files)
|
||||
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
# ***** ***** ***** ***** ***** ***** **** ***** ***** ***** *****
|
||||
# Be sure to change script_version in launcher/script_version.rpy, too!
|
||||
# Also check to see if we have to update renpy.py.
|
||||
version = "Ren'Py 6.8.0a"
|
||||
version = "Ren'Py 6.8.0d"
|
||||
script_version = 5003000
|
||||
savegame_suffix = "-LT1.save"
|
||||
|
||||
|
||||
+1
-1
@@ -175,7 +175,7 @@ keymap = dict(
|
||||
inspector = [ 'I' ],
|
||||
developer = [ 'D' ],
|
||||
quit = [ 'meta_q', 'alt_K_F4' ],
|
||||
iconify = [ 'meta_h' ],
|
||||
iconify = [ 'meta_m', 'alt_m' ],
|
||||
help = [ 'K_F1', 'meta_shift_/' ],
|
||||
|
||||
# Say.
|
||||
|
||||
+10
-4
@@ -718,10 +718,16 @@ class Display(object):
|
||||
|
||||
# Window icon.
|
||||
if renpy.config.window_icon:
|
||||
pygame.display.set_icon(
|
||||
renpy.display.scale.image_load_unscaled(
|
||||
renpy.loader.load(renpy.config.window_icon),
|
||||
renpy.config.window_icon))
|
||||
|
||||
im = renpy.display.scale.image_load_unscaled(
|
||||
renpy.loader.load(renpy.config.window_icon),
|
||||
renpy.config.window_icon)
|
||||
|
||||
if on_windows and im.get_width() > 32:
|
||||
im = renpy.display.scale.real_bilinear(im, (32, 32))
|
||||
|
||||
pygame.display.set_icon(im)
|
||||
|
||||
|
||||
# If a window exists of the right size and flags, use it. Otherwise,
|
||||
# make our own window.
|
||||
|
||||
+241
-69
@@ -40,9 +40,81 @@ fonts = { }
|
||||
# loaded font object corresponding to that specification.
|
||||
font_cache = { }
|
||||
|
||||
|
||||
class ImageFont(object):
|
||||
pass
|
||||
|
||||
# ImageFonts are expected to have the following fields defined by
|
||||
# a subclass:
|
||||
|
||||
# Font global:
|
||||
# height - The line height, the height of each character cell.
|
||||
# kerns - The kern between wach pair of characters.
|
||||
# default_kern - The default kern.
|
||||
# baseline - The y offset of the font baseline.
|
||||
|
||||
# Per-character:
|
||||
# width - The width of each character.
|
||||
# advance - The advance of each character.
|
||||
# offsets - The x and y offsets of each character.
|
||||
# chars - A map from a character to the surface containing that character.
|
||||
|
||||
def size(self, text):
|
||||
w = 0
|
||||
|
||||
if not text:
|
||||
return (0, self.height)
|
||||
|
||||
for a, b in zip(text, text[1:]):
|
||||
try:
|
||||
w += self.advance[a] + self.kerns.get(a + b, self.default_kern)
|
||||
except KeyError:
|
||||
raise Exception("Character %r not found in %s." % (a, type(self).__name__))
|
||||
|
||||
w += self.width[text[-1]]
|
||||
|
||||
return (w, self.height)
|
||||
|
||||
def render(self, text, antialias, color, black_color=(0, 0, 0, 255), background=None):
|
||||
surf = pygame.Surface(self.size(text), 0,
|
||||
renpy.game.interface.display.sample_surface)
|
||||
|
||||
if not text:
|
||||
return surf
|
||||
|
||||
x = 0
|
||||
y = 0
|
||||
|
||||
for a, b in zip(text, text[1:]):
|
||||
xoff, yoff = self.offsets[a]
|
||||
surf.blit(self.chars[a], (x + xoff, y + yoff))
|
||||
x += self.advance[a] + self.kerns.get(a + b, self.default_kern)
|
||||
|
||||
xoff, yoff = self.offsets[text[-1]]
|
||||
surf.blit(self.chars[text[-1]], (x + xoff, y + yoff))
|
||||
|
||||
if renpy.config.recolor_sfonts and \
|
||||
(color != (255, 255, 255, 255) or black_color != (0, 0, 0, 255) ) and \
|
||||
renpy.display.module.can_twomap:
|
||||
|
||||
newsurf = pygame.Surface(surf.get_size(), surf.get_flags(), surf)
|
||||
renpy.display.module.twomap(surf, newsurf, color, black_color)
|
||||
renpy.display.render.mutated_surface(newsurf)
|
||||
|
||||
surf = newsurf
|
||||
|
||||
return surf
|
||||
|
||||
def get_linesize(self):
|
||||
return self.height + 10
|
||||
|
||||
def get_height(self):
|
||||
return self.height
|
||||
|
||||
def get_ascent(self):
|
||||
return self.baseline
|
||||
|
||||
|
||||
def get_descent(self):
|
||||
return -(self.height - self.baseline)
|
||||
|
||||
class SFont(ImageFont):
|
||||
|
||||
@@ -61,26 +133,30 @@ class SFont(ImageFont):
|
||||
|
||||
def load(self):
|
||||
|
||||
# Map from character to subsurface.
|
||||
self.chars = { }
|
||||
|
||||
# Map from character to width, height.
|
||||
self.sizes = { }
|
||||
|
||||
self.width = { }
|
||||
self.advance = { }
|
||||
self.offsets = { }
|
||||
|
||||
# Load in the image.
|
||||
surf = renpy.display.im.Image(self.filename).load(unscaled=True)
|
||||
self.surf = surf
|
||||
|
||||
sw, sh = surf.get_size()
|
||||
height = sh
|
||||
self.height = height
|
||||
|
||||
self.baseline = height
|
||||
|
||||
# Create space characters.
|
||||
self.chars[u' '] = pygame.Surface((self.spacewidth, height), 0, surf)
|
||||
self.sizes[u' '] = self.spacewidth
|
||||
self.chars[u'\u00a0'] = self.chars[u' ']
|
||||
self.sizes[u'\u00a0'] = self.sizes[u' ']
|
||||
self.width[u' '] = self.spacewidth
|
||||
self.advance[u' '] = self.spacewidth
|
||||
self.offsets[u' '] = (0, 0)
|
||||
|
||||
self.chars[u'\u00a0'] = self.chars[u' ']
|
||||
self.width[u'\u00a0'] = self.width[u' ']
|
||||
self.advance[u'\u00a0'] = self.advance[u' ']
|
||||
self.offsets[u'\u00a0'] = self.offsets[u' ']
|
||||
|
||||
# The color key used to separate characters.
|
||||
i = 0
|
||||
while True:
|
||||
@@ -111,87 +187,169 @@ class SFont(ImageFont):
|
||||
ss = renpy.display.scale.surface_scale(ss)
|
||||
|
||||
self.chars[c] = ss
|
||||
self.sizes[c] = i - start
|
||||
|
||||
self.width[c] = i - start
|
||||
self.advance[c] = i - start
|
||||
self.offsets[c] = (0, 0)
|
||||
|
||||
i += 1
|
||||
|
||||
def size(self, text):
|
||||
w = 0
|
||||
|
||||
if not text:
|
||||
return (0, self.height)
|
||||
class MudgeFont(ImageFont):
|
||||
|
||||
def __init__(self,
|
||||
filename,
|
||||
xml,
|
||||
spacewidth,
|
||||
default_kern,
|
||||
kerns):
|
||||
|
||||
self.filename = filename
|
||||
self.xml = xml
|
||||
self.spacewidth = spacewidth
|
||||
self.default_kern = default_kern
|
||||
self.kerns = kerns
|
||||
|
||||
def load(self):
|
||||
|
||||
self.chars = { }
|
||||
self.width = { }
|
||||
self.advance = { }
|
||||
self.offsets = { }
|
||||
|
||||
for a, b in zip(text, text[1:]):
|
||||
w += self.sizes[a] + self.kerns.get(a + b, self.default_kern)
|
||||
# Load in the image.
|
||||
surf = renpy.display.im.Image(self.filename).load(unscaled=True)
|
||||
|
||||
w += self.sizes[text[-1]]
|
||||
# Parse the xml file.
|
||||
tree = etree.fromstring(renpy.loader.load(self.xml).read())
|
||||
|
||||
return (w, self.height)
|
||||
height = 0
|
||||
|
||||
# Find each character.
|
||||
for e in tree.findall("char"):
|
||||
|
||||
char = int(e.attrib["id"])
|
||||
if char < 0:
|
||||
continue
|
||||
|
||||
c = unichr(char)
|
||||
x = int(e.attrib["x"])
|
||||
y = int(e.attrib["y"])
|
||||
w = int(e.attrib["width"])
|
||||
h = int(e.attrib["height"])
|
||||
|
||||
ss = surf.subsurface((x, y, w, h))
|
||||
ss = renpy.display.scale.surface_scale(ss)
|
||||
|
||||
self.chars[c] = ss
|
||||
self.width[c] = w
|
||||
self.advance[c] = w
|
||||
self.offsets[c] = (0, 0)
|
||||
|
||||
height = max(height, h)
|
||||
|
||||
self.height = height
|
||||
self.baseline = height
|
||||
|
||||
# Create space characters.
|
||||
if u' ' not in self.chars:
|
||||
self.chars[u' '] = pygame.Surface((self.spacewidth, height), 0, surf)
|
||||
self.width[u' '] = self.spacewidth
|
||||
self.advance[u' '] = self.spacewidth
|
||||
self.offsets[u' '] = (0, 0)
|
||||
|
||||
def render(self, text, antialias, color, black_color=(0, 0, 0, 255), background=None):
|
||||
surf = pygame.Surface(self.size(text), 0,
|
||||
renpy.game.interface.display.sample_surface)
|
||||
|
||||
if u'\u00a0' not in self.chars:
|
||||
self.chars[u'\u00a0'] = self.chars[u' ']
|
||||
self.width[u'\u00a0'] = self.width[u' ']
|
||||
self.advance[u'\u00a0'] = self.advance[u' ']
|
||||
self.offsets[u'\u00a0'] = self.offsets[u' ']
|
||||
|
||||
if not text:
|
||||
return surf
|
||||
|
||||
x = 0
|
||||
y = 0
|
||||
def parse_bmfont_line(l):
|
||||
w = ""
|
||||
line = [ ]
|
||||
|
||||
quote = False
|
||||
|
||||
for c in l:
|
||||
if c == "\r" or c == "\n":
|
||||
continue
|
||||
|
||||
for a, b in zip(text, text[1:]):
|
||||
surf.blit(self.chars[a], (x, y))
|
||||
x += self.sizes[a] + self.kerns.get(a + b, self.default_kern)
|
||||
if c == " " and not quote:
|
||||
if w:
|
||||
line.append(w)
|
||||
w = ""
|
||||
continue
|
||||
|
||||
surf.blit(self.chars[text[-1]], (x, y))
|
||||
if c == "\"":
|
||||
quote = not quote
|
||||
continue
|
||||
|
||||
if renpy.config.recolor_sfonts and \
|
||||
(color != (255, 255, 255, 255) or black_color != (0, 0, 0, 255) ) and \
|
||||
renpy.display.module.can_twomap:
|
||||
w += c
|
||||
|
||||
newsurf = pygame.Surface(surf.get_size(), surf.get_flags(), surf)
|
||||
renpy.display.module.twomap(surf, newsurf, color, black_color)
|
||||
renpy.display.render.mutated_surface(newsurf)
|
||||
if w:
|
||||
line.append(w)
|
||||
|
||||
surf = newsurf
|
||||
map = dict(i.split("=", 1) for i in line[1:])
|
||||
return line[0], map
|
||||
|
||||
class BMFont(ImageFont):
|
||||
|
||||
return surf
|
||||
def __init__(self, filename):
|
||||
self.filename = filename
|
||||
|
||||
def get_linesize(self):
|
||||
return self.height
|
||||
def load(self):
|
||||
|
||||
def get_height(self):
|
||||
return self.height
|
||||
self.chars = { }
|
||||
self.width = { }
|
||||
self.advance = { }
|
||||
self.offsets = { }
|
||||
self.kerns = { }
|
||||
self.default_kern = 0
|
||||
|
||||
pages = { }
|
||||
|
||||
def get_ascent(self):
|
||||
return self.height
|
||||
f = renpy.loader.load(self.filename)
|
||||
for l in f:
|
||||
|
||||
def get_descent(self):
|
||||
return 0
|
||||
kind, args = parse_bmfont_line(l)
|
||||
|
||||
if kind == "common":
|
||||
self.height = int(args["lineHeight"])
|
||||
self.baseline = int(args["base"])
|
||||
elif kind == "page":
|
||||
pages[int(args["id"])] = renpy.display.im.Image(args["file"]).load(unscaled=True)
|
||||
elif kind == "char":
|
||||
c = unichr(int(args["id"]))
|
||||
x = int(args["x"])
|
||||
y = int(args["y"])
|
||||
w = int(args["width"])
|
||||
h = int(args["height"])
|
||||
xo = int(args["xoffset"])
|
||||
yo = int(args["yoffset"])
|
||||
xadvance = int(args["xadvance"])
|
||||
page = int(args["page"])
|
||||
|
||||
ss = pages[page].subsurface((x, y, w, h))
|
||||
ss = renpy.display.scale.surface_scale(ss)
|
||||
|
||||
self.chars[c] = ss
|
||||
self.width[c] = w + xo
|
||||
self.advance[c] = xadvance
|
||||
self.offsets[c] = (xo, yo)
|
||||
|
||||
f.close()
|
||||
|
||||
if u'\u00a0' not in self.chars:
|
||||
self.chars[u'\u00a0'] = self.chars[u' ']
|
||||
self.width[u'\u00a0'] = self.width[u' ']
|
||||
self.advance[u'\u00a0'] = self.advance[u' ']
|
||||
self.offsets[u'\u00a0'] = self.offsets[u' ']
|
||||
|
||||
|
||||
def register_sfont(name=None, size=None, bold=False, italics=False, underline=False,
|
||||
filename=None, spacewidth=10, default_kern=0, kerns={},
|
||||
charset=u"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"):
|
||||
"""
|
||||
This registers an SFont with the given details. Please note that
|
||||
size, bold, italic, and underline are all advisory (used for matching), and
|
||||
do not change the appearance of the font.
|
||||
|
||||
@param name: The name of the font being registered.
|
||||
@param size: The size of the font being registered.
|
||||
@param bold: The boldness of the font being registered.
|
||||
@param italics: The italicness of the font being registered.
|
||||
@param underline: The underline of the font being registered.
|
||||
|
||||
@param filename: The file containing the sfont image.
|
||||
@param spacewidth: The width of a space character.
|
||||
@param default_kern: The default kern spacing between characters.
|
||||
@param kerns: A map from two-character strings to the kern that should
|
||||
be used between those characters.
|
||||
@param charset: The character set of the font. A string containing characters
|
||||
in the order in which they are found in the image.
|
||||
"""
|
||||
|
||||
if name is None or size is None or filename is None:
|
||||
raise Exception("When registering an SFont, the font name, font size, and filename are required.")
|
||||
|
||||
@@ -199,6 +357,20 @@ def register_sfont(name=None, size=None, bold=False, italics=False, underline=Fa
|
||||
fonts[(name, size, bold, italics, underline)] = sf
|
||||
|
||||
|
||||
def register_mudgefont(name=None, size=None, bold=False, italics=False, underline=False,
|
||||
filename=None, xml=None, spacewidth=10, default_kern=0, kerns={}):
|
||||
|
||||
if name is None or size is None or filename is None or xml is None:
|
||||
raise Exception("When registering a Mudge Font, the font name, font size, filename, and xml filename are required.")
|
||||
|
||||
mf = MudgeFont(filename, xml, spacewidth, default_kern, kerns)
|
||||
fonts[(name, size, bold, italics, underline)] = mf
|
||||
|
||||
def register_bmfont(name=None, size=None, bold=False, italics=False, underline=False,
|
||||
filename=None):
|
||||
|
||||
bmf = BMFont(filename)
|
||||
fonts[(name, size, bold, italics, underline)] = bmf
|
||||
|
||||
def load_ttf(fn, size, bold, italics, underline, expand):
|
||||
|
||||
|
||||
@@ -1249,6 +1249,9 @@ class Text(renpy.display.core.Displayable):
|
||||
|
||||
surf, (sw, sh) = ts.render(text, antialias, color, black_color, user_colors, time, at, expand)
|
||||
|
||||
if expand:
|
||||
(sw, sh) = ts.sizes(text)
|
||||
|
||||
actual_y = y + max_ascent - ts.get_ascent()
|
||||
|
||||
if surf:
|
||||
@@ -1327,10 +1330,10 @@ class Text(renpy.display.core.Displayable):
|
||||
maxdsy = max(maxdsy, dsy)
|
||||
|
||||
for expand, color, dsx, dsy in outlines:
|
||||
mindsx = min(mindsx, dsx)
|
||||
mindsy = min(mindsy, dsy)
|
||||
maxdsx = max(maxdsx, dsx)
|
||||
maxdsy = max(maxdsy, dsy)
|
||||
mindsx = min(mindsx, dsx - expand)
|
||||
mindsy = min(mindsy, dsy - expand)
|
||||
maxdsx = max(maxdsx, dsx + expand)
|
||||
maxdsy = max(maxdsy, dsy + expand)
|
||||
|
||||
# minds{x,y} are negative (or 0), maxds{x,y} are positive (or 0).
|
||||
|
||||
|
||||
+36
-15
@@ -29,7 +29,7 @@ _file = file
|
||||
|
||||
import renpy
|
||||
from renpy.display.text import ParameterizedText
|
||||
from renpy.display.font import register_sfont
|
||||
from renpy.display.font import register_sfont, register_mudgefont, register_bmfont
|
||||
from renpy.display.behavior import Keymap
|
||||
from renpy.display.minigame import Minigame
|
||||
|
||||
@@ -917,13 +917,41 @@ def get_filename_line():
|
||||
|
||||
def shell_escape(s):
|
||||
s = s.replace("\\", "\\\\")
|
||||
# s = s.replace("\'", "\\\'")
|
||||
s = s.replace("\"", "\\\"")
|
||||
s = s.replace("\$", "\\\$")
|
||||
s = s.replace("\%", "\\\%")
|
||||
s = s.replace("\`", "\\\`")
|
||||
return s
|
||||
|
||||
def split_args(s):
|
||||
|
||||
rv = [ ]
|
||||
word = ""
|
||||
quoted = False
|
||||
|
||||
i = 0
|
||||
while i < len(s):
|
||||
c = s[i]
|
||||
i += 1
|
||||
|
||||
if not quoted and c == ' ' and word:
|
||||
if word:
|
||||
rv.append(word)
|
||||
word = ""
|
||||
continue
|
||||
|
||||
if c == '"':
|
||||
quoted = not quoted
|
||||
continue
|
||||
|
||||
if c == '\\':
|
||||
c = s[i]
|
||||
i += 1
|
||||
|
||||
word += c
|
||||
|
||||
if word:
|
||||
rv.append(word)
|
||||
|
||||
return rv
|
||||
|
||||
def launch_editor(filenames, line=1, transient=0):
|
||||
"""
|
||||
This causes an editor to be launched at the location of the current
|
||||
@@ -940,16 +968,8 @@ def launch_editor(filenames, line=1, transient=0):
|
||||
if not len(filenames):
|
||||
return
|
||||
|
||||
# join = '" "'
|
||||
shell = True
|
||||
|
||||
# if hasattr(sys, "winver"):
|
||||
# shell = False
|
||||
# # join = '" "'
|
||||
# else:
|
||||
# shell = True
|
||||
# # join = "' '"
|
||||
|
||||
filenames = [ shell_escape(os.path.normpath(i)) for i in filenames ]
|
||||
filename = filenames[0]
|
||||
|
||||
@@ -965,11 +985,12 @@ def launch_editor(filenames, line=1, transient=0):
|
||||
cmd = cmd.replace('""', '')
|
||||
|
||||
try:
|
||||
return subprocess.Popen(cmd, shell=shell)
|
||||
subprocess.Popen(split_args(cmd))
|
||||
return True
|
||||
except:
|
||||
if renpy.config.debug:
|
||||
raise
|
||||
return None
|
||||
return False
|
||||
|
||||
# A file that log logs to.
|
||||
logfile = None
|
||||
|
||||
+1
-1
@@ -493,7 +493,7 @@ def rebuild():
|
||||
global style_pending
|
||||
global styles_built
|
||||
|
||||
if not styles_built:
|
||||
if renpy.game.init_phase:
|
||||
return
|
||||
|
||||
styles_pending = [ j for i in style_parts.values() for j in i.values() ]
|
||||
|
||||
@@ -13,18 +13,18 @@ init:
|
||||
|
||||
if platform.mac_ver()[0]:
|
||||
config.editor = "open -t '%(allfiles)s'"
|
||||
|
||||
else:
|
||||
|
||||
if sys.platform == 'win32':
|
||||
editor = config.renpy_base + "/editor/scite.exe"
|
||||
else:
|
||||
editor = config.renpy_base + "/editor/scite"
|
||||
|
||||
editor = os.path.normpath(editor)
|
||||
editor = renpy.shell_escape(editor)
|
||||
|
||||
if os.path.exists(editor):
|
||||
editor = renpy.shell_escape(editor)
|
||||
config.editor = '"' + editor + '" "%(allfiles)s" "-open:%(filename)s" -goto:%(line)d'
|
||||
config.editor_transient = config.editor+' -revert:'
|
||||
config.editor = '"' + editor + '" "%(allfiles)s" -goto:%(line)d'
|
||||
config.editor_transient = config.editor+' -revert:'
|
||||
|
||||
if config.editor:
|
||||
os.environ['RENPY_EDITOR'] = config.editor
|
||||
@@ -6,6 +6,8 @@ version = renpy.version[7:]
|
||||
|
||||
import sys
|
||||
if "retag" in sys.argv[1:]:
|
||||
renpy.subprocess.call([ "svn", "rm", 'http://www.bishoujo.us/svn/renpy/tags/' + version, "-m", "Tagging " + version ])
|
||||
renpy.subprocess.call([ "bzr", "tag", "--delete", version ])
|
||||
|
||||
renpy.subprocess.call([ "svn", "copy", ".", 'http://www.bishoujo.us/svn/renpy/tags/' + version, "-m", "Tagging " + version ])
|
||||
renpy.subprocess.call([ "bzr", "tag", version ])
|
||||
|
||||
|
||||
|
||||
@@ -200,10 +200,9 @@ init -1 python hide:
|
||||
## - A label in the script, in which case that label is called to
|
||||
## show help to the user.
|
||||
## - A file name relative to the base directory, which is opened in a
|
||||
## web browser. The filename may be followed by an # to specifiy an
|
||||
## anchor inside an html file.
|
||||
## web browser.
|
||||
## - None, to disable help.
|
||||
config.help = "README.html#renpy_help"
|
||||
config.help = "README.html"
|
||||
|
||||
|
||||
#########################################
|
||||
|
||||
@@ -203,10 +203,9 @@ init -1 python hide:
|
||||
## - A label in the script, in which case that label is called to
|
||||
## show help to the user.
|
||||
## - A file name relative to the base directory, which is opened in a
|
||||
## web browser. The filename may be followed by an # to specifiy an
|
||||
## anchor inside an html file.
|
||||
## web browser.
|
||||
## - None, to disable help.
|
||||
config.help = "README.html#renpy_help"
|
||||
config.help = "README.html"
|
||||
|
||||
|
||||
#########################################
|
||||
|
||||
Reference in New Issue
Block a user