[PATCH] for easier using Windows fonts and CJK support

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
Tiberius
Newbie
Posts: 3
Joined: Sat Mar 31, 2007 3:34 pm
Contact:

[PATCH] for easier using Windows fonts and CJK support

#1 Post by Tiberius »

Hello,
recently I'm developing an adventure game with Ren'Py. It's a such a great tool, working with it is a joy. Thanks all developers and contributors!

I've modified some code to satisfy my own needs. First here's a path to easily reference Windows-supplied TTF/TTC fonts, like e.g. mingliu.ttc for Chinese font. It saves a lot of space since our game won't need to supply some huge Chinese fonts (assuming players are using Windows systems, and they can legally use these fonts).

Code: Select all

diff -ur renpy-6.1.1/renpy/display/text.py renpy-6.1.1c/renpy/display/text.py
--- renpy-6.1.1/renpy/display/text.py	Sun Feb 25 00:40:22 2007
+++ renpy-6.1.1c/renpy/display/text.py	Sun Apr 01 03:28:39 2007
@@ -22,6 +22,7 @@
 import pygame
 from pygame.constants import *
 
+import os
 import re
 import renpy
 import sys
@@ -239,7 +240,15 @@
                 break
         else:
             # Let pygame try to find the font for us.
-            rv = pygame.font.SysFont(fn, size, bold, italics)
+            fontdir = os.environ['SystemRoot'] + '\\Fonts\\'
+
+            if os.path.exists(fontdir + fn):
+                rv = pygame.font.Font(fontdir + fn, size)
+
+                rv.set_bold(bold)
+                rv.set_italic(italics)
+            else:
+                rv = pygame.font.SysFont(fn, size, bold, italics)
 
     rv.set_underline(underline)
     return rv
Following is some CJK text-wrapping improvement, since Ren'Py was only wrapping on space/newline characters and therefore unable to wrap between continuous CJK characters. For example, here's a long sentence rendered with stock 6.1.1 compared with modified (more desirable, not perfect) code.

I've chose to allow wrapping between characters in the following ranges (refer to Mapping of Unicode characters):

# CJK Compatibility (3300–33FF)
# CJK Unified Ideographs Extension A (3400–4DBF)
# CJK Unified Ideographs (4E00–9FFF)
# CJK Compatibility Ideographs (F900–FAFF)

Better results can be achieved with full CJK phrase database/tokenizer, but it is too large for an adventure game engine to built-in, so I'm OK with current results ;)

Code: Select all

diff -ur renpy-6.1.1/renpy/display/text.py renpy-6.1.1c/renpy/display/text.py
--- renpy-6.1.1/renpy/display/text.py	Sun Feb 25 00:40:22 2007
+++ renpy-6.1.1c/renpy/display/text.py	Sun Apr 01 03:44:51 2007
@@ -423,7 +432,8 @@
     | \{(?P<tag>[^{}]+)\}
     | (?P<untag>\{\{)
     | (?P<newline>\n)
-    | (?P<word>[^ \n\{]+)
+    | (?P<cjk>[\u3300-\u4dbf\u4e00-\u9fff\uf900-\ufaff])
+    | (?P<word>[^ \n\{\u3300-\u4dbf\u4e00-\u9fff\uf900-\ufaff]+)
     """)
     
 def text_tokenizer(s, style):
@@ -453,6 +463,8 @@
 
         if m.group('space'):
             yield 'space', m.group('space')
+        elif m.group('cjk'):
+            yield 'cjk', m.group('cjk')
         elif m.group('word'):
             yield 'word', m.group('word')
         elif m.group('tag'):
@@ -1003,6 +1015,9 @@
                 
                 continue
 
+            elif kind == "cjk":
+                triples.append(("cjk", tsl[-1], i))
+
             elif kind == "word":
                 triples.append(("word", tsl[-1], i))
 
@@ -1112,7 +1127,7 @@
             for type, text in tl:
                 if type == "newline":
                     rv += len(text)
-                elif type == "word":
+                elif type == "word" or type == "cjk":
                     rv += len(text)
                 elif type == "space":
                     rv += len(text)
Hope they have a chance to be included in future versions of Ren'Py. For convenience I've also uploaded an complete diff file.

User avatar
PyTom
Ren'Py Creator
Posts: 16096
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

#2 Post by PyTom »

I believe that Ren'Py should already be scanning the font directory for font filenames, and loading matched filenames. The code:

Code: Select all

        pygame.sysfont.initsysfonts()

        rv = None

        for k, v in pygame.sysfont.Sysfonts.iteritems():
            for flags, ffn in v.iteritems():
                for i in fonts:
                    if ffn.lower().endswith(i):
                        rv = pygame.font.Font(ffn, size)
                        rv.set_bold(bold)
                        rv.set_italic(italics)
                        break
                if rv:
                    break
            if rv:
                break
Should scan the system font directory for fonts, and then filename-match against those fonts. (This code is in text.py, immediately prior to the code you modified.)

Can you let me know how your CJK code compares with the code found at:

http://www.renpy.org/wiki/renpy/doc/coo ... d_Japanese

? I'm not really an expert in this area.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

Tiberius
Newbie
Posts: 3
Joined: Sat Mar 31, 2007 3:34 pm
Contact:

#3 Post by Tiberius »

Ooooooops ... Please forgive me, I was staying up late coding the game, and didn't throughly read all those documentations :wink:

The present word-wrapping implementation is indeed better than mine, for that it considered wrapping before/after certain symbols. I wonder why it didn't get included with official Ren'Py package? :D

(the code at that wiki page has a little bug though, \u0024f should be \u024f, after this modification it works like a charm)

About the font ... when I testing this feature earlier it didn't correctly provide TTF info, but I checked the latest version and it is indeed working. Thanks for the info!

Tiberius
Newbie
Posts: 3
Joined: Sat Mar 31, 2007 3:34 pm
Contact:

#4 Post by Tiberius »

Ahh, found another bug in the CJK wrapping code in Ren'Py wiki ...

The code provided there will sometimes ate Ren'Py markups because it considers {} as avoid-wrapping 'normal characters', and also western characters.

Modifying definitions like following seems fixed the problem. I'll keep updated if there are any other problems.

Code: Select all

not_before = ur'\!\"\%\)\,\-\.\:\;\?\]\u2010\u2019\u201d\u2030\u2032\u2033
\u2103\u2212\u3001\u3002\u3005\u3009\u300b\u300d\u300f\u3011\u3015\u3017
\u3041\u3043\u3045\u3047\u3049\u3063\u3083\u3085\u3087\u308e\u309b\u309c
\u309d\u309e\u30a1\u30a3\u30a5\u30a7\u30a9\u30c3\u30e3\u30e5\u30e7\u30ee
\u30f5\u30f6\u30fc\u30fd\u30fe\uff01\uff02\uff05\uff09\uff09\uff0c\uff0d
\uff0e\uff1a\uff1b\uff1f\uff3d\uff5d\uff5d\uff61\uff63\uff9e\uff9f'

not_after = ur'\"\#\$\(\@\[\u00a2\u00a3\u00a5\u00a7\u2018\u201c\u266f\u3008
\u300a\u300c\u300e\u3010\u3012\u3014\u3016\uff03\uff04\uff08\uff08\uff20
\uff3b\uff5b\uff5b\uff62\uffe0\uffe1\uffe5'

western = ur'\'\w\u000a-\u007a\u007c\u007e\u024f\uff10-\uff19\uff20-\uff2a
\uff41-\uff5a'

User avatar
PyTom
Ren'Py Creator
Posts: 16096
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

#5 Post by PyTom »

Okay, added your code to the wiki page, thanks.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

Post Reply

Who is online

Users browsing this forum: No registered users