forked from chrissimpkins/codeface
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrender.py
More file actions
126 lines (115 loc) · 5.43 KB
/
Copy pathrender.py
File metadata and controls
126 lines (115 loc) · 5.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# Copyright (c) 2015 Andrew Kensler
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# python render.py -t samplecode/test-pattern.txt -l text -x 725 -b "\#ddddddff" -i test.png -f "Anonymous Pro 16"
import argparse
import codecs
import pygments
import pygments.lexers
import pygments.formatters
import re
import cairo
import pango
import pangocairo
# Basic argument parsing
parser = argparse.ArgumentParser(
description = "Render sample images of fonts using Pango/Cairo.",
formatter_class = argparse.ArgumentDefaultsHelpFormatter )
parser.add_argument( "-t", "--text", default = "sample.txt",
help = "name of sample text to render" )
parser.add_argument( "-l", "--lang", default = "text",
help = "Pygments language to interpret sample as" )
parser.add_argument( "-s", "--style", default = "borland",
help = "Pygments style to render sample in" )
parser.add_argument( "-r", "--regular", action="store_true",
help = "regular only, ignore bold and italic in style" )
parser.add_argument( "-i", "--image", default = "sample.png",
help = "name of image to write" )
parser.add_argument( "-f", "--font", default = "monospace 15",
help = "Pango specification for font to use" )
parser.add_argument( "-m", "--mode", default = "subpixel",
choices = [ "grey", "bilevel", "subpixel" ],
help = "antialiasing mode" )
parser.add_argument( "-b", "--background", default = "#ffffffff",
help = "background color and opacity" )
parser.add_argument( "-p", "--pad", default = 4, type = int,
help = "padding in pixels around image" )
parser.add_argument( "-x", "--width", default = 0, type = int,
help = "minimum width of image to generate" )
parser.add_argument( "-y", "--height", default = 0, type = int,
help = "minimum height of image to generate" )
args = parser.parse_args()
# Read sample text in (may be utf-8) and optionally syntax highlight it
# with Pygments. The markup will be adapted for Pango.
with codecs.open( args.text, encoding = "utf-8" ) as source:
text = source.read().strip( "\n" )
lexer = pygments.lexers.get_lexer_by_name( args.lang )
formatter = pygments.formatters.HtmlFormatter(
noclasses = True,
nowrap = True,
style = args.style )
text = pygments.highlight( text, lexer, formatter )
text = re.sub( "style=\"color: (#[0-9A-Fa-f]{6})(?:; )?",
"foreground=\"\\1\" style=\"", text )
if args.regular:
text = re.sub( "style=\"font-weight: bold(?:; )?",
"style=\"", text )
text = re.sub( "style=\"font-style: italic(?:; )?",
"style=\"", text )
else:
text = re.sub( "style=\"font-weight: bold(?:; )?",
"weight=\"bold\" style=\"", text )
text = re.sub( "style=\"font-style: italic(?:; )?",
"style=\"italic\" style=\"", text )
text = re.sub( "style=\"background-color: (#[0-9A-Fa-f]{6})(?:; )?",
"background=\"\\1\" style=\"", text )
text = re.sub( "style=\"\"", "", text )
text = text.strip()
# First pass, find image size to hold the text.
mode = { "grey" : -1,
"bilevel" : cairo.ANTIALIAS_NONE,
"subpixel" : cairo.ANTIALIAS_SUBPIXEL
}[ args.mode ]
pangocairo.cairo_font_map_get_default().set_resolution( 72 )
surface = cairo.ImageSurface( cairo.FORMAT_ARGB32, 0, 0 )
context = pangocairo.CairoContext( cairo.Context( surface ) )
layout = context.create_layout()
options = cairo.FontOptions()
options.set_antialias( mode )
pangocairo.context_set_font_options( layout.get_context(), options )
layout.set_font_description( pango.FontDescription( args.font ) )
layout.set_markup( text )
width = max( layout.get_pixel_size()[ 0 ] + args.pad * 2, args.width )
height = max( layout.get_pixel_size()[ 1 ] + args.pad * 2, args.height )
# Second pass, render actual image and save it.
surface = cairo.ImageSurface( cairo.FORMAT_ARGB32, width, height )
context = pangocairo.CairoContext( cairo.Context( surface ) )
layout = context.create_layout()
options = cairo.FontOptions()
options.set_antialias( mode )
pangocairo.context_set_font_options( layout.get_context(), options )
layout.set_font_description( pango.FontDescription( args.font ) )
layout.set_markup( text )
context.set_source_rgba(
int( args.background[ 1 : 3 ], 16 ) / 255.0,
int( args.background[ 3 : 5 ], 16 ) / 255.0,
int( args.background[ 5 : 7 ], 16 ) / 255.0,
int( args.background[ 7 : 9 ], 16 ) / 255.0 )
context.rectangle( 0, 0, width, height )
context.fill()
context.set_source_rgb( 0, 0, 0 )
context.translate( args.pad, args.pad )
context.update_layout( layout )
context.show_layout( layout )
with open( args.image, "wb" ) as result:
surface.write_to_png( result )