{"id":25504568,"url":"https://github.com/nilostolte/java-hacks","last_synced_at":"2025-10-09T09:37:55.805Z","repository":{"id":142985167,"uuid":"356386291","full_name":"nilostolte/Java-Hacks","owner":"nilostolte","description":"Each directory of this repository contains a program in Java that is shown how to be compiled via CLI with a build.bat for Windows machines (in other machines just copy and paste the individual commands in this batch file or convert it the another shell script) to obtain a jar application that functions as a tool or example.","archived":false,"fork":false,"pushed_at":"2025-03-15T22:32:50.000Z","size":549,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-19T22:41:52.379Z","etag":null,"topics":["illustrations","java","parser","phong-model","phong-shading","radial-gradient","specular-glossiness","specular-highlight","stop-color","svg","symbol-table","tree","treemap","vector-graphics"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nilostolte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-04-09T20:06:20.000Z","updated_at":"2025-03-15T22:32:53.000Z","dependencies_parsed_at":"2025-01-03T17:32:05.108Z","dependency_job_id":"61753564-7504-4f5a-a24b-7b4f8c043b67","html_url":"https://github.com/nilostolte/Java-Hacks","commit_stats":null,"previous_names":["nilostolte/java-hacks"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nilostolte/Java-Hacks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilostolte%2FJava-Hacks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilostolte%2FJava-Hacks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilostolte%2FJava-Hacks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilostolte%2FJava-Hacks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nilostolte","download_url":"https://codeload.github.com/nilostolte/Java-Hacks/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilostolte%2FJava-Hacks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001122,"owners_count":26083022,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["illustrations","java","parser","phong-model","phong-shading","radial-gradient","specular-glossiness","specular-highlight","stop-color","svg","symbol-table","tree","treemap","vector-graphics"],"created_at":"2025-02-19T05:41:13.561Z","updated_at":"2025-10-09T09:37:55.800Z","avatar_url":"https://github.com/nilostolte.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Java Hacks\n\nEach directory of this repository contains a program in Java that is shown how to be compiled \nvia CLI with a `build.bat` for Windows machines (in other machines just copy and paste the \nindividual commands in this batch file or convert it the another shell script) to obtain a \n`jar` application that functions as a tool or example.\n\n## SVGspecular - Phong shading for SVG radial gradients\n\n[This](SVGspecular) is a single class program that creates an **SVG** file containing a square with a non-linear radial gradient based on Phong shading function for specular highlights (function $cos^n(angle)$​). The program produces a complete standalone **SVG** file.\n\nThe **SVG** has a number of stop colors $N$ determined by the user. Other parameters, such as the\nexponent of Phong's function (the $n$ of $cos^n(angle)$, not $N$), can also be supplied by the user following the program name as usually done in **CLI** mode.\n\n### Overall algorithm\n\nThe program takes the **initial color** $\\vec{C_0}$ (which is generally white in the center of a the radial\ngradient) and the **last color** $\\vec{C_1}$ (which is any color to be continued outside the radial gradient),\nand linearly interpolates the color $\\vec{C}$ for each **stop color** based on a multidimensional parametric line equation, where the value of the parameter $t$ is given by the result of applying an $angle$ $\\alpha$ to the function $cos^n(angle)$. In other words, this procedure is shown below:\n\n```math\n  \\begin{aligned}\n     \u0026t = cos^n(\\alpha)\\\\\n     \u0026\\vec{C} = \\vec{C_1}+ (\\vec{C_0} - \\vec{C_1}) \\cdot t\\\\\n     \u0026\\\\\n  \\end{aligned}\n ```\n\nNotice that the individual color components need to be processed independently. For simplicity and easier comprehension, the colors are dealt here as a sort of 3D (or 4D, including the alpha channel) vector representation. Indeed, colors can be represented as vectors where each color component corresponds to a different dimension.\n\nCheck the complete algorithm [here](SVGspecular/README.md)\n\n## SVGPathBoundingBox\n\nThis is a [parser](SVGPathBoundingBox) for vectorized SVG files generated by [Vectorizer](https://vectorizer.com/) or \nfor other SVG files using the same path representation as Vectorizer. It also provides some other generic tools like \n([reverse.java](SVGPathBoundingBox/reverse.java)) to reverse paths in files generated by Vectorizer or other SVG files\nusing identical representation for SVG paths.\n\nThe parser interprets path commands and calculates their bounding boxes. This is useful to locate locate paths in a complex\nSVG file, for example.\n\n### Vectorizer SVG path representation\n\n[Vectorizer](https://vectorizer.com/) represents a path using only the initial \"M\" command followed by \"C\" or \"c\" commands, and \nending with a \"z\" command. In this representation, graphics commands are actually all represented by cubic Bezier curves. Therefore,\neven lines and quadratic Bezier curves are represented using cubic Bezier curves notation, that is with three control points (plus\nthe current pen point, which is also a control point in SVG.\n\n### Utility to reverse paths using Vectorizer path representation\n\nThe generic utility [reverse.java](SVGPathBoundingBox/reverse.java) reverses a path given in Vectorizer's format passed as a string (with \nexplicit double quotes) to the program. Consider the following example:\n\n```\njava reverse\nPaste your path and press Enter: M459,1308.5c-6.313-5.109-8.98-11.776-8-20c1.297-13.675,8.63-22.342,22-26 c18.909-8.942,38.909-12.276,60-10c3.084,1.469,5.917,3.302,8.5,5.5c7.969,14.922,5.469,27.756-7.5,38.5 c-21.537,9.883-44.204,15.05-68,15.5C464.115,1310.189,461.781,1309.021,459,1308.5z\"\n```\n\nWhich produces this result:\n\n```\nM459,1308.5c2.781,0.521,5.115,1.689,7,3.5c23.796-0.45,46.463-5.617,68-15.5c12.969-10.744,15.469-23.578,7.5-38.5c-2.583-2.198,-5.416-4.031-8.5-5.5c-21.091-2.276,-41.091,1.058-60,10c-13.37,3.658,-20.703,12.325-22,26c-0.98,8.224,1.687,14.891,8,20z\n```\n\n**Purpose of this utility**: the inversion of paths are useful to \"carve\" the interior of another path by pasting the inverted path right after it. The\nreverted path must be in the interior of the path preceeding it.\n\n\n## SVGfix - TreeMap Example\n\n[This program](SVGfix) copies the color information from CSS classes and plugs them into the\nrespective paths using SVG `fill` attribute instead of CSS.\n\nIt's an example of application using `TreeMap` JRE class to create a tree\nfunctioning as a symbol table to keep colors of SVG paths initially defined by CSS classes at \nthe beginning of the SVG file as done by some versions of Illustrator when saving the file as SVG.\n\nOnce the program reads the colors between `\u003cdefs\u003e\u003cstyle\u003e` and  `\u003c/style\u003e\u003c/defs\u003e` from file `input.svg`,\nstoring the the colors preceeded by a `fill` command in string format and using the class name as the key \nto access it in the `TreeMap`, it then prints in the command prompt (usually redirected to a file) the SVG\nwith colors applied directly to the corresponding path (via `fill` attribute) that used the corresponding \nclass to define the color.\n\nThis program is a simple hack and it may copy other commands when multiple classes with the same name are\nused but only the last reference will be taken into account for each path. Complex configurations, like \nCSS classes separated by commas sharing the same attribute (color or another attribute) will cause an error.\n\nWhen an error is detected while using the `TreeMap`, the program says which class was not found and dumps all \nthe keys of the tree for debugging purposes.\n\n## SVGinktxt - Mini parser for Texts and Automatization of CLI Debbuging\n\nThe actual class is called \"[SVGinktxt](SVGtextInkscape/SVGinktxt.java).\" More details about it can be\nfound in the [SVGinktxt README file](SVGtextInkscape/README.md). This program implements a small\nparser for texts in SVG coming from Inkscape. It erases the matrix that appears at each text line, by just\napplying the matrix to the coordinates of the first item in the line. For simplification and because the y\ncoordinate first item in these cases is always negative, I just search for the negative value. Since Inkscape\nuses an entire matrix only to translate a negative y to a positive y, all I have to do is to extract the y \ntranslation from the matrix, make the matrix disappear, and add that value to the negative y in the first \nelement of the line.\n\nNotice that doing that, the matrix becomes an identity matrix which is what allows us to delete it.\nInkscape typically generates one text item per line. This item posesses only one y coordinate and a list of \nx coordinates, one for each glyph in the text item. This is generally used to justify texts.\n\nIn certain versions of Illustrator text justifications don't always come out well. For some reason when the\nfile is converted to SVG a line that was perfectly well justified on-screen can sometimes be divided at its last \nword, with a hyphen at the end of the line and the rest of the word appearing on the next line. This messes up \nwith the intended formatting where the words were chosen to fit well in the paragraph. Something that looked\nbeautiful and harmonious, becomes ugly and awkward.\n\nThe easy solution for this problem is to convert the whole file on Illustrator to PDF, import the PDF file into \nInkscape and save the file as SVG. The problem is that Inkscape is too verbose and also makes use of internal \nvariables where the name \"inkscape\" appears everywhere. The perfect solution in this case is to locate the text in\nthe file generated by Inkscape and copy it into the file generated by Illustrator. It's often easier to erase the whole\ntext in the file generated by Illustrator and substitute it by the text copied from the file generated by Inkscape.\n\nNew versions of Inkscape make this procedure almost straightforward. The only strange thing is the use of one matrix\nper line only to do a translation in the y coordinate. SVGinktxt is used to remove those matrices from all Inkscape\ntext items.\n\nOn the other hand, the main interest of this class is not exactly its use case, but in the way the parser was written.\nIt uses a methodololy that makes it ressemble a BNF grammar. This is done with just simple programming rules that \nare explained in the [SVGinktxt README file](SVGtextInkscape/README.md).\n\nAnother insteresting topic discussed [there](SVGtextInkscape/README.md) is the automatization of CLI Java debugger \nsetup which was used in this project to release the burden of manually setting it by hand.\n\n## UTF-8\n\n[This project](UTF-8) allows to read UTF-8 encoded UNICODE files. It implements an infinite buffer file \nreader where one can recover the text word by word, which is converted from UTF-8, skipping blanks. \nThe blanks can be recovered since they are all counted (feature used in the test program). By skipping \nblanks the reader is able to identify the start and the end of the words because they are different \nthan blank. The fact that the text is encoded is totally transparent to the reader. The test program \nreads an UTF-8 testing file and prints it over the console. A batch file is provided to help running\nthe jar. The source files are also given and they are all for free with no license of any kind. \n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnilostolte%2Fjava-hacks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnilostolte%2Fjava-hacks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnilostolte%2Fjava-hacks/lists"}