| 1 | // Aseprite | 
|---|
| 2 | // Copyright (C) 2018-2022  Igara Studio S.A. | 
|---|
| 3 | // Copyright (C) 2001-2017  David Capello | 
|---|
| 4 | // | 
|---|
| 5 | // This program is distributed under the terms of | 
|---|
| 6 | // the End-User License Agreement for Aseprite. | 
|---|
| 7 |  | 
|---|
| 8 | #ifdef HAVE_CONFIG_H | 
|---|
| 9 | #include "config.h" | 
|---|
| 10 | #endif | 
|---|
| 11 |  | 
|---|
| 12 | #include "app/cli/app_options.h" | 
|---|
| 13 |  | 
|---|
| 14 | #include "base/fs.h" | 
|---|
| 15 |  | 
|---|
| 16 | #include <iostream> | 
|---|
| 17 |  | 
|---|
| 18 | namespace app { | 
|---|
| 19 |  | 
|---|
| 20 | AppOptions::AppOptions(int argc, const char* argv[]) | 
|---|
| 21 | : m_exeName(base::get_file_name(argv[0])) | 
|---|
| 22 | , m_startUI(true) | 
|---|
| 23 | , m_startShell(false) | 
|---|
| 24 | , m_previewCLI(false) | 
|---|
| 25 | , m_showHelp(false) | 
|---|
| 26 | , m_showVersion(false) | 
|---|
| 27 | , m_verboseLevel(kNoVerbose) | 
|---|
| 28 | #ifdef ENABLE_SCRIPTING | 
|---|
| 29 | , m_shell(m_po.add( "shell").description( "Start an interactive console to execute scripts")) | 
|---|
| 30 | #endif | 
|---|
| 31 | , m_batch(m_po.add( "batch").mnemonic('b').description( "Do not start the UI")) | 
|---|
| 32 | , m_preview(m_po.add( "preview").mnemonic('p').description( "Do not execute actions, just print what will be\ndone")) | 
|---|
| 33 | , m_saveAs(m_po.add( "save-as").requiresValue( "<filename>").description( "Save the last given sprite with other format")) | 
|---|
| 34 | , m_palette(m_po.add( "palette").requiresValue( "<filename>").description( "Change the palette of the last given sprite")) | 
|---|
| 35 | , m_scale(m_po.add( "scale").requiresValue( "<factor>").description( "Resize all previously opened sprites")) | 
|---|
| 36 | , m_ditheringAlgorithm(m_po.add( "dithering-algorithm").requiresValue( "<algorithm>").description( "Dithering algorithm used in --color-mode\nto convert images from RGB to Indexed\n  none\n  ordered\n  old")) | 
|---|
| 37 | , m_ditheringMatrix(m_po.add( "dithering-matrix").requiresValue( "<id>").description( "Matrix used in ordered dithering algorithm\n  bayer2x2\n  bayer4x4\n  bayer8x8\n  filename.png")) | 
|---|
| 38 | , m_colorMode(m_po.add( "color-mode").requiresValue( "<mode>").description( "Change color mode of all previously\nopened sprites:\n  rgb\n  grayscale\n  indexed")) | 
|---|
| 39 | , m_shrinkTo(m_po.add( "shrink-to").requiresValue( "width,height").description( "Shrink each sprite if it is\nlarger than width or height")) | 
|---|
| 40 | , m_data(m_po.add( "data").requiresValue( "<filename.json>").description( "File to store the sprite sheet metadata")) | 
|---|
| 41 | , m_format(m_po.add( "format").requiresValue( "<format>").description( "Format to export the data file\n(json-hash, json-array)")) | 
|---|
| 42 | , m_sheet(m_po.add( "sheet").requiresValue( "<filename.png>").description( "Image file to save the texture")) | 
|---|
| 43 | , m_sheetType(m_po.add( "sheet-type").requiresValue( "<type>").description( "Algorithm to create the sprite sheet:\n  horizontal\n  vertical\n  rows\n  columns\n  packed")) | 
|---|
| 44 | , m_sheetPack(m_po.add( "sheet-pack").description( "Same as -sheet-type packed")) | 
|---|
| 45 | , m_sheetWidth(m_po.add( "sheet-width").requiresValue( "<pixels>").description( "Sprite sheet width")) | 
|---|
| 46 | , m_sheetHeight(m_po.add( "sheet-height").requiresValue( "<pixels>").description( "Sprite sheet height")) | 
|---|
| 47 | , m_sheetColumns(m_po.add( "sheet-columns").requiresValue( "<columns>").description( "Fixed # of columns for -sheet-type rows")) | 
|---|
| 48 | , m_sheetRows(m_po.add( "sheet-rows").requiresValue( "<rows>").description( "Fixed # of rows for -sheet-type columns")) | 
|---|
| 49 | , m_splitLayers(m_po.add( "split-layers").description( "Save each visible layer of sprites\nas separated images in the sheet\n")) | 
|---|
| 50 | , m_splitTags(m_po.add( "split-tags").description( "Save each tag as a separated file")) | 
|---|
| 51 | , m_splitSlices(m_po.add( "split-slices").description( "Save each slice as a separated file")) | 
|---|
| 52 | , m_splitGrid(m_po.add( "split-grid").description( "Save each grid tile as a separated file")) | 
|---|
| 53 | , m_layer(m_po.add( "layer").alias( "import-layer").requiresValue( "<name>").description( "Include just the given layer in the sheet\nor save as operation")) | 
|---|
| 54 | , m_allLayers(m_po.add( "all-layers").description( "Make all layers visible\nBy default hidden layers will be ignored")) | 
|---|
| 55 | , m_ignoreLayer(m_po.add( "ignore-layer").requiresValue( "<name>").description( "Exclude the given layer in the sheet\nor save as operation")) | 
|---|
| 56 | , m_tag(m_po.add( "tag").alias( "frame-tag").requiresValue( "<name>").description( "Include tagged frames in the sheet")) | 
|---|
| 57 | , m_frameRange(m_po.add( "frame-range").requiresValue( "from,to").description( "Only export frames in the [from,to] range")) | 
|---|
| 58 | , m_ignoreEmpty(m_po.add( "ignore-empty").description( "Do not export empty frames/cels")) | 
|---|
| 59 | , m_mergeDuplicates(m_po.add( "merge-duplicates").description( "Merge all duplicate frames into one in the sprite sheet")) | 
|---|
| 60 | , m_borderPadding(m_po.add( "border-padding").requiresValue( "<value>").description( "Add padding on the texture borders")) | 
|---|
| 61 | , m_shapePadding(m_po.add( "shape-padding").requiresValue( "<value>").description( "Add padding between frames")) | 
|---|
| 62 | , m_innerPadding(m_po.add( "inner-padding").requiresValue( "<value>").description( "Add padding inside each frame")) | 
|---|
| 63 | , m_trim(m_po.add( "trim").description( "Trim whole sprite for --save-as\nor individual frames for --sheet")) | 
|---|
| 64 | , m_trimSprite(m_po.add( "trim-sprite").description( "Trim the whole sprite (for --save-as and --sheet)")) | 
|---|
| 65 | , m_trimByGrid(m_po.add( "trim-by-grid").description( "Trim all images by its correspondent grid boundaries before exporting")) | 
|---|
| 66 | , m_extrude(m_po.add( "extrude").description( "Extrude all images duplicating all edges one pixel")) | 
|---|
| 67 | , m_crop(m_po.add( "crop").requiresValue( "x,y,width,height").description( "Crop all the images to the given rectangle")) | 
|---|
| 68 | , m_slice(m_po.add( "slice").requiresValue( "<name>").description( "Crop the sprite to the given slice area")) | 
|---|
| 69 | , m_filenameFormat(m_po.add( "filename-format").requiresValue( "<fmt>").description( "Special format to generate filenames")) | 
|---|
| 70 | #ifdef ENABLE_SCRIPTING | 
|---|
| 71 | , m_script(m_po.add( "script").requiresValue( "<filename>").description( "Execute a specific script")) | 
|---|
| 72 | , m_scriptParam(m_po.add( "script-param").requiresValue( "name=value").description( "Parameter for a script executed from the\nCLI that you can access with app.params")) | 
|---|
| 73 | #endif | 
|---|
| 74 | , m_listLayers(m_po.add( "list-layers").description( "List layers of the next given sprite\nor include layers in JSON data")) | 
|---|
| 75 | , m_listTags(m_po.add( "list-tags").description( "List tags of the next given sprite\nor include frame tags in JSON data")) | 
|---|
| 76 | , m_listSlices(m_po.add( "list-slices").description( "List slices of the next given sprite\nor include slices in JSON data")) | 
|---|
| 77 | , m_oneFrame(m_po.add( "oneframe").description( "Load just the first frame")) | 
|---|
| 78 | , m_exportTileset(m_po.add( "export-tileset").description( "Export only tilesets from visible tilemap layers")) | 
|---|
| 79 | , m_verbose(m_po.add( "verbose").mnemonic('v').description( "Explain what is being done")) | 
|---|
| 80 | , m_debug(m_po.add( "debug").description( "Extreme verbose mode and\ncopy log to desktop")) | 
|---|
| 81 | #ifdef _WIN32 | 
|---|
| 82 | , m_disableWintab(m_po.add( "disable-wintab").description( "Don't load wintab32.dll library")) | 
|---|
| 83 | #endif | 
|---|
| 84 | , m_help(m_po.add( "help").mnemonic('?').description( "Display this help and exits")) | 
|---|
| 85 | , m_version(m_po.add( "version").description( "Output version information and exit")) | 
|---|
| 86 | { | 
|---|
| 87 | try { | 
|---|
| 88 | m_po.parse(argc, argv); | 
|---|
| 89 |  | 
|---|
| 90 | if (m_po.enabled(m_debug)) | 
|---|
| 91 | m_verboseLevel = kHighlyVerbose; | 
|---|
| 92 | else if (m_po.enabled(m_verbose)) | 
|---|
| 93 | m_verboseLevel = kVerbose; | 
|---|
| 94 |  | 
|---|
| 95 | #ifdef ENABLE_SCRIPTING | 
|---|
| 96 | m_startShell = m_po.enabled(m_shell); | 
|---|
| 97 | #endif | 
|---|
| 98 | m_previewCLI = m_po.enabled(m_preview); | 
|---|
| 99 | m_showHelp = m_po.enabled(m_help); | 
|---|
| 100 | m_showVersion = m_po.enabled(m_version); | 
|---|
| 101 |  | 
|---|
| 102 | if (m_startShell || | 
|---|
| 103 | m_showHelp || | 
|---|
| 104 | m_showVersion || | 
|---|
| 105 | m_po.enabled(m_batch)) { | 
|---|
| 106 | m_startUI = false; | 
|---|
| 107 | } | 
|---|
| 108 | } | 
|---|
| 109 | catch (const std::runtime_error& parseError) { | 
|---|
| 110 | std::cerr << m_exeName << ": "<< parseError.what() << '\n' | 
|---|
| 111 | << "Try \""<< m_exeName << " --help\" for more information.\n"; | 
|---|
| 112 | m_startUI = false; | 
|---|
| 113 | } | 
|---|
| 114 | } | 
|---|
| 115 |  | 
|---|
| 116 | bool AppOptions::hasExporterParams() const | 
|---|
| 117 | { | 
|---|
| 118 | return | 
|---|
| 119 | m_po.enabled(m_data) || | 
|---|
| 120 | m_po.enabled(m_sheet); | 
|---|
| 121 | } | 
|---|
| 122 |  | 
|---|
| 123 | #ifdef _WIN32 | 
|---|
| 124 | bool AppOptions::disableWintab() const | 
|---|
| 125 | { | 
|---|
| 126 | return m_po.enabled(m_disableWintab); | 
|---|
| 127 | } | 
|---|
| 128 | #endif | 
|---|
| 129 |  | 
|---|
| 130 | } | 
|---|
| 131 |  | 
|---|