pebble/tools/generate_pdcs/pdc_gen.py
2025-01-27 11:38:16 -08:00

136 lines
5.3 KiB
Python

# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
'''
PDC_GEN converts SVG images, SVG sequences, or JSON sequences to a PDC (Pebble Draw Command) binary format image or sequence. The PDC file format
consists of a header, followed by the binary representation of a PDC image or sequence.
The file header is as follows:
Magic Word (4 bytes) - 'PDCI' for image, 'PDCS' for sequence
Size (4 bytes) - size of PDC image or sequence following the header in bytes
'''
import os
import argparse
import pebble_commands
import svg2commands
import json2commands
def create_pdc_data_from_path(path, viewbox_size, verbose, duration, play_count,
precise=False, raise_error=False):
dir_name = path
output = ''
errors = []
if not os.path.exists(path):
raise Exception("Invalid path")
if verbose:
print path + ":"
if os.path.isfile(path):
dir_name = os.path.dirname(path)
frames = []
commands = []
if os.path.isfile(path):
ext = os.path.splitext(path)[-1]
if ext == '.json':
# JSON file
result = json2commands.parse_json_sequence(path, viewbox_size, precise, raise_error)
if result:
frames = result[0]
errors += result[1]
frame_duration = result[2]
output = pebble_commands.serialize_sequence(
frames, viewbox_size, frame_duration, play_count)
elif ext == '.svg':
# SVG file
size, commands, error = svg2commands.parse_svg_image(path, verbose, precise,
raise_error)
if commands:
output = pebble_commands.serialize_image(commands, size)
if error:
errors += [path]
else:
# SVG files
# get all .svg files in directory
result = svg2commands.parse_svg_sequence(dir_name, verbose, precise, raise_error)
if result:
frames = result[1]
size = result[0]
errors += result[2]
output = pebble_commands.serialize_sequence(frames, size, duration, play_count)
if verbose:
if frames:
pebble_commands.print_frames(frames)
elif commands:
pebble_commands.print_commands(commands)
return output, errors
def create_pdc_from_path(path, out_path, viewbox_size, verbose, duration, play_count,
precise=False, raise_error=False):
output, errors = create_pdc_data_from_path(path, viewbox_size, verbose, duration, play_count,
precise=False, raise_error=False)
if output != '':
if out_path is None:
if sequence:
f = os.path.basename(dir_name.rstrip('/')) + '.pdc'
else:
base = os.path.basename(path)
f = '.'.join(base.split('.')[:-1]) + '.pdc'
out_path = os.path.join(dir_name, f)
with open(out_path, 'w') as out_file:
out_file.write(output)
out_file.close()
return errors
def main(args):
path = os.path.abspath(args.path)
viewbox_size = (args.viewbox_x, args.viewbox_y)
errors = create_pdc_from_path(path, args.output, viewbox_size, args.verbose, args.duration,
args.play_count, args.precise)
if errors:
print "Errors in the following files or frames:"
for ef in errors:
print "\t" + str(ef)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('path', type=str,
help="Path to svg file or directory (with multiple svg files)")
parser.add_argument('-o', '--output', type=str,
help="Output file path (.pdc will be appended to file name if it is not included in the path "
"specified")
parser.add_argument('-v', '--verbose', action='store_true',
help="Verbose output")
parser.add_argument('-d', '--duration', type=int, default=33,
help="Duration (ms) of each frame in a sequence (SVG sequence only) - default = 33ms")
parser.add_argument('-c', '--play_count', type=int, default=1,
help="Number of times the sequence should play - default = 1")
parser.add_argument('-p', '--precise', action='store_true',
help="Use sub-pixel precision for paths")
parser.add_argument('-x', '--viewbox_x', help="Viewbox length (JSON sequence only)",
type=int, default=json2commands.DISPLAY_DIM_X)
parser.add_argument('-y', '--viewbox_y', help="Viewbox height (JSON sequence only)",
type=int, default=json2commands.DISPLAY_DIM_Y)
args = parser.parse_args()
main(args)