Initial commit.

This commit is contained in:
Relintai 2020-11-28 22:32:58 +01:00
commit cb326a976b
707 changed files with 95015 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

18
.gitignore vendored Normal file
View File

@ -0,0 +1,18 @@
# Godot-specific ignores
.import/
# Imported translations (automatically generated from CSV files)
*.translation
# Mono-specific ignores
.mono/
data_*/
mono_crash.*.json
# System/tool-specific ignores
.directory
*~
#Visual Studio Code ignores
.vscode/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "addons/godot-gifexporter"]
path = addons/godot-gifexporter
url = https://github.com/novhack/godot-gifexporter.git

294
CHANGELOG.md Normal file
View File

@ -0,0 +1,294 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). All the dates are in YYYY-MM-DD format.
<br><br>
## [v0.8.1] - 2020-10-14
This update has been brought to you by the contributions of:
Laurenz Reinthaler (Schweini07), PinyaColada
### Added
- Buttons for moving the current frame left or right. ([#344](https://github.com/Orama-Interactive/Pixelorama/pull/344))
- Creating palettes from sprites has been enhanced - you can now choose if you want to get colors from the selection, current cel, entire frame or all frames, and if you want the colors to have an alpha component.
- A new "Cut" option in the Edit menu or by pressing `Ctrl-X`. It cuts (deletes & copies) the selection, and you can later paste it. ([#345](https://github.com/Orama-Interactive/Pixelorama/pull/345))
- Added a warning dialog when clicking the remove palette button, to prevent accidental palette deletions.
- A new purple theme.
### Changed
- Guides now move with a step of 0.5 pixels. That makes it possible to have guides (and symmetry guides) to be in the middle of pixels.
- Changed how Dark, Gray, Caramel and Light themes look. All theme elements now have the same spacing and margins.
### Fixed
- Most likely fixed an issue that occurred when the user attempted to export the project, which failed due to a locking error (error code 23). (Part of [#331](https://github.com/Orama-Interactive/Pixelorama/issues/3391))
- Fixed crash where Pixelorama could not load a cached sub-resource. ([#339](https://github.com/Orama-Interactive/Pixelorama/issues/339))
- When moving tabs, the projects now move along with their respective tabs.
- Fixed crash where the animation was playing in the mini canvas preview and then the user switched to a project with less frames.
- Fixed issue with the selection rectangle, where if it was being moved while using paste or delete, it went back to its original position. ([#346](https://github.com/Orama-Interactive/Pixelorama/pull/346))
<br><br>
## [v0.8] - 2020-09-23
This update has been brought to you by the contributions of:
Darshan Phaldesai (luiq54), Igor Santarek (jegor377), rob-a-bolton, Kinwailo, Michael Alexsander (YeldhamDev), Hugo Locurcio (Calinou), Martin Novák (novhack), Xenofon Konitsas (huskeee), Matthew Paul (matthewpaul-us)
### Added
- The Web (HTML5) is now a supported platform of Pixelorama! It is now possible to save .png and .pxo files, as well as load image and palette files in the Web version. Made possible thanks to https://github.com/Pukkah/HTML5-File-Exchange-for-Godot
- Windows, Linux, macOS and Web builds are now automatically generated every time a commit is pushed to master by GitHub Actions.
- Project tabs! You can now have multiple projects open at the same time, and access each one with tabs.
- Gradient generation. A new option under the "Image" menu that lets you generate a RGB gradient.
- The dialog windows of most image effects have been improved. You can now select if you want the effect to apply in the selection, the current cel, the entire frame, all frames or even all projects (tabs)!
- Added previews in all image effect dialog windows with a checkerboard background. Also placed checkerboard backgrounds in the cel buttons of the timeline, and the Export window. ([#206](https://github.com/Orama-Interactive/Pixelorama/issues/206))
- A new isometric grid!
- Ability to remove the current palette. ([#239](https://github.com/Orama-Interactive/Pixelorama/pull/239))
- You can now drag & drop files into the program while it's running to open them. You can open .pxo files, image files and palette (json, gpl and pal) files this way.
- You can now draw on the tiling mode previews! ([#65](https://github.com/Orama-Interactive/Pixelorama/issues/65))
- Added Resize Canvas option to Image menu.
- Added Symmetry Guides. They let you change the axis of symmetry for mirroring. ([#133](https://github.com/Orama-Interactive/Pixelorama/issues/133))
- Palettes can now be created from the colors of the selected sprite.
- You can now preview how the frames of the spritesheet you are importing will look.
- You can now import image files as layers. Their size will be cropped to the project's size.
- You can import image files as brushes, patterns and palettes.
- Buttons have been added in Preferences to restore each setting to its default state.
- Created a NSIS installer for Windows. ([#303](https://github.com/Orama-Interactive/Pixelorama/pull/303))
- Added Scale3X algorithm as an option to scale sprites ([#290](https://github.com/Orama-Interactive/Pixelorama/pull/290))
- Added "Copy", "Paste" and "Delete" options in the Edit menu. ([#281](https://github.com/Orama-Interactive/Pixelorama/pull/281))
- Selection region and size are now being shown when making a selection on the top, next to the position label. ([#281](https://github.com/Orama-Interactive/Pixelorama/pull/281))
- Added color overwrite option for the Pencil tool. ([#282](https://github.com/Orama-Interactive/Pixelorama/pull/282))
- Flip, desaturation and invert colors now have dialogs with previews and extra options. You can now choose individual color channels to invert, including alpha.
- A play button has been added for playing the animation exclusively on the small canvas preview area. A zoom slider for the preview area has been added, too.
- Added color previews next to the themes in Preferences.
- Added options for the checkerboard background to follow camera movement and zoom level. ([#311](https://github.com/Orama-Interactive/Pixelorama/pull/311))
- Added support for importing PAL palette files. ([#315](https://github.com/Orama-Interactive/Pixelorama/pull/315))
- Added Hungarian, Korean and Romanian translations.
### Changed
- The GDNative gif exporter addon has been replaced with a GDScript equivalent. This makes gif exporting possible in all currently supported platforms, and it also adds support for transparency. ([#295](https://github.com/Orama-Interactive/Pixelorama/pull/295))
- Drawing is no longer limited by the canvas boundaries. This means that, if you have a brush largen than 1px, you can draw on the edges of the canvas. All pixels that are being drawn outside of the canvas will still have no effect.
- The guides are now the same for all frames.
- Imported frames are now being cropped to the project's size. It is no longer possible to have multiple sizes for each frame at all in the same project.
- Pixel perfect is no longer enabled when the brush size is bigger than 1px.
- The .pxo file structure has been changed. It's now consisted of a JSON-structured metadata part, where all the data that can be stored as text are, and a binary part, that contain all the actual image data for each cel and project brush.
- You can now choose if you want your .pxo to use ZSTD compression or not.
- To make a straight line, you now have to hold Shift while dragging (moving and pressing) your mouse. Releasing your mouse button makes the line. ([#281](https://github.com/Orama-Interactive/Pixelorama/pull/281))
- When making a straight line, a preview of how the line's pixels will look is now being shown. ([#260](https://github.com/Orama-Interactive/Pixelorama/pull/260))
- Drawing lines with Ctrl are now constrained at 1:1 and 1:2 ([#201](https://github.com/Orama-Interactive/Pixelorama/issues/201))
- Pixelorama now remembers the selected colors, tools and their options when it's closed and re-opened. ([#281](https://github.com/Orama-Interactive/Pixelorama/pull/281))
- The "pixelorama" folder, which contains data like Brushes, Patterns and Palettes has been renamed to "pixelorama_data" for all non-XDG directory paths.
- Mac builds will now have the execute permission by default, and they will be in `.dmg` form. ([#319](https://github.com/Orama-Interactive/Pixelorama/pull/319))
- Linux builds will also have the execute permission by default, and will be compressed as `tar.gz` instead of `.zip`.
- Drawing brushes with mirror also mirrors the images of the brushes themselves. ([#281](https://github.com/Orama-Interactive/Pixelorama/pull/281))
- When making a new palette or importing one and its name already exists, Pixelorama will add a number to its name. For example, "Palette_Name" would become "Palette_Name (2)", "Palette_Name (3)", etc.
- Re-organized preferences dialog.
- The "create new image" dialog now remembers the last created canvas size. The default image settings are being used only when Pixelorama first launches. ([#178](https://github.com/Orama-Interactive/Pixelorama/issues/178))
- Language and theme checkboxes are now radio buttons.
- The Blue theme has more similar margins and seperations with the rest of the themes.
- Fullscreen can be toggled on and off from the View menu.
- Multi-threaded rendering has been enabled. ([#294](https://github.com/Orama-Interactive/Pixelorama/pull/294))
- Use the Dummy audio driver since Pixelorama doesn't play any sounds. ([#312](https://github.com/Orama-Interactive/Pixelorama/pull/312))
### Fixed
- Exporting large images and drawing with large image brushes is now a lot faster. (Because of Godot 3.2.2)
- Pixel perfect strokes no longer leave gaps when the mouse is moving fast. ([#281](https://github.com/Orama-Interactive/Pixelorama/pull/281))
- Fixed failed imports of gpl palettes by adding support for the newer variant of gpl files. ([#250](https://github.com/Orama-Interactive/Pixelorama/pull/250))
- Fixed alpha blending and lighting/darkening issues when drawing pixels with mirroring.
- Fixed issue where if you moved a frame to the start (move left), it was invisible.
- Fixed a rare issue with Undo/Redo not working while motion-drawing and making lines.
- Grid and guides are now longer being displayed on previews. ([#205](https://github.com/Orama-Interactive/Pixelorama/issues/205))
- Fixed a rare problem where the custom mouse cursor's image was failing to load.
- Importing corrupted image files and non-palette json files no longer crash the app.
- Drawing brushes no longer have clipping issues. ([#281](https://github.com/Orama-Interactive/Pixelorama/pull/281))
- When undoing a removal of a brush, the brush index is no longer incorrect. ([#281](https://github.com/Orama-Interactive/Pixelorama/pull/281))
- Fix out-of-bounds error when color picking outside the image. ([#291](https://github.com/Orama-Interactive/Pixelorama/pull/291))
- When a color is being selected from a palette, the outline of the color's button no longer disappears when drawing. ([#329](https://github.com/Orama-Interactive/Pixelorama/pull/329))
### Removed
- The "Import" option from the file menu has been removed, users can now import image files from "Open".
<br><br>
## [v0.7] - 2020-05-16
This update has been brought to you by the contributions of:
Martin Novák (novhack), Darshan Phaldesai (luiq54), Schweini07, Marco Galli (Gaarco), Matheus Pesegoginski (MatheusPese),
sapient-cogbag, Kinwailo, Igor Santarek (jegor377), Dávid Gábor BODOR (dragonfi), John Jerome Romero (Wishdream)
### Added
- Cels are now in the timeline. Each cel refers to a specific layer AND a frame. Frames are a collection of cels for every layer.
- Cel linking is now possible. This way, layers can be "shared" in multiple frames.
- You can now group multiple frames with tags.
- You can now export your projects to `.gif` files.
- A new rotation method has been added, "Upscale, Rotate and Downscale". It's similar to Rotsprite.
- An HSV Adjust dialog has been added in the Images menu.
- Pattern filling is now possible. The bucket tool can now use Patterns to fill areas, instead of a single color.
- An autosave feature that keeps backups of unsaved projects have been added. In the case of a software crash, the users can restore their work with this system.
- Users can now change keyboard shortcut bindings for tools, in the Preferences.
- Pixel Perfect mode has been added for pencil, eraser and lighten/darken tools.
- Importing `.pngs` as palettes is now possible.
- A confirmation message now appears when the user quits Pixelorama, if there are unsaved changes.
- The last edited project gets loaded at startup (toggleable in the Preferences), along with a new option in the File menu that also does this.
- Templates and a lock aspect ratio option have been added to the "Create new image" dialog.
- Locking layers is now possible. When a layer is locked, no changes can be made to it. Layers are unlocked by default.
- Ability to get color for palette buttons, when editing a palette, from the currently selected left and right colors.
- Esperanto, Indonesian & Czech translation.
- When the image is unsaved and the user tries to make a new one, a new warning dialog will appear to ask for confirmation.
- A new zoom tool has been added, and you can also zoom in with the `+` key, and zoom out with `-`.
- You can now move the canvas with the `Arrow keys`. `Shift + Arrows` make it move with medium speed, and `Ctrl + Shift + Arrows` makes it move with high speed.
- The left and right tool icon options (found in Preferences) are now saved and restored on startup.
### Changed
- The UI - and especially the timeline - has been revamped!
- The export dialog has also been revamped.
- An asterisk is added to the window title if there are unsaved changes.
- A VSplitContainer has been added between the canvas and the timeline.
- The texture of the transparent checker background is now no longer affected by the zoom value. The users can now also change the texture's colors and the size.
- Notification text is now black on the gold and light themes.
- Layer's LineEdit now saves the changes when it loses focus, or when the user presses ESC (or Enter).
- LineEdits lose focus when the user presses Enter.
- When cloning a frame, the clone will appear next to the original.
- Scale image and crop image now affect all frames.
- Layer visibility is taken into account when exporting the drawing as a `.png` file. This means that invisible layers will not be included in the final `.png` file.
- The Godot theme has changed and been renamed to Blue. The Gold theme has also been renamed to Caramel.
- When a dialog is opened, the UI in the background gets darker.
- Visual change, added border outlines to all window dialogs.
- Animation now loops by default.
- Onion skinning settings have been moved to a popup window, and 2 new buttons were added. One that toggles onion skinning, and one that opens the settings window.
- The default window size is now 1280x720, and the minimum window size is 1024x576.
- `.pxo` files now use ZSTD compression to result in smaller file sizes.
- Palettes/Brushes get loaded/saved in appropriate locations as specified by the XDG basedir standard, for easier usage of standard Linux/BSD packaging methods and for better per-user usability.
- The splash screen has been revamped and is no longer purple, it now gets affected by the chosen theme.
- The brush selection popup now closes when a brush is selected.
- Pixelorama's version number now appears on the window title.
- Images now get zoomed properly (fit to canvas frame) when they are first created or loaded.
### Fixed
- Chinese characters not being rendered in notifications (the labels that appear when undoing/redoing) and at the splash screen for Platinum & Gold Sponsor Placeholder labels
- Fixed issue when moving frames, the current frame was being shown but the frame next to it was actually the one being drawn on.
- Fixed issue with LineEdits not letting go of focus when the user clicked somewhere else. (Issue #167)
- When the palette, outline and rotate image dialogs are open, the user can't zoom in the canvas anymore.
- Fixed bug where the user could drag the selection and the guides when the canvas had no focus.
- The zoom label on the top bar now shows the correct zoom value when smooth zoom is enabled.
- Fixed issue with Space triggering the event of the last pressed button. This caused unwanted behavior when using Space to move the canvas around. Resolved by changing the focus mode of the buttons to None.
### Removed
- It's no longer possible for frames to have different amounts of layers. All frames have the same amount.
- The guides no longer work with undo/redo.
<br><br>
## [v0.6.2] - 2020-02-17
### Added
- Image layer rotation! Choose between 2 rotation algorithms, Rotxel and Nearest Neighbour - Thanks to azagaya!
- Crowdin integration for contributing translations!
- Spanish translation - thanks to azagaya & Lilly And!
- Chinese Simplified translation - thanks to Chenxu Wang!
- Latvian translation - thanks to Agnis Aldiņš (NeZvers)!
- Translators can now be seen in the About window.
- It is now possible to remove custom brushes with the middle mouse button.
- Added HSV mode to the color picker. (Added automatically because of the Godot 3.2 update)
- Lanczos scaling interpolation. (Added because of the Godot 3.2 update)
- You can now drag and drop (or right click and open with) image and .pxo files in Pixelorama.
- You can now hide the animation timeline - Thanks to YeldhamDev!
### Changed
- Major changes to alpha blending behavior. The alpha values now get added/blended together instead of just replacing the pixel with the new value.
- Replaced some OS alerts with a custom made error dialog.
- Made the zooming smoother, is toggleable in Preferences whether to keep the new zooming or the old one.
- The camera now zooms at the mouse's position.
- Made the "X" button on the custom brushes a little smaller.
- The color picker will now have a small white triangle on the top left of the color preview if at least one of its RGB values are above 1 in Raw mode. (Added automatically because of the Godot 3.2 update)
- You can now toggle the visibility of hidden items on and off in the file dialogs. (Added automatically because of the Godot 3.2 update)
- The language buttons in the preferences have their localized names in their hint tooltips. For example, if you hover over the "English" button while the language is Greek, the hint tooltip will be "Αγγλικά", which is the Greek word for English.
- Translation updates.
- The presets in the ColorPickers are now hidden - Thanks to YeldhamDev!
- When opening a project (.pxo file), the save path is being set to the opened project's path - Thanks to YeldhamDev!
### Fixed
- Delay the splash screen popup so it shows properly centered - Thanks to YeldhamDev!
- Possibly fixed crashes with motion drawing and undo/redoing.
- Fixed bug (which also caused crashes sometimes) when generating an outline inside the image and it was going outside the canvas' borders.
- Fixed crash when importing images that were failing to load. They still fail to load, but Pixelorama does not crash.
- Possibly fixed a rare crash where the cursor image was failing to load. It is now being loaded only once.
- Fixed ruler markings cutting off before they should - Thanks to YeldhamDev!
- Fixed bug where resizing the image on export and moving selection content were not working on Godot 3.2 - Issues #161 and #162
<br><br>
## [v0.6.1] - 2020-01-13
### Added
- Italian translation - thanks to Gaarco!
- In addition to the middle mouse button, you can now use `Space` to pan around the canvas.
- The ability to choose for which color the color picker does its job, the left or the right. (Issue #115)
- Default image settings are now in the Preferences - thanks to Gaarco!
- Added option to hide tool icons next to the cursor - thanks to haonkrub (Issue #122)
### Changed
- When saving a .pxo file, the file path (along with the file name) gets remembered by the Export PNG file dialog path. (Issue #114)
- LightenDarken tool no longer affects transparent pixels.
- More translatable strings, updates to Greek & Brazilian Portuguese (thanks to YeldhamDev) translations.
- The dark theme button is now pressed by default if the user hasn't saved a theme preference in the config file.
- Added a VSplitContainer for the tools and their options, and another one for Palettes and Layers.
- Made minor changes to the UI of tool options, including a ScrollContainer for them.
- Added a ScrollContainer for the palette buttons on the Edit Palette popup.
- Made Palette .json files more readable, and placed "comments" on top of the color data.
- The grid options are now being updated realtime when they're being changed from the preferences, and they are also being saved in the config cache file.
### Fixed
- Fixed crash that occurred when trying to delete contents of a selection, that were outside the canvas.
- Fixed .gpl palettes not being imported correctly - Issue #112
- Fixed crash that occurred when pressing the play buttons on the timeline, on Godot 3.2 - Issue #111
- Fixed bug where, if you had a random brush selected and then selected the pencil tool, "brush color from" did not appear.
- Fixed crash on Godot 3.2.beta6 when pressing the Edit Palette button.
- The canvas updates automatically when onion skinning settings change.
- Fixed a rare crash with straight lines. It was possible that the variable `is_making_line` could be true, even if the line itself has been freed from memory.
- Fixed issue where undo/redo was not working properly for straight lines that went outside the canvas.
<br><br>
## [v0.6] - 2020-01-06
### Added
- Palettes. You can choose default ones or make your own! (Thanks to greusser/CheetoHead - issue #27)
- Multiple theme support (Dark, Gray, Light, Godot, Gold) to better match your style (Thanks to Erevoid)!
- Image menu with new features (Outlines, Color invert, desaturation) for more editing power.
- Added a new splash screen window dialog that appears when Pixelorama loads. Patrons with the rank of Visionaries and above can participate in splash screen artwork contests for every version! Click here for more info: https://www.patreon.com/OramaInteractive
- Added a better circle and filled circle brushes. They use Bresenham's circle algorithm for scaling.
- Added random brushes! Every time you draw, expect to see something different! To create random brushes, place the images you want your brush to have in the same folder, and put the symbol "%" in front of their filename. Examples, "%icon1.png", "%grass_green.png"
- Pixelorama goes worldwide with even more translations! (German, French, Polish, Brazilian Portuguese, Russian, Traditional Chinese)
- Added a layer opacity slider, that lets you change the alpha values of layers.
- Importing spritesheets is now possible.
- Exporting matrix spritesheets is now possible. You can choose how many rows OR columns your spritesheet will be.
- Straight lines now have constrained angles if you press `Ctrl`. With a step of 15 angles.
- Straight line angles are now being shown on the top bar.
- Guide color can now be changed in Preferences.
- Added sliders next to the spinboxes of brush size, brush color interpolation and LightenDarken's amount.
- Color switch has `X` as its shortcut.
- Frames can now be removed with middle click.
- Selection content can be deleted with the "Delete" button.
- Added "View Splash Screen", "Issue Tracker" and "Changelog" as Help menu options
### Changed
- Straight line improvements - it activates by pressing shift after last draw (Thanks to SbNanduri)
- Changed Preferences window's layout.
- Changed export dialog's options to be more clean and easier to understand.
- Switched from a single .csv to gettext for handling translations.
- The About dialog window got an overhaul. It now shows the names of the Development team, Contributors & Donors.
- Changed default cursor shape for the rulers so the users can see that they are interactive.
- Made the layer and timeline buttons have hover textures. (Thanks to Erevoid)
- Brush color interpolation and LightenDarknen's amount now range from 0-100, instead of 0-1.
- Redo has both `Ctrl-Y` and `Shift-Ctrl-Z` as its shortcuts. (Thanks to Schweini07)
- Removed split screen button, you can now drag the second canvas from the right.
- Changed positions of color switch & color default buttons.
- Importing brushes from the Brushes folder now looks inside its subfolders too, but not the subfolders of the subfolders.
- The Brushes folder now gets created if it doesn't exist (tested on Windows)
- Enabled switching between menus in menu bar on hover (Thanks to YeldhamDev)
- The "View" menu remains visible when toggling items (Thanks to YeldhamDev)
- The UI darkens when exiting the application (Thanks to Calinou)
- The bucket tool's "paint all pixels with the same color" now gets limited to the selection, if there is any.
- If the alpha on the color picker is at 0 and any of the other RGB values change, alpha becomes 1. (Issue #54)
### Fixed
- UndoRedo leak (issue #34) (Thanks to qarmin)
- Enabled low processor usage and reduced the amount of times "update()" gets called on Canvas and the rulers, to improve CPU usage. (Thanks to Calinou & Martin1991zab)
- Fixed alpha in custom brushes, because their alpha was being blended along with its RGB values. (Issue #51)
- Fixed "Parent node is busy setting up children, move_child() failed" when the Quit dialog popup was being called. (Issue #90, thanks to Sslaxx)
- Fixed issues with bucket tool and mirroring.
- Fixed issue with invisible layers becomes visible when a layer was added/removed/moved or changed frame.
- Switched to '2D' framebuffer allocation, which results in slightly increased performance and decreased CPU/GPU usage. (Thanks to Calinou)

66
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,66 @@
# How to contribute efficiently
## Table of contents:
* [Reporting bugs or proposing features](#reporting-bugs-or-proposing-features)
* [Contributing pull requests](#contributing-pull-requests)
* [Contributing translations](#contributing-translations)
* [Communicating with developers](#communicating-with-developers)
**Please read the first section before reporting a bug!**
<br><br>
## Reporting bugs or proposing features
Please, open just one issue for each bug you'd like to report, or a feature you'd like to request. Don't open many issues for the same bug or feature request, and don't use the same issue to report more than one bugs, or to request more than one feature. It's best to open different issues for each bug/feature request.
Also, make sure to search the [issue tracker](https://github.com/Orama-Interactive/Pixelorama/issues) before opening a new issue, in case an issue like that exists. If you're unsure, feel free to open an issue. If it's a duplicate, we'll handle it.
When reporting a bug, make sure to provide enough details, such as information about your Operating System (OS), Pixelorama version, Godot version (if you're using the source project) and clear steps to reproduce the issue. Feel free to include screenshots that might help, too.
<br><br>
## Contributing pull requests
If you want to add new features or fix bugs, please make sure that:
- The code you are submitting follows the recommended [GDScript style guide.](https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_styleguide.html)
[Static typing](https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/static_typing.html) is used in the code, so please make sure the code in your PRs also use it.
- Avoid including unneeded files in your commits. This is true mostly for Main.tscn and other scenes, as Godot likes to change them by itself. If you haven't made changes to scenes, please **do NOT** include them in your commits.
- Please have **Trim Trailing Whitespace On Save** enabled. This makes for cleaner VCS diffs. It's usually considered good practice to avoid trailing whitespace in files, and to make sure all files end with a single blank line.
You can enable **Text Editor > Files > Trim Trailing Whitespace On Save** in the Editor Settings to do this automatically in the script editor.
- Make sure your branch is up to date with the master branch. If it's not, please rebase it, if it's possible.
- If your PR is closing an issue, make sure to let us know.
- If you're making visual changes, it's a good idea to include screenshots in your PR. It's an easy way to let others know of the changes you made.
- If you are adding new UI elements with text, please include the new strings in the `Translations.pot` file. Do not include them in the other `*.po` files. Please make sure to group similar elements together (like element names and their tooltips) by placing them close to each other.
- If you want to make changes to UI elements that are PackedScenes, please edit them in their own scene files (open their scenes in the editor) instead of Main.tscn, or their parent scene in general.
- If you are making changes to popup (and as an extension, dialog) nodes as different scenes, please don't forget to turn off their visibility.
- When you're creating a new script, Godot will place some comments and methods for you. If you're not using them, please remove them. They're taking unnecessary space.
- Avoid using the "pass" keyword. It has no actual usage, besides being used as a placeholder for temporarily empty methods and empty cases. Make sure you don't include empty methods and cases in the code of your PR.
- If you are adding new interactive UI elements such as buttons, don't forget to change their mouse default cursor shape to pointing arrow. Hint tooltips that explain the element's usage to the user are welcome too, just make sure to also include them in `Translations.pot`.
- If you are adding new scripts and/or scenes, please put them somewhere inside the `src/` directory, and make sure to use PascalCase for your file and folder names. [Read this guide for more information.](https://www.gdquest.com/docs/guidelines/best-practices/godot-gdscript/)
- If you are adding images or any type of asset, please put them somewhere inside the `assets/` directory, and make sure to use snake_case for your file and folder names.
- Do **NOT** use the `l10n_master`, `release` or `gh-pages` branches for development. Do not base your work from them, and do not open Pull Requests targeted at them.
- If you want to add an error dialog, use the existing ErrorDialog, change its text and pop it up, instead of making a new one.
Please create different pull requests for each feature you'd like to implement, or each bug you'd like to fix. Make sure your pull request only handles one specific topic, and not multiple. If you want to make multiple changes, make a pull request for each of them. For this reason, it's recommended you create new branches in your forked repository, instead of using your fork's master branch.
This [Git style guide](https://github.com/agis-/git-style-guide) has some good practices to have in mind.
If you are new to git, [this guide](https://akrabat.com/the-beginners-guide-to-contributing-to-a-github-project/) will help you.
Keep in mind, however, that not all PRs will be merged. Some may need discussion, or others may be downright closed.
<br><br>
## Contributing translations
Pixelorama uses [Crowdin](https://crowdin.com/project/pixelorama) to host the translations. In order to contribute, you need to login with your Crowdin account, select the language(s) you'd like to provide translations for, select `Translations.pot` and start translating!
If you need help with the context of some strings, or want to translate in a language that is not available, feel free to contact me (Overloaded). All languages are welcome to be translated!
<br><br>
## Communicating with developers
To communicate with developers (e.g. to discuss a feature you want to implement or a bug you want to fix), the following channels can be used:
- [GitHub Issues](https://github.com/Orama-Interactive/Pixelorama/issues): If there is an
existing issue about a topic you want to discuss, just add a comment to it -
all developers watch the repository and will get an email notification. You
can also create a new issue - please keep in mind to create issues only to
discuss quite specific points about the development, and not general user
feedback or support requests.
- [Our Discord Server](https://discord.gg/GTMtr8s): All developers and most contributors are there, so it's the best way for direct chat
about Pixelorama. You can use the channel `#pixelorama-dev` to stay up to date with Pixelorama's developments real-time,
or talk about the developments and request new features. If you seek support, please use the `#pixelorama-help` channel instead.

22
LICENSE Normal file
View File

@ -0,0 +1,22 @@
MIT License
Copyright (c) 2020 Péter Magyar
Copyright (c) 2019-2020 Orama Interactive and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

0
Misc/.gdignore Normal file
View File

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (c) 2019-2020 Orama Interactive and contributors -->
<component type="desktop">
<id>com.orama_interactive.Pixelorama.desktop</id>
<name>Pixelorama</name>
<summary>2D sprite editor with animation support</summary>
<description>
<p>
Pixelorama is a free and open source 2D sprite editor, made by Orama
Interactive in the Godot Engine using GDScript.
</p>
</description>
<metadata_license>CC0-1.0</metadata_license>
<project_license>MIT</project_license>
<developer_name>Orama Interactive</developer_name>
<url type="homepage">https://orama-interactive.itch.io/pixelorama</url>
<url type="bugtracker">https://github.com/Orama-Interactive/Pixelorama/issues</url>
<screenshots>
<screenshot type="default" width="1919" height="1053">
<image type="source">https://static.wixstatic.com/media/673cdd_061f5f9602ea4c35b6d4f3c50713d36a~mv2.png</image>
<caption>Art by Wishdream</caption>
</screenshot>
<screenshot type="default" width="1919" height="1079">
<image type="source">https://static.wixstatic.com/media/cc6108_ccec89c37b3d425da4f03776160c859c~mv2.png</image>
<caption>Art by Erevos</caption>
</screenshot>
<screenshot type="default" width="1919" height="1079">
<image type="source">https://static.wixstatic.com/media/cc6108_854ca4dc022c481f96bbc2b4f03fb04d~mv2.png</image>
<caption>Art by Erevos</caption>
</screenshot>
</screenshots>
<content_rating type="oars-1.1"/>
<releases>
<release version="0.8.1" date="2020-10-14"/>
<release version="0.8" date="2020-09-23"/>
<release version="0.7" date="2020-05-16"/>
<release version="0.6.2" date="2020-02-17"/>
</releases>
<update_contact>hugo.locurcio@hugo.pro</update_contact>
</component>

View File

@ -0,0 +1,15 @@
[Desktop Entry]
Name=Pixelorama
GenericName=2D sprite editor
GenericName[el]=Επεξεργαστής δισδιάστατων εικόνων
GenericName[fr]=Éditeur de sprites 2D
GenericName[pt_BR]=Editor de sprites 2D
Comment=Create and edit static or animated 2D sprites
Comment[el]=Δημιουργήστε και επεξεργαστείτε στατικές ή κινούμενες δισδιάστατες εικόνες
Comment[fr]=Créez et modifiez des sprites 2D statiques ou animées
Comment[pt_BR]=Crie e edite sprites 2D estáticos ou animados
Exec=pixelorama
Icon=pixelorama
Terminal=false
Type=Application
Categories=Graphics;2DGraphics;RasterGraphics;

6
README.md Normal file
View File

@ -0,0 +1,6 @@
# draw_gd
My goal with this project is to take Pixelorama's code, simplify it as much as possible, and make it an editor plugin,
to have an in-godot texture/image editor.
If it turns out well I'll probably turn it into a c++ engine module eventually.

5
Translations/README.md Normal file
View File

@ -0,0 +1,5 @@
### Contributing Translations
If you wish to contribute a translation, make sure to use [Pixelorama's Crowdin page](https://crowdin.com/project/pixelorama). Crowdin is a web-based translation platform, where people can contribute translations together and with ease. Please use Crowdin and do not directly open pull requests to Pixelorama's GitHub repository.
Link: [https://crowdin.com/project/pixelorama](https://crowdin.com/project/pixelorama)

File diff suppressed because it is too large Load Diff

1442
Translations/af_ZA.po Normal file

File diff suppressed because it is too large Load Diff

1442
Translations/ar_SA.po Normal file

File diff suppressed because it is too large Load Diff

1462
Translations/ca_ES.po Normal file

File diff suppressed because it is too large Load Diff

1472
Translations/cs_CZ.po Normal file

File diff suppressed because it is too large Load Diff

1442
Translations/da_DK.po Normal file

File diff suppressed because it is too large Load Diff

1471
Translations/de_DE.po Normal file

File diff suppressed because it is too large Load Diff

1472
Translations/el_GR.po Normal file

File diff suppressed because it is too large Load Diff

750
Translations/en.po Normal file
View File

@ -0,0 +1,750 @@
msgid ""
msgstr ""
"Project-Id-Version: Pixelorama\n"
"Last-Translator: Overloaded\n"
"Language-Team: none\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "OK"
msgstr "OK"
msgid "Cancel"
msgstr "Cancel"
msgid "Open"
msgstr "Open"
msgid "Save"
msgstr "Save"
msgid "Please Confirm..."
msgstr "Please Confirm..."
msgid "Image Size"
msgstr "Image Size"
msgid "Width:"
msgstr "Width:"
msgid "Height:"
msgstr "Height:"
msgid "File"
msgstr "File"
msgid "Edit"
msgstr "Edit"
msgid "View"
msgstr "View"
msgid "Image"
msgstr "Image"
msgid "Effects"
msgstr "Effects"
msgid "Help"
msgstr "Help"
msgid "New..."
msgstr "New..."
msgid "Open..."
msgstr "Open..."
msgid "Save..."
msgstr "Save..."
msgid "Save as..."
msgstr "Save as..."
msgid "Import PNG..."
msgstr "Import PNG..."
msgid "Export"
msgstr "Export"
msgid "Export PNG..."
msgstr "Export PNG..."
msgid "Export PNG as..."
msgstr "Export PNG as..."
msgid "Quit"
msgstr "Quit"
msgid "Undo"
msgstr "Undo"
msgid "Redo"
msgstr "Redo"
msgid "Scale Image"
msgstr "Scale Image"
msgid "Crop Image"
msgstr "Crop Image"
msgid "Clear Selection"
msgstr "Clear Selection"
msgid "Flip Horizontal"
msgstr "Flip Horizontal"
msgid "Flip Vertical"
msgstr "Flip Vertical"
msgid "Preferences"
msgstr "Preferences"
msgid "Tile Mode"
msgstr "Tile Mode"
msgid "Show Grid"
msgstr "Show Grid"
msgid "Show Rulers"
msgstr "Show Rulers"
msgid "Show Guides"
msgstr "Show Guides"
msgid "Fill with color:"
msgstr "Fill with color:"
msgid "Open a File"
msgstr "Open a File"
msgid "Open File(s)"
msgstr "Open File(s)"
msgid "IMPORT_FILE_LABEL"
msgstr "Import as new frame"
msgid "IMPORT_SPRITESHEET"
msgstr "Import as a spritesheet"
msgid "Save Sprite as .pxo"
msgstr "Save Sprite as .pxo"
msgid "Export Sprite as .png"
msgstr "Export Sprite as .png"
msgid "Export Sprite"
msgstr "Export Sprite"
msgid "File Exists, Overwrite?"
msgstr "File Exists, Overwrite?"
msgid "Resize:"
msgstr "Resize:"
msgid "EXPORT_CURRENT_FRAME_LABEL"
msgstr "Export current frame"
msgid "EXPORT_FRAMES_AS_MULTIPLE_FILES_LABEL"
msgstr "Export all frames as multiple files"
msgid "EXPORT_FRAMES_AS_SPRITESHEET_LABEL"
msgstr "Export all frames as a spritesheet (single file)"
msgid "Columns"
msgstr "Columns"
msgid "Rows"
msgstr "Rows"
msgid "Path:"
msgstr "Path:"
msgid "Directories & Files:"
msgstr "Directories & Files:"
msgid "Create Folder"
msgstr "Create Folder"
msgid "File:"
msgstr "File:"
msgid "Interpolation:"
msgstr "Interpolation:"
msgid "Nearest"
msgstr "Nearest"
msgid "Bilinear"
msgstr "Bilinear"
msgid "Cubic"
msgstr "Cubic"
msgid "Trilinear"
msgstr "Trilinear"
msgid "Language"
msgstr "Language"
msgid "Themes"
msgstr "Themes"
msgid "Guides & Grid"
msgstr "Guides & Grid"
msgid "Language options"
msgstr "Language options"
msgid "Theme options"
msgstr "Theme options"
msgid "Grid options"
msgstr "Grid options"
msgid "Color:"
msgstr "Color:"
msgid "Guide color:"
msgstr "Guide color:"
msgid "System Language"
msgstr "System Language"
msgid "Dark"
msgstr "Dark"
msgid "Gray"
msgstr "Gray"
msgid "Gold"
msgstr "Gold"
msgid "Light"
msgstr "Light"
msgid "Invert colors"
msgstr "Invert colors"
msgid "Desaturation"
msgstr "Desaturation"
msgid "Outline"
msgstr "Outline"
msgid "Diagonal"
msgstr "Diagonal"
msgid "Place inside image"
msgstr "Place inside image"
msgid "Thickness:"
msgstr "Thickness:"
msgid "View Splash Screen"
msgstr "View Splash Screen"
msgid "Issue Tracker"
msgstr "Issue Tracker"
msgid "Changelog"
msgstr "Changelog"
msgid "About Pixelorama"
msgstr "About Pixelorama"
msgid "MADEBY_LABEL"
msgstr "Developed by Orama Interactive"
msgid "Website"
msgstr "Website"
msgid "Donate"
msgstr "Donate"
msgid "Developers"
msgstr "Developers"
msgid "Contributors"
msgstr "Contributors"
msgid "Donors"
msgstr "Donors"
msgid "Development Team"
msgstr "Development Team"
msgid "Lead Programmer"
msgstr "Lead Programmer"
msgid "UI Designer"
msgstr "UI Designer"
msgid "GitHub Contributors"
msgstr "GitHub Contributors"
msgid "Art by"
msgstr "Art by"
msgid "untitled"
msgstr "untitled"
msgid "imported"
msgstr "imported"
msgid "copy"
msgstr "copy"
msgid "QUIT_LABEL"
msgstr "Are you sure you want to exit Pixelorama?"
msgid "Utility Tools"
msgstr "Utility Tools"
msgid "RECTSELECT_HT"
msgstr ""
"Rectangular Selection\n"
"\n"
"R for left mouse button\n"
"Alt + R for right mouse button\n"
"\n"
"Press Shift to move the content"
msgid "COLORPICKER_HT"
msgstr ""
"Color Picker\n"
"Select a color from a pixel of the sprite\n"
"\n"
"O for left mouse button\n"
"Alt + O for right mouse button"
msgid "Draw Tools"
msgstr "Draw Tools"
msgid "PENCIL_HT"
msgstr ""
"Pencil\n"
"\n"
"P for left mouse button\n"
"Alt + P for right mouse button\n"
"\n"
"Hold Shift to make a line"
msgid "ERASER_HT"
msgstr ""
"Eraser\n"
"\n"
"E for left mouse button\n"
"Alt + E for right mouse button\n"
"\n"
"Hold Shift to make a line"
msgid "BUCKET_HT"
msgstr ""
"Bucket\n"
"\n"
"B for left mouse button\n"
"Alt + B for right mouse button"
msgid "LD_HT"
msgstr ""
"Lighten/Darken\n"
"\n"
"U for left mouse button\n"
"Alt + U for right mouse button"
msgid "LEFTCOLOR_HT"
msgstr "Choose a color for the left tool"
msgid "RIGHTCOLOR_HT"
msgstr "Choose a color for the right tool"
msgid "COLORSWITCH_HT"
msgstr ""
"Switch left and right colors\n"
"(X)"
msgid "COLORDEFAULTS_HT"
msgstr ""
"Reset the colors to their default state (black for left, white for right)"
msgid "Raw Mode"
msgstr "Raw Mode"
msgid "Left tool options"
msgstr "Left tool options"
msgid "Right tool options"
msgstr "Right tool options"
msgid "Left pixel indicator"
msgstr "Left pixel indicator"
msgid "Show tool icon"
msgstr "Show tool icon"
msgid "LEFT_INDIC_HT"
msgstr "Show left mouse pixel indicator or brush on the canvas when drawing"
msgid "RIGHT_INDIC_HT"
msgstr "Show right mouse pixel indicator or brush on the canvas when drawing"
msgid "Right pixel indicator"
msgstr "Right pixel indicator"
msgid "Brush:"
msgstr "Brush:"
msgid "BRUSH_HT"
msgstr "Select a brush"
msgid "Brush: Pixel"
msgstr "Brush: Pixel"
msgid "Brush: Circle"
msgstr "Brush: Circle"
msgid "Brush: Filled Circle"
msgstr "Brush: Filled Circle"
msgid "Custom brush"
msgstr "Custom brush"
msgid "Brush size:"
msgstr "Brush size:"
msgid "Brush color from"
msgstr "Brush color from"
msgid "COLORFROM_HT"
msgstr "0: Color from the brush itself, 100: the currently selected color"
msgid "Fill area:"
msgstr "Fill area:"
msgid "Area of the same color"
msgstr "Area of the same color"
msgid "All pixels of the same color"
msgstr "All pixels of the same color"
msgid "Lighten"
msgstr "Lighten"
msgid "Darken"
msgstr "Darken"
msgid "Amount:"
msgstr "Amount:"
msgid "LDAMOUNT_HT"
msgstr "Lighten/Darken amount"
msgid "Pick for:"
msgstr "Pick for:"
msgid "Left Color"
msgstr "Left Color"
msgid "Right Color"
msgstr "Right Color"
msgid "Mirroring"
msgstr "Mirroring"
msgid "Horizontal"
msgstr "Horizontal"
msgid "HORIZMIRROR_HT"
msgstr "Enable horizontal mirrored drawing"
msgid "VERTMIRROR_HT"
msgstr "Enable vertical mirrored drawing"
msgid "Vertical"
msgstr "Vertical"
msgid "Current frame:"
msgstr "Current frame:"
msgid "Current frame: 1/1"
msgstr "Current frame: 1/1"
msgid "FIRSTFRAME_HT"
msgstr ""
"Jump to the first frame\n"
"(Ctrl+Home)"
msgid "PREVIOUSFRAME_HT"
msgstr ""
"Go to the previous frame\n"
"(Ctrl+Left)"
msgid "PLAYBACKWARDS_HT"
msgstr ""
"Play the animation backwards (from end to beginning)\n"
"(F4)"
msgid "PLAYFORWARD_HT"
msgstr ""
"Play the animation forward (from beginning to end)\n"
"(F5)"
msgid "NEXTFRAME_HT"
msgstr ""
"Go to the next frame\n"
"(Ctrl+Right)"
msgid "LASTFRAME_HT"
msgstr ""
"Jump to the last frame\n"
"(Ctrl+End)"
msgid "FPS_HT"
msgstr ""
"How many frames per second should the animation preview be?\n"
"The more FPS, the faster the animation plays."
msgid "No loop"
msgstr "No loop"
msgid "Cycle loop"
msgstr "Cycle loop"
msgid "Ping-pong loop"
msgstr "Ping-pong loop"
msgid "Onion Skinning:"
msgstr "Onion Skinning:"
msgid "Past Frames"
msgstr "Past Frames"
msgid "Future Frames"
msgstr "Future Frames"
msgid "Blue-Red Mode"
msgstr "Blue-Red Mode"
msgid "Add a new frame"
msgstr "Add a new frame"
msgid "Remove Frame"
msgstr "Remove Frame"
msgid "Clone Frame"
msgstr "Clone Frame"
msgid "Move Left"
msgstr "Move Left"
msgid "Move Right"
msgstr "Move Right"
msgid "Layer"
msgstr "Layer"
msgid "Layers"
msgstr "Layers"
msgid "LAYERNEW_HT"
msgstr "Create a new layer"
msgid "LAYERREMOVE_HT"
msgstr "Remove current layer"
msgid "LAYERUP_HT"
msgstr "Move up the current layer"
msgid "LAYERDOWN_HT"
msgstr "Move down the current layer"
msgid "LAYERCLONE_HT"
msgstr "Clone current layer"
msgid "LAYERMERGE_HT"
msgstr "Merge current layer with the one below"
msgid "Opacity:"
msgstr "Opacity:"
msgid "LAYERVISIBILITY_HT"
msgstr "Toggle layer's visibility"
msgid "Palette"
msgstr "Palette"
msgid "Palettes"
msgstr "Palettes"
msgid "NEWPALETTE_HT"
msgstr "Add a new palette"
msgid "EDITPALETTE_HT"
msgstr "Edit currently selected palette"
msgid "CHOOSEPALETTE_HT"
msgstr "Choose a palette"
msgid "Undo: Draw"
msgstr "Undo: Draw"
msgid "Redo: Draw"
msgstr "Redo: Draw"
msgid "Undo: Rectangle Select"
msgstr "Undo: Rectangle Select"
msgid "Redo: Rectangle Select"
msgstr "Redo: Rectangle Select"
msgid "Undo: Scale"
msgstr "Undo: Scale"
msgid "Redo: Scale"
msgstr "Redo: Scale"
msgid "Undo: Add Layer"
msgstr "Undo: Add Layer"
msgid "Redo: Add Layer"
msgstr "Redo: Add Layer"
msgid "Undo: Remove Layer"
msgstr "Undo: Remove Layer"
msgid "Redo: Remove Layer"
msgstr "Redo: Remove Layer"
msgid "Undo: Merge Layer"
msgstr "Undo: Merge Layer"
msgid "Redo: Merge Layer"
msgstr "Redo: Merge Layer"
msgid "Undo: Change Layer Order"
msgstr "Undo: Change Layer Order"
msgid "Redo: Change Layer Order"
msgstr "Redo: Change Layer Order"
msgid "Undo: Add Frame"
msgstr "Undo: Add Frame"
msgid "Redo: Add Frame"
msgstr "Redo: Add Frame"
msgid "Undo: Remove Frame"
msgstr "Undo: Remove Frame"
msgid "Redo: Remove Frame"
msgstr "Redo: Remove Frame"
msgid "Undo: Change Frame Order"
msgstr "Undo: Change Frame Order"
msgid "Redo: Change Frame Order"
msgstr "Redo: Change Frame Order"
msgid "Undo: Delete Custom Brush"
msgstr "Undo: Delete Custom Brush"
msgid "Redo: Delete Custom Brush"
msgstr "Redo: Delete Custom Brush"
msgid "Move Guide"
msgstr "Move Guide"
msgid "File saved"
msgstr "File saved"
msgid "File exported"
msgstr "File exported"
msgid "New Empty Palette"
msgstr "New Empty Palette"
msgid "Import Palette"
msgstr "Import Palette"
msgid "Palette Name:"
msgstr "Palette Name:"
msgid "Color Name:"
msgstr "Color Name:"
msgid "Create a new empty palette?"
msgstr "Create a new empty palette?"
msgid "Error: Palette must have a valid name."
msgstr "Error: Palette must have a valid name."
msgid "Error: Palette named '%s' already exists!"
msgstr "Error: Palette named '%s' already exists!"
msgid "Invalid Palette file!"
msgstr "Invalid Palette file!"
msgid "Edit Palette"
msgstr "Edit Palette"
msgid "Patrons:"
msgstr "Patrons:"
msgid "Changes"
msgstr "Changes"
msgid "Platinum Sponsor"
msgstr "Platinum Sponsor"
msgid "Gold Sponsors"
msgstr "Gold Sponsors"
msgid "Platinum Sponsor Placeholder"
msgstr "Platinum Sponsor Placeholder"
msgid "Gold Sponsors Placeholder"
msgstr "Gold Sponsors Placeholder"
msgid "Don't show again"
msgstr "Don't show again"
msgid "Take this spot!"
msgstr "Take this spot!"
#~ msgid "Don't show on the next startup"
#~ msgstr "Don't show on the next startup"
#~ msgid "Language:"
#~ msgstr "Language:"
#~ msgid "SPLITSCREEN_HT"
#~ msgstr ""
#~ "Split screen\n"
#~ "\n"
#~ "Show second canvas"
#~ msgid "SPLITSCREEN_HIDE_HT"
#~ msgstr ""
#~ "Split screen\n"
#~ "\n"
#~ "Hide second canvas"
msgid "Image Options"
msgstr "Image Options"
msgid "Default Width:"
msgstr "Default Width:"
msgid "Default Height:"
msgstr "Default Height:"
msgid "Default Fill Color:"
msgstr "Default Fill Color:"
msgid "Lock aspect ratio:"
msgstr "Lock aspect ratio:"
msgid "Templates:"
msgstr "Templates:"

1101
Translations/en_US.po Normal file

File diff suppressed because it is too large Load Diff

1443
Translations/eo_UY.po Normal file

File diff suppressed because it is too large Load Diff

1472
Translations/es_ES.po Normal file

File diff suppressed because it is too large Load Diff

1442
Translations/fi_FI.po Normal file

File diff suppressed because it is too large Load Diff

1472
Translations/fr_FR.po Normal file

File diff suppressed because it is too large Load Diff

1442
Translations/he_IL.po Normal file

File diff suppressed because it is too large Load Diff

1472
Translations/hu_HU.po Normal file

File diff suppressed because it is too large Load Diff

1470
Translations/id_ID.po Normal file

File diff suppressed because it is too large Load Diff

1472
Translations/it_IT.po Normal file

File diff suppressed because it is too large Load Diff

1442
Translations/ja_JP.po Normal file

File diff suppressed because it is too large Load Diff

1472
Translations/ko_KR.po Normal file

File diff suppressed because it is too large Load Diff

1467
Translations/lv_LV.po Normal file

File diff suppressed because it is too large Load Diff

1442
Translations/nl_NL.po Normal file

File diff suppressed because it is too large Load Diff

1469
Translations/no_NO.po Normal file

File diff suppressed because it is too large Load Diff

1471
Translations/pl_PL.po Normal file

File diff suppressed because it is too large Load Diff

1472
Translations/pt_BR.po Normal file

File diff suppressed because it is too large Load Diff

1442
Translations/pt_PT.po Normal file

File diff suppressed because it is too large Load Diff

1472
Translations/ro_RO.po Normal file

File diff suppressed because it is too large Load Diff

1470
Translations/ru_RU.po Normal file

File diff suppressed because it is too large Load Diff

1442
Translations/sr_SP.po Normal file

File diff suppressed because it is too large Load Diff

1442
Translations/sv_SE.po Normal file

File diff suppressed because it is too large Load Diff

1451
Translations/tr_TR.po Normal file

File diff suppressed because it is too large Load Diff

1442
Translations/uk_UA.po Normal file

File diff suppressed because it is too large Load Diff

1442
Translations/vi_VN.po Normal file

File diff suppressed because it is too large Load Diff

1471
Translations/zh_CN.po Normal file

File diff suppressed because it is too large Load Diff

1470
Translations/zh_TW.po Normal file

File diff suppressed because it is too large Load Diff

10
addons/README.md Normal file
View File

@ -0,0 +1,10 @@
# Addons
## gdgifexporter
- Upstream: https://github.com/jegor377/godot-gdgifexporter
- Version: git (201123154acfb9a1e00149fa708b4f13645d88dc, 2020)
- License: MIT
Files extracted from source:
- `gdgifexporter/quantization/enhanced_uniform_quantization.gd`

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Igor Santarek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,58 @@
extends Reference
var _shader: Shader
func get_indexed_datas(image: Image, colors: Array) -> PoolByteArray:
_shader = preload("./lookup_color.shader")
return _convert(image, colors)
func get_similar_indexed_datas(image: Image, colors: Array) -> PoolByteArray:
_shader = preload("./lookup_similar.shader")
return _convert(image, colors)
func _convert(image: Image, colors: Array) -> PoolByteArray:
var vp = VisualServer.viewport_create()
var canvas = VisualServer.canvas_create()
VisualServer.viewport_attach_canvas(vp, canvas)
VisualServer.viewport_set_size(vp, image.get_width(), image.get_height())
VisualServer.viewport_set_disable_3d(vp, true)
VisualServer.viewport_set_usage(vp, VisualServer.VIEWPORT_USAGE_2D)
VisualServer.viewport_set_hdr(vp, true)
VisualServer.viewport_set_active(vp, true)
var ci_rid = VisualServer.canvas_item_create()
VisualServer.viewport_set_canvas_transform(vp, canvas, Transform())
VisualServer.canvas_item_set_parent(ci_rid, canvas)
var texture = ImageTexture.new()
texture.create_from_image(image)
VisualServer.canvas_item_add_texture_rect(ci_rid, Rect2(Vector2(0, 0), image.get_size()), texture)
var mat_rid = VisualServer.material_create()
VisualServer.material_set_shader(mat_rid, _shader.get_rid())
var lut = Image.new()
lut.create(256, 1, false, Image.FORMAT_RGB8)
lut.fill(Color8(colors[0][0], colors[0][1], colors[0][2]))
lut.lock()
for i in colors.size():
lut.set_pixel(i, 0, Color8(colors[i][0], colors[i][1], colors[i][2]))
var lut_tex = ImageTexture.new()
lut_tex.create_from_image(lut)
VisualServer.material_set_param(mat_rid, "lut", lut_tex)
VisualServer.canvas_item_set_material(ci_rid, mat_rid)
VisualServer.viewport_set_update_mode(vp, VisualServer.VIEWPORT_UPDATE_ONCE)
VisualServer.viewport_set_vflip(vp, true)
VisualServer.force_draw(false)
image = VisualServer.texture_get_data(VisualServer.viewport_get_texture(vp))
VisualServer.free_rid(vp)
VisualServer.free_rid(canvas)
VisualServer.free_rid(ci_rid)
VisualServer.free_rid(mat_rid)
image.convert(Image.FORMAT_R8)
return image.get_data()

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Igor Santarek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,31 @@
extends Reference
class LSB_LZWBitPacker:
var bit_index: int = 0
var stream: int = 0
var chunks: PoolByteArray = PoolByteArray([])
func put_byte():
chunks.append(stream & 0xff)
bit_index -= 8
stream >>= 8
func write_bits(value: int, bits_count: int) -> void:
value &= (1 << bits_count) - 1
value <<= bit_index
stream |= value
bit_index += bits_count
while bit_index >= 8:
self.put_byte()
func pack() -> PoolByteArray:
if bit_index != 0:
self.put_byte()
return chunks
func reset() -> void:
bit_index = 0
stream = 0
chunks = PoolByteArray([])

View File

@ -0,0 +1,41 @@
extends Reference
class LSB_LZWBitUnpacker:
var chunk_stream: PoolByteArray
var bit_index: int = 0
var byte: int
var byte_index: int = 0
func _init(_chunk_stream: PoolByteArray):
chunk_stream = _chunk_stream
self.get_byte()
func get_bit(value: int, index: int) -> int:
return (value >> index) & 1
func set_bit(value: int, index: int) -> int:
return value | (1 << index)
func get_byte():
byte = chunk_stream[byte_index]
byte_index += 1
bit_index = 0
func read_bits(bits_count: int) -> int:
var result: int = 0
var result_bit_index: int = 0
for _i in range(bits_count):
if self.get_bit(byte, bit_index) == 1:
result = self.set_bit(result, result_bit_index)
result_bit_index += 1
bit_index += 1
if bit_index == 8:
self.get_byte()
return result
func remove_bits(bits_count: int) -> void:
self.read_bits(bits_count)

View File

@ -0,0 +1,202 @@
extends Reference
var lsbbitpacker = preload('./lsbbitpacker.gd')
var lsbbitunpacker = preload('./lsbbitunpacker.gd')
class CodeEntry:
var sequence: PoolByteArray
var raw_array: Array
func _init(_sequence):
raw_array = _sequence
sequence = _sequence
func add(other):
return CodeEntry.new(self.raw_array + other.raw_array)
func to_string():
var result: String = ''
for element in self.sequence:
result += str(element) + ', '
return result.substr(0, result.length() - 2)
class CodeTable:
var entries: Dictionary = {}
var counter: int = 0
var lookup: Dictionary = {}
func add(entry) -> int:
self.entries[self.counter] = entry
self.lookup[entry.raw_array] = self.counter
counter += 1
return counter
func find(entry) -> int:
return self.lookup.get(entry.raw_array, -1)
func has(entry) -> bool:
return self.find(entry) != -1
func get(index) -> CodeEntry:
return self.entries.get(index, null)
func to_string() -> String:
var result: String = 'CodeTable:\n'
for id in self.entries:
result += str(id) + ': ' + self.entries[id].to_string() + '\n'
result += 'Counter: ' + str(self.counter) + '\n'
return result
func log2(value: float) -> float:
return log(value) / log(2.0)
func get_bits_number_for(value: int) -> int:
if value == 0:
return 1
return int(ceil(log2(value + 1)))
func initialize_color_code_table(colors: PoolByteArray) -> CodeTable:
var result_code_table: CodeTable = CodeTable.new()
for color_id in colors:
# warning-ignore:return_value_discarded
result_code_table.add(CodeEntry.new([color_id]))
# move counter to the first available compression code index
var last_color_index: int = colors.size() - 1
var clear_code_index: int = pow(2, get_bits_number_for(last_color_index))
result_code_table.counter = clear_code_index + 2
return result_code_table
# compression and decompression done with source:
# http://www.matthewflickinger.com/lab/whatsinagif/lzw_image_data.asp
func compress_lzw(image: PoolByteArray, colors: PoolByteArray) -> Array:
# Initialize code table
var code_table: CodeTable = initialize_color_code_table(colors)
# Clear Code index is 2**<code size>
# <code size> is the amount of bits needed to write down all colors
# from color table. We use last color index because we can write
# all colors (for example 16 colors) with indexes from 0 to 15.
# Number 15 is in binary 0b1111, so we'll need 4 bits to write all
# colors down.
var last_color_index: int = colors.size() - 1
var clear_code_index: int = pow(2, get_bits_number_for(last_color_index))
var index_stream: PoolByteArray = image
var current_code_size: int = get_bits_number_for(clear_code_index)
var binary_code_stream = lsbbitpacker.LSB_LZWBitPacker.new()
# initialize with Clear Code
binary_code_stream.write_bits(clear_code_index, current_code_size)
# Read first index from index stream.
var index_buffer: CodeEntry = CodeEntry.new([index_stream[0]])
var data_index: int = 1
# <LOOP POINT>
while data_index < index_stream.size():
# Get the next index from the index stream.
var K: CodeEntry = CodeEntry.new([index_stream[data_index]])
data_index += 1
# Is index buffer + K in our code table?
var new_index_buffer: CodeEntry = index_buffer.add(K)
if code_table.has(new_index_buffer): # if YES
# Add K to the end of the index buffer
index_buffer = new_index_buffer
else: # if NO
# Add a row for index buffer + K into our code table
binary_code_stream.write_bits(code_table.find(index_buffer), current_code_size)
# We don't want to add new code to code table if we've exceeded 4095
# index.
var last_entry_index: int = code_table.counter - 1
if last_entry_index != 4095:
# Output the code for just the index buffer to our code stream
# warning-ignore:return_value_discarded
code_table.add(new_index_buffer)
else:
# if we exceeded 4095 index (code table is full), we should
# output Clear Code and reset everything.
binary_code_stream.write_bits(clear_code_index, current_code_size)
code_table = initialize_color_code_table(colors)
# get_bits_number_for(clear_code_index) is the same as
# LZW code size + 1
current_code_size = get_bits_number_for(clear_code_index)
# Detect when you have to save new codes in bigger bits boxes
# change current code size when it happens because we want to save
# flexible code sized codes
var new_code_size_candidate: int = get_bits_number_for(code_table.counter - 1)
if new_code_size_candidate > current_code_size:
current_code_size = new_code_size_candidate
# Index buffer is set to K
index_buffer = K
# Output code for contents of index buffer
binary_code_stream.write_bits(code_table.find(index_buffer), current_code_size)
# output end with End Of Information Code
binary_code_stream.write_bits(clear_code_index + 1, current_code_size)
var min_code_size: int = get_bits_number_for(clear_code_index) - 1
return [binary_code_stream.pack(), min_code_size]
func decompress_lzw(code_stream_data: PoolByteArray, min_code_size: int, colors: PoolByteArray) -> PoolByteArray:
var code_table: CodeTable = initialize_color_code_table(colors)
var index_stream: PoolByteArray = PoolByteArray([])
var binary_code_stream = lsbbitunpacker.LSB_LZWBitUnpacker.new(code_stream_data)
var current_code_size: int = min_code_size + 1
var clear_code_index: int = pow(2, min_code_size)
# CODE is an index of code table, {CODE} is sequence inside
# code table with index CODE. The same goes for PREVCODE.
# Remove first Clear Code from stream. We don't need it.
binary_code_stream.remove_bits(current_code_size)
# let CODE be the first code in the code stream
var code: int = binary_code_stream.read_bits(current_code_size)
# output {CODE} to index stream
index_stream.append_array(code_table.get(code).sequence)
# set PREVCODE = CODE
var prevcode: int = code
# <LOOP POINT>
while true:
# let CODE be the next code in the code stream
code = binary_code_stream.read_bits(current_code_size)
# Detect Clear Code. When detected reset everything and get next code.
if code == clear_code_index:
code_table = initialize_color_code_table(colors)
current_code_size = min_code_size + 1
code = binary_code_stream.read_bits(current_code_size)
elif code == clear_code_index + 1: # Stop when detected EOI Code.
break
# is CODE in the code table?
var code_entry: CodeEntry = code_table.get(code)
if code_entry != null: # if YES
# output {CODE} to index stream
index_stream.append_array(code_entry.sequence)
# let K be the first index in {CODE}
var K: CodeEntry = CodeEntry.new([code_entry.sequence[0]])
# warning-ignore:return_value_discarded
# add {PREVCODE} + K to the code table
code_table.add(code_table.get(prevcode).add(K))
# set PREVCODE = CODE
prevcode = code
else: # if NO
# let K be the first index of {PREVCODE}
var prevcode_entry: CodeEntry = code_table.get(prevcode)
var K: CodeEntry = CodeEntry.new([prevcode_entry.sequence[0]])
# output {PREVCODE} + K to index stream
index_stream.append_array(prevcode_entry.add(K).sequence)
# add {PREVCODE} + K to code table
# warning-ignore:return_value_discarded
code_table.add(prevcode_entry.add(K))
# set PREVCODE = CODE
prevcode = code
# Detect when we should increase current code size and increase it.
var new_code_size_candidate: int = get_bits_number_for(code_table.counter)
if new_code_size_candidate > current_code_size:
current_code_size = new_code_size_candidate
return index_stream

View File

@ -0,0 +1,392 @@
extends Reference
var little_endian = preload('./little_endian.gd').new()
var lzw = preload('./gif-lzw/lzw.gd').new()
var used_proc_count: int = 4
class GraphicControlExtension:
var extension_introducer: int = 0x21
var graphic_control_label: int = 0xf9
var block_size: int = 4
var packed_fields: int = 0b00001000
var delay_time: int = 0
var transparent_color_index: int = 0
func _init(_delay_time: int,
use_transparency: bool = false,
_transparent_color_index: int = 0):
delay_time = _delay_time
transparent_color_index = _transparent_color_index
if use_transparency:
packed_fields = 0b00001001
func to_bytes() -> PoolByteArray:
var little_endian = preload('./little_endian.gd').new()
var result: PoolByteArray = PoolByteArray([])
result.append(extension_introducer)
result.append(graphic_control_label)
result.append(block_size)
result.append(packed_fields)
result += little_endian.int_to_2bytes(delay_time)
result.append(transparent_color_index)
result.append(0)
return result
class ImageDescriptor:
var image_separator: int = 0x2c
var image_left_position: int = 0
var image_top_position: int = 0
var image_width: int
var image_height: int
var packed_fields: int = 0b10000000
func _init(_image_left_position: int,
_image_top_position: int,
_image_width: int,
_image_height: int,
size_of_local_color_table: int):
image_left_position = _image_left_position
image_top_position = _image_top_position
image_width = _image_width
image_height = _image_height
packed_fields = packed_fields | (0b111 & size_of_local_color_table)
func to_bytes() -> PoolByteArray:
var little_endian = preload('./little_endian.gd').new()
var result: PoolByteArray = PoolByteArray([])
result.append(image_separator)
result += little_endian.int_to_2bytes(image_left_position)
result += little_endian.int_to_2bytes(image_top_position)
result += little_endian.int_to_2bytes(image_width)
result += little_endian.int_to_2bytes(image_height)
result.append(packed_fields)
return result
class LocalColorTable:
var colors: Array = []
func log2(value: float) -> float:
return log(value) / log(2.0)
func get_size() -> int:
if colors.size() <= 1:
return 0
return int(ceil(log2(colors.size()) - 1))
func to_bytes() -> PoolByteArray:
var result: PoolByteArray = PoolByteArray([])
for v in colors:
result.append(v[0])
result.append(v[1])
result.append(v[2])
if colors.size() != int(pow(2, get_size() + 1)):
for i in range(int(pow(2, get_size() + 1)) - colors.size()):
result += PoolByteArray([0, 0, 0])
return result
class ApplicationExtension:
var extension_introducer: int = 0x21
var extension_label: int = 0xff
var block_size: int = 11
var application_identifier: PoolByteArray
var appl_authentication_code: PoolByteArray
var application_data: PoolByteArray
func _init(_application_identifier: String,
_appl_authentication_code: String):
application_identifier = _application_identifier.to_ascii()
appl_authentication_code = _appl_authentication_code.to_ascii()
func to_bytes() -> PoolByteArray:
var result: PoolByteArray = PoolByteArray([])
result.append(extension_introducer)
result.append(extension_label)
result.append(block_size)
result += application_identifier
result += appl_authentication_code
result.append(application_data.size())
result += application_data
result.append(0)
return result
class ImageData:
var lzw_minimum_code_size: int
var image_data: PoolByteArray
func to_bytes() -> PoolByteArray:
var result: PoolByteArray = PoolByteArray([])
result.append(lzw_minimum_code_size)
var block_size_index: int = 0
var i: int = 0
var data_index: int = 0
while data_index < image_data.size():
if i == 0:
result.append(0)
block_size_index = result.size() - 1
result.append(image_data[data_index])
result[block_size_index] += 1
data_index += 1
i += 1
if i == 254:
i = 0
if not image_data.empty():
result.append(0)
return result
class ConvertedImage:
var image_converted_to_codes: PoolByteArray
var color_table: Array
var transparency_color_index: int
var width: int
var height: int
class ConvertionResult:
var converted_image: ConvertedImage = ConvertedImage.new()
var error: int = Error.OK
func with_error_code(_error: int) -> ConvertionResult:
error = _error
return self
class ThreadWriteFrameResult:
var frame_data: PoolByteArray = PoolByteArray([])
var error: int = Error.OK
func with_error_code(_error: int) -> ThreadWriteFrameResult:
error = _error
return self
enum Error {
OK = 0,
EMPTY_IMAGE = 1,
BAD_IMAGE_FORMAT = 2
}
# File data and Header
var data: PoolByteArray = 'GIF'.to_ascii() + '89a'.to_ascii()
func _init(_width: int, _height: int):
# Logical Screen Descriptor
var width: int = _width
var height: int = _height
# not Global Color Table Flag
# Color Resolution = 8 bits
# Sort Flag = 0, not sorted.
# Size of Global Color Table set to 0
# because we'll use only Local Tables
var packed_fields: int = 0b01110000
var background_color_index: int = 0
var pixel_aspect_ratio: int = 0
data += little_endian.int_to_2bytes(width)
data += little_endian.int_to_2bytes(height)
data.append(packed_fields)
data.append(background_color_index)
data.append(pixel_aspect_ratio)
var application_extension: ApplicationExtension = ApplicationExtension.new(
"NETSCAPE",
"2.0")
application_extension.application_data = PoolByteArray([1, 0, 0])
data += application_extension.to_bytes()
func calc_delay_time(frame_delay: float) -> int:
return int(ceil(frame_delay / 0.01))
func color_table_to_indexes(colors: Array) -> PoolByteArray:
var result: PoolByteArray = PoolByteArray([])
for i in range(colors.size()):
result.append(i)
return result
func find_color_table_if_has_less_than_256_colors(image: Image) -> Dictionary:
image.lock()
var result: Dictionary = {}
var image_data: PoolByteArray = image.get_data()
for i in range(0, image_data.size(), 4):
var color: Array = [int(image_data[i]), int(image_data[i + 1]), int(image_data[i + 2]), int(image_data[i + 3])]
if not color in result:
result[color] = result.size()
if result.size() > 256:
break
image.unlock()
return result
func change_colors_to_codes(image: Image,
color_palette: Dictionary,
transparency_color_index: int) -> PoolByteArray:
image.lock()
var image_data: PoolByteArray = image.get_data()
var result: PoolByteArray = PoolByteArray([])
for i in range(0, image_data.size(), 4):
var color: Array = [int(image_data[i]), int(image_data[i + 1]), int(image_data[i + 2]), int(image_data[i + 3])]
if color in color_palette:
if color[3] == 0 and transparency_color_index != -1:
result.append(transparency_color_index)
else:
result.append(color_palette[color])
else:
result.append(0)
push_warning('change_colors_to_codes: color not found! [%d, %d, %d, %d]' % color)
image.unlock()
return result
func sum_color(color: Array) -> int:
return color[0] + color[1] + color[2] + color[3]
func find_transparency_color_index(color_table: Dictionary) -> int:
for color in color_table:
if sum_color(color) == 0:
return color_table[color]
return -1
func find_transparency_color_index_for_quantized_image(color_table: Array) -> int:
for i in range(color_table.size()):
if sum_color(color_table[i]) == 0:
return i
return -1
func make_sure_color_table_is_at_least_size_4(color_table: Array) -> Array:
var result := [] + color_table
if color_table.size() < 4:
for i in range(4 - color_table.size()):
result.append([0, 0, 0, 0])
return result
func convert_image(image: Image, quantizator) -> ConvertionResult:
var result := ConvertionResult.new()
# check if image is of good format
if image.get_format() != Image.FORMAT_RGBA8:
return result.with_error_code(Error.BAD_IMAGE_FORMAT)
# check if image isn't empty
if image.is_empty():
return result.with_error_code(Error.EMPTY_IMAGE)
var found_color_table: Dictionary = find_color_table_if_has_less_than_256_colors(
image)
var image_converted_to_codes: PoolByteArray
var transparency_color_index: int = -1
var color_table: Array
if found_color_table.size() <= 256: # we don't need to quantize the image.
# exporter images always try to include transparency because I'm lazy.
transparency_color_index = find_transparency_color_index(found_color_table)
if transparency_color_index == -1 and found_color_table.size() <= 255:
found_color_table[[0, 0, 0, 0]] = found_color_table.size()
transparency_color_index = found_color_table.size() - 1
image_converted_to_codes = change_colors_to_codes(
image, found_color_table, transparency_color_index)
color_table = make_sure_color_table_is_at_least_size_4(found_color_table.keys())
else: # we have to quantize the image.
var quantization_result: Array = quantizator.quantize_and_convert_to_codes(image)
image_converted_to_codes = quantization_result[0]
color_table = quantization_result[1]
# don't find transparency index if the quantization algorithm
# provides it as third return value
if quantization_result.size() == 3:
transparency_color_index = 0 if quantization_result[2] else -1
else:
transparency_color_index = find_transparency_color_index_for_quantized_image(quantization_result[1])
result.converted_image.image_converted_to_codes = image_converted_to_codes
result.converted_image.color_table = color_table
result.converted_image.transparency_color_index = transparency_color_index
result.converted_image.width = image.get_width()
result.converted_image.height = image.get_height()
return result.with_error_code(Error.OK)
func write_frame(image: Image, frame_delay: float, quantizator) -> int:
var converted_image_result := convert_image(image, quantizator)
if converted_image_result.error != Error.OK:
return converted_image_result.error
var converted_image := converted_image_result.converted_image
return write_frame_from_conv_image(converted_image, frame_delay)
func write_frame_from_conv_image(converted_image: ConvertedImage,
frame_delay: float) -> int:
var delay_time := calc_delay_time(frame_delay)
var color_table_indexes = color_table_to_indexes(converted_image.color_table)
var compressed_image_result: Array = lzw.compress_lzw(
converted_image.image_converted_to_codes, color_table_indexes)
var compressed_image_data: PoolByteArray = compressed_image_result[0]
var lzw_min_code_size: int = compressed_image_result[1]
var table_image_data_block: ImageData = ImageData.new()
table_image_data_block.lzw_minimum_code_size = lzw_min_code_size
table_image_data_block.image_data = compressed_image_data
var local_color_table: LocalColorTable = LocalColorTable.new()
local_color_table.colors = converted_image.color_table
var image_descriptor: ImageDescriptor = ImageDescriptor.new(0, 0,
converted_image.width,
converted_image.height,
local_color_table.get_size())
var graphic_control_extension: GraphicControlExtension
if converted_image.transparency_color_index != -1:
graphic_control_extension = GraphicControlExtension.new(
delay_time, true, converted_image.transparency_color_index)
else:
graphic_control_extension = GraphicControlExtension.new(
delay_time, false, 0)
data += graphic_control_extension.to_bytes()
data += image_descriptor.to_bytes()
data += local_color_table.to_bytes()
data += table_image_data_block.to_bytes()
return Error.OK
func scale_conv_image(converted_image: ConvertedImage, scale_factor: int) -> ConvertedImage:
var result = ConvertedImage.new()
result.image_converted_to_codes = PoolByteArray([])
result.color_table = converted_image.color_table.duplicate()
result.transparency_color_index = converted_image.transparency_color_index
result.width = converted_image.width * scale_factor
result.height = converted_image.height * scale_factor
for y in range(converted_image.height):
var row := PoolByteArray([])
for x in range(converted_image.width):
for i in range(scale_factor):
row.append(converted_image.image_converted_to_codes[(y * converted_image.width) + x])
for i in range(scale_factor):
result.image_converted_to_codes += row
row = PoolByteArray([])
return result
func export_file_data() -> PoolByteArray:
return data + PoolByteArray([0x3b])

View File

@ -0,0 +1,5 @@
extends Reference
func int_to_2bytes(value: int) -> PoolByteArray:
return PoolByteArray([value & 255, (value >> 8) & 255])

View File

@ -0,0 +1,19 @@
shader_type canvas_item;
render_mode unshaded;
uniform sampler2D lut;
void fragment() {
vec4 color = texture(TEXTURE, UV);
float index = 0.0;
if (color.a > 0.0) {
for (int i = 0; i < 256; i++) {
vec4 c = texture(lut, vec2((float(i) + 0.5) / 256.0, 0.5));
if (c.rgb == color.rgb) {
index = float(i) / 255.0;
break;
}
}
}
COLOR = vec4(vec3(index), 1.0);
}

View File

@ -0,0 +1,22 @@
shader_type canvas_item;
render_mode unshaded;
uniform sampler2D lut;
void fragment() {
vec4 color = texture(TEXTURE, UV);
vec4 similar = texture(lut, vec2(0.5 / 256.0, 0.5));
float index = 0.0;
if (color.a > 0.0) {
float dist = distance(color.xyz, similar.xyz);
for (int i = 1; i < 256; i++) {
vec4 c = texture(lut, vec2((float(i) + 0.5) / 256.0, 0.5));
float d = distance(color.xyz, c.xyz);
if (d < dist) {
dist = d;
index = float(i) / 255.0;
}
}
}
COLOR = vec4(vec3(index), 1.0);
}

View File

@ -0,0 +1,148 @@
extends Reference
var converter = preload('../converter.gd').new()
var color_table: Dictionary = {}
var transparency: bool = false
var tree: TreeNode
var leaf: Array = []
class TreeNode:
var colors: Array
var average_color: Array
var axis: int
var median: int
var parent: TreeNode
var left: TreeNode
var right: TreeNode
func _init(_parent: TreeNode, _colors: Array):
self.parent = _parent
self.colors = _colors
func median_cut() -> void:
var start: Array = [255, 255, 255]
var end: Array = [0, 0, 0]
var delta: Array = [0, 0, 0]
for color in colors:
for i in 3:
if color[i] < start[i]:
start[i] = color[i]
if color[i] > end[i]:
end[i] = color[i]
for i in 3:
delta[i] = end[i] - start[i]
axis = 0
if delta[1] > delta[0]:
axis = 1
if delta[2] > delta[axis]:
axis = 2
var axis_sort: Array = []
for i in colors.size():
axis_sort.append(colors[i][axis])
axis_sort.sort()
var cut = colors.size() >> 1
median = axis_sort[cut]
var left_colors: Array = []
var right_colors: Array = []
for color in colors:
if color[axis] < median:
left_colors.append(color)
else:
right_colors.append(color)
left = TreeNode.new(self, left_colors)
right = TreeNode.new(self, right_colors)
colors = []
func calculate_average_color(color_table: Dictionary) -> void:
average_color = [0, 0, 0]
var total: int = 0
for color in colors:
var weight = color_table[color]
for i in 3:
average_color[i] += color[i] * weight
total += weight
for i in 3:
average_color[i] /= total
func fill_color_table(image: Image) -> void:
image.lock()
var data: PoolByteArray = image.get_data()
for i in range(0, data.size(), 4):
if data[i + 3] == 0:
transparency = true
continue
var color: Array = [data[i], data[i + 1], data[i + 2]]
var count = color_table.get(color, 0)
color_table[color] = count + 1
image.unlock()
func convert_image(image: Image, colors: Array) -> PoolByteArray:
image.lock()
var data: PoolByteArray = image.get_data()
var nearest_lookup: Dictionary = {}
var result: PoolByteArray = PoolByteArray()
for i in colors.size():
colors[i] = Vector3(colors[i][0], colors[i][1], colors[i][2])
for i in range(0, data.size(), 4):
if data[i + 3] == 0:
result.append(0)
continue
var current: Vector3 = Vector3(data[i], data[i + 1], data[i + 2])
var nearest_index: int = 0 + int(transparency)
if current in nearest_lookup:
nearest_index = nearest_lookup[current]
else:
var nearest_distance: float = current.distance_squared_to(colors[nearest_index])
for j in range(1 + int(transparency), colors.size()):
var distance: float = current.distance_squared_to(colors[j])
if distance < nearest_distance:
nearest_index = j
nearest_distance = distance
nearest_lookup[current] = nearest_index
result.append(nearest_index)
image.unlock()
return result
func quantize_and_convert_to_codes(image: Image) -> Array:
color_table.clear()
transparency = false
fill_color_table(image)
tree = TreeNode.new(null, color_table.keys())
leaf = [tree]
var num = 254 if transparency else 255
while leaf.size() <= num:
var node = leaf.pop_front()
if node.colors.size() > 1:
node.median_cut()
leaf.append(node.left)
leaf.append(node.right)
if leaf.size() <= 0:
break
var color_quantized: Dictionary = {}
for node in leaf:
node.calculate_average_color(color_table)
color_quantized[node.average_color] = color_quantized.size()
var color_array: Array = color_quantized.keys()
if transparency:
color_array.push_front([0, 0, 0])
var data: PoolByteArray = converter.get_similar_indexed_datas(image, color_array)
return [data, color_array, transparency]

Binary file not shown.

View File

@ -0,0 +1,9 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://assets/fonts/CJK/NotoSansCJKtc-Regular.otf" type="DynamicFontData" id=1]
[resource]
size = 12
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )

View File

@ -0,0 +1,9 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://assets/fonts/CJK/NotoSansCJKtc-Regular.otf" type="DynamicFontData" id=1]
[resource]
size = 10
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )

View File

@ -0,0 +1,9 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://assets/fonts/Roboto-Bold.ttf" type="DynamicFontData" id=1]
[resource]
size = 12
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )

Binary file not shown.

View File

@ -0,0 +1,9 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://assets/fonts/Roboto-Italic.ttf" type="DynamicFontData" id=1]
[resource]
size = 12
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )

Binary file not shown.

View File

@ -0,0 +1,9 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://assets/fonts/Roboto-Regular.ttf" type="DynamicFontData" id=1]
[resource]
size = 12
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )

Binary file not shown.

View File

@ -0,0 +1,8 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://assets/fonts/Roboto-Regular.ttf" type="DynamicFontData" id=1]
[resource]
size = 10
use_mipmaps = true
font_data = ExtResource( 1 )

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/bucket.png-739d8168ebcd5362099b45138d07124e.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/bucket.png"
dest_files=[ "res://.import/bucket.png-739d8168ebcd5362099b45138d07124e.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/bucket_l.png-4f7c3df94ef1f9dd5663fb56a921426c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/bucket_l.png"
dest_files=[ "res://.import/bucket_l.png-4f7c3df94ef1f9dd5663fb56a921426c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/bucket_l_r.png-8035ba2a9e69311abb90e5c2e1116b5b.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/bucket_l_r.png"
dest_files=[ "res://.import/bucket_l_r.png-8035ba2a9e69311abb90e5c2e1116b5b.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/bucket_r.png-7e6e87f0eb3706b9a4c2683b5dfc13a1.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/bucket_r.png"
dest_files=[ "res://.import/bucket_r.png-7e6e87f0eb3706b9a4c2683b5dfc13a1.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/colorpicker.png-4849cc00860d4bd077116f5f4c156e28.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/colorpicker.png"
dest_files=[ "res://.import/colorpicker.png-4849cc00860d4bd077116f5f4c156e28.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/colorpicker_l.png-63ce5d5af072a001ac167671870a6652.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/colorpicker_l.png"
dest_files=[ "res://.import/colorpicker_l.png-63ce5d5af072a001ac167671870a6652.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/colorpicker_l_r.png-ddcb844c5732a98ad1afa0d2f983c73c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/colorpicker_l_r.png"
dest_files=[ "res://.import/colorpicker_l_r.png-ddcb844c5732a98ad1afa0d2f983c73c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/colorpicker_r.png-3a9fc8b7397235e8c6edc0091296207c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/colorpicker_r.png"
dest_files=[ "res://.import/colorpicker_r.png-3a9fc8b7397235e8c6edc0091296207c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/eraser.png-c3515c2808657bb1a5aed02228155f9c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/eraser.png"
dest_files=[ "res://.import/eraser.png-c3515c2808657bb1a5aed02228155f9c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/eraser_l.png-798dafb6c8e2dee57d8ac302f56639e5.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/eraser_l.png"
dest_files=[ "res://.import/eraser_l.png-798dafb6c8e2dee57d8ac302f56639e5.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/eraser_l_r.png-9a231785a5aea84f768dd8cedcf24582.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/eraser_l_r.png"
dest_files=[ "res://.import/eraser_l_r.png-9a231785a5aea84f768dd8cedcf24582.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/eraser_r.png-e8279250778bbfb0c3061707160e9a36.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/eraser_r.png"
dest_files=[ "res://.import/eraser_r.png-e8279250778bbfb0c3061707160e9a36.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lightendarken.png-cc76071888c6b4d42e88f84da5221ccb.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/lightendarken.png"
dest_files=[ "res://.import/lightendarken.png-cc76071888c6b4d42e88f84da5221ccb.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lightendarken_l.png-aa3b63835ac485853a829849ed2153b1.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/lightendarken_l.png"
dest_files=[ "res://.import/lightendarken_l.png-aa3b63835ac485853a829849ed2153b1.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lightendarken_l_r.png-e73a128a8a0b2e4ac56528b2d1cf529e.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/lightendarken_l_r.png"
dest_files=[ "res://.import/lightendarken_l_r.png-e73a128a8a0b2e4ac56528b2d1cf529e.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lightendarken_r.png-17165444a8a46fe8cc7e4c9c7a52ed1a.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/lightendarken_r.png"
dest_files=[ "res://.import/lightendarken_r.png-17165444a8a46fe8cc7e4c9c7a52ed1a.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Some files were not shown because too many files have changed in this diff Show More