Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update resource-building scripts for future compatibility. #656

Merged
merged 4 commits into from
May 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/linux-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ jobs:
sudo apt install cmake libcurl4-openssl-dev libopenal-dev libssl-dev \
libogg-dev libopus-dev libspeex-dev uuid-dev libvpx-dev \
libvorbis-dev qtbase5-dev
sudo pip install -r ${GITHUB_WORKSPACE}/requirements.txt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too bad the resource.dat is never built on linux-ci since it's part of the plClient build :trollface:

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not currently, but hopefully that will change. I know the scripts run on there because I've done so. :trollface:

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the requirements file allows specifications based on environment (such as OS), it makes sense to add this to both build systems for consistency (and to watch for accidental breakages).

- name: Build string_theory
run: |
mkdir -p build_deps && cd build_deps
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Plasma currently requires the following third-party libraries:

The following libraries are optional:

- (for building resource.dat) PyGTK - http://www.pygtk.org/downloads.html
- (for building resource.dat) CairoSVG - https://cairosvg.org/
- (for building resource.dat) Pillow - https://python-pillow.org/
- (for plFontConverter) Freetype - http://freetype.org/
- (for the GUI tools) Qt5 - http://www.qt.io/download-open-source/
Expand Down
8 changes: 5 additions & 3 deletions Sources/Plasma/Apps/plClient/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ set_package_properties(PythonInterp PROPERTIES

if(PYTHONINTERP_FOUND)
include(FindPythonModule)

# Test for Python modules needed to build resource.dat
find_python_module(rsvg)
find_python_module(cairosvg)
find_python_module(PIL)
if((DEFINED PY_RSVG) AND (DEFINED PY_PIL))

if((DEFINED PY_CAIROSVG) AND (DEFINED PY_PIL))
set(CAN_BUILD_RESOURCE_DAT ON)
endif((DEFINED PY_RSVG) AND (DEFINED PY_PIL))
endif((DEFINED PY_CAIROSVG) AND (DEFINED PY_PIL))
endif(PYTHONINTERP_FOUND)

set(plClient_HEADERS
Expand Down
5 changes: 3 additions & 2 deletions Sources/Plasma/Apps/plClient/external/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
set(external_SCRIPTS
create_resource_dat.py
makeres.py
render_svg.py
create_resource_dat.py
render_svg.py
scalergba.py
)

set(external_SOURCES
Expand Down
7 changes: 3 additions & 4 deletions Sources/Plasma/Apps/plClient/external/Linking_Book.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def create_resource_dat(resfilepath, inrespath):
datFile.write(struct.pack("<I",len(resourceList)))
for res in resourceList:
with open(res, "rb") as resFile:
name = os.path.basename(res)
name = os.path.basename(res).encode("utf-8")
datFile.write(struct.pack("<I", len(name)))
datFile.write(name)
datFile.write(struct.pack("<I", os.path.getsize(res)))
Expand Down
89 changes: 25 additions & 64 deletions Sources/Plasma/Apps/plClient/external/render_svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@
import scalergba

try:
import rsvg
import cairo
import cairosvg
except ImportError as e:
print("Rendering SVG resources requires PyGTK. Exiting...")
print("Rendering SVG resources requires CairoSVG. Exiting...")
exit(1)

cursorList = {
Expand Down Expand Up @@ -116,6 +115,10 @@ def shift_all_layers(layers, shiftx, shifty):
for layer in layers:
layers[layer].setAttribute("transform", "translate(%g,%g)" % (shiftx, shifty))

def rotate_layer(layer, angle, offX, offY):
# note: this assumes that this layer starts out with no transform of their own
layer.setAttribute("transform", "rotate(%g %g %g)" % (angle, offX, offY))

def get_layers_from_svg(svgData):
inkscapeNS = "http://www.inkscape.org/namespaces/inkscape"
layers = {}
Expand All @@ -134,104 +137,62 @@ def render_cursors(inpath, outpath):
layers = get_layers_from_svg(cursorSVG)
svgwidth = float(cursorSVG.documentElement.getAttribute("width"))
svgheight = float(cursorSVG.documentElement.getAttribute("height"))
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(math.ceil(scalefactor*svgwidth)), int(math.ceil(scalefactor*svgheight)))

for cursor in cursorList:
ctx = cairo.Context(surface)
ctx.save()
ctx.set_operator(cairo.OPERATOR_CLEAR)
ctx.paint()
ctx.restore()

enabledlayers = cursorList[cursor]
enabledlayers = enabledlayers + [l + "Shadow" for l in enabledlayers]
enable_only_layers(enabledlayers, layers)

shift_all_layers(layers, *cursorOffsetList.get(cursor, [0, 0]))

svg = rsvg.Handle(data=cursorSVG.toxml())
ctx.scale(scalefactor, scalefactor)
svg.render_cairo(ctx)

outfile = os.path.join(outpath, cursor + ".png")
surface.write_to_png(outfile)
cairosvg.svg2png(bytestring=cursorSVG.toxml().encode('utf-8'), write_to=outfile,
parent_width=svgwidth, parent_height=svgheight, scale=scalefactor)
scalergba.scale(outfile, outfile, scalefactor)

def render_loading_books(inpath, outpath):
resSize = {"width":256, "height":256}
with open(os.path.join(inpath,"Linking_Book.svg"), "r") as svgFile:
bookSVG = parse(svgFile)
layers = get_layers_from_svg(bookSVG)
ratioW = resSize["width"] / float(bookSVG.documentElement.getAttribute("width"))
ratioH = resSize["height"] / float(bookSVG.documentElement.getAttribute("height"))
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, resSize["width"], resSize["height"])
cX = float(bookSVG.documentElement.getAttribute("width")) / 2
cY = float(bookSVG.documentElement.getAttribute("height")) / 2

for angle in range(0, 18):
ctx = cairo.Context(surface)

# Draw Book and Black Background
enable_only_layers(["background", "book"],layers)
svg = rsvg.Handle(data=bookSVG.toxml())
ctx.save()
ctx.scale(ratioW, ratioH)
svg.render_cairo(ctx)
ctx.restore()

# Draw Circles at appropriate angle
enable_only_layers(["circles"],layers)
svg = rsvg.Handle(data=bookSVG.toxml())
ctx.translate(resSize["height"] / 2, resSize["width"] / 2)
ctx.rotate(math.radians(angle*(5)))
ctx.translate(-resSize["width"] / 2, -resSize["height"] / 2)
ctx.scale(ratioW, ratioH)
svg.render_cairo(ctx)

surface.write_to_png(os.path.join(outpath, "xLoading_Linking.{0:02}.png".format(angle)))
# Draw Book, Black Background, and rotating Circles
enable_only_layers(["background", "book", "circles"],layers)

# Rotate Circles at appropriate angle
rotate_layer(layers["circles"], angle*5, cX, cY)

cairosvg.svg2png(bytestring=bookSVG.toxml().encode('utf-8'),
write_to=os.path.join(outpath, "xLoading_Linking.{0:02}.png".format(angle)),
parent_width=resSize["width"], parent_height=resSize["height"])

def render_loading_text(inpath, outpath):
resSize = {"width":192, "height":41}
with open(os.path.join(inpath,"Loading_Text_rasterfont.svg"), "r") as svgFile:
textSVG = parse(svgFile)
layers = get_layers_from_svg(textSVG)
ratioW = resSize["width"] / float(textSVG.documentElement.getAttribute("width"))
ratioH = resSize["height"] / float(textSVG.documentElement.getAttribute("height"))
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, resSize["width"], resSize["height"])

for textEntry in textList:
ctx = cairo.Context(surface)
ctx.save()
ctx.set_operator(cairo.OPERATOR_CLEAR)
ctx.paint()
ctx.restore()
enable_only_layers(textList[textEntry], layers)
svg = rsvg.Handle(data=textSVG.toxml())
ctx.scale(ratioW, ratioH)
svg.render_cairo(ctx)
surface.write_to_png(os.path.join(outpath, textEntry + ".png"))
cairosvg.svg2png(bytestring=textSVG.toxml().encode('utf-8'),
write_to=os.path.join(outpath, textEntry + ".png"),
parent_width=resSize["width"], parent_height=resSize["height"])

def render_voice_icons(inpath, outpath):
resSize = {"width":32, "height":32}
with open(os.path.join(inpath,"Voice_Chat.svg"), "r") as svgFile:
uiSVG = parse(svgFile)
layers = get_layers_from_svg(uiSVG)
ratioW = resSize["width"] / float(uiSVG.documentElement.getAttribute("width"))
ratioH = resSize["height"] / float(uiSVG.documentElement.getAttribute("height"))
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, resSize["width"], resSize["height"])

for voiceUI in voiceList:
ctx = cairo.Context(surface)
ctx.save()
ctx.set_operator(cairo.OPERATOR_CLEAR)
ctx.paint()
ctx.restore()

enable_only_layers(voiceList[voiceUI], layers)

svg = rsvg.Handle(data=uiSVG.toxml())
ctx.scale(ratioW, ratioH)
svg.render_cairo(ctx)

surface.write_to_png(os.path.join(outpath, voiceUI + ".png"))
cairosvg.svg2png(bytestring=uiSVG.toxml().encode('utf-8'),
write_to=os.path.join(outpath, voiceUI + ".png"),
parent_width=resSize["width"], parent_height=resSize["height"])

if __name__ == '__main__':
parser = OptionParser(usage="usage: %prog [options]")
Expand Down
4 changes: 4 additions & 0 deletions Sources/Plasma/Apps/plClient/external/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
https://download.lfd.uci.edu/pythonlibs/s2jqpv5t/cp27/pycairo-1.18.2-cp27-cp27m-win32.whl; sys_platform == "win32" and python_version ~= "2.7"
cairosvg==1.0.22 ; python_version ~= "2.7"
cairosvg; python_version >= "3.7"
pillow
4 changes: 1 addition & 3 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ install:
Write-Host "OK" -foregroundColor Green

Write-Host "Installing Python modules... " -noNewLine
Invoke-WebRequest "http://ftp.gnome.org/pub/GNOME/binaries/win32/pygtk/2.24/pygtk-all-in-one-2.24.2.win32-py2.7.msi" -OutFile pygtk-all-in-one-2.24.2.win32-py2.7.msi
Start-Process msiexec -ArgumentList "/i pygtk-all-in-one-2.24.2.win32-py2.7.msi TRANSFORMS=devlibs\EnableRSVG.mst TARGETDIR=C:\Python27 /qn /norestart" -wait
C:\Python27\python.exe -m pip install -q Pillow 2> $null
C:\Python27\python.exe -m pip install -r ../requirements.txt 2> $null
Write-Host "OK" -foregroundColor Green

Write-Host "Installing library dependencies... "
Expand Down
2 changes: 1 addition & 1 deletion cmake/FindPythonModule.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function(find_python_module module)
# A module's location is usually a directory, but for binary modules
# it's a .so file.
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c"
"import re, ${module}; print re.compile('/__init__.py.*').sub('',${module}.__file__)"
"import re, ${module}; print(re.compile('/__init__.py.*').sub('',${module}.__file__))"
RESULT_VARIABLE _${module}_status
OUTPUT_VARIABLE _${module}_location
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
Expand Down
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# - Python Module Requirements

# Required for building plClient's resource.dat assets
-r ./Sources/Plasma/Apps/plClient/external/requirements.txt