{"id":16953899,"url":"https://github.com/romainguy/pathway","last_synced_at":"2025-04-09T10:10:07.438Z","repository":{"id":40778369,"uuid":"428439021","full_name":"romainguy/pathway","owner":"romainguy","description":"A set of APIs to manipulate graphics paths on Android.","archived":false,"fork":false,"pushed_at":"2024-07-21T19:11:52.000Z","size":163,"stargazers_count":212,"open_issues_count":0,"forks_count":4,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-02T02:24:58.600Z","etag":null,"topics":["android","graphics","kotlin-android","path"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/romainguy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2021-11-15T22:20:31.000Z","updated_at":"2025-02-20T15:44:17.000Z","dependencies_parsed_at":"2023-01-29T01:45:13.228Z","dependency_job_id":"0faec38c-92a4-4ef3-9af7-d6ccd8b9d1fe","html_url":"https://github.com/romainguy/pathway","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romainguy%2Fpathway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romainguy%2Fpathway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romainguy%2Fpathway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romainguy%2Fpathway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/romainguy","download_url":"https://codeload.github.com/romainguy/pathway/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248018061,"owners_count":21034048,"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","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":["android","graphics","kotlin-android","path"],"created_at":"2024-10-13T22:08:15.556Z","updated_at":"2025-04-09T10:10:06.844Z","avatar_url":"https://github.com/romainguy.png","language":"Kotlin","readme":"# Pathway\n\n[![pathway](https://maven-badges.herokuapp.com/maven-central/dev.romainguy/pathway/badge.svg?subject=pathway)](https://maven-badges.herokuapp.com/maven-central/dev.romainguy/pathway)\n[![Android build status](https://github.com/romainguy/pathway/workflows/Android/badge.svg)](https://github.com/romainguy/pathway/actions?query=workflow%3AAndroid)\n\nPathway is an Android library that provides new functionalities around the graphics\n[Path](https://developer.android.com/reference/android/graphics/Path) API.\n\nPathway is compatible with API 21+.\n\n## Maven\n\n```gradle\nrepositories {\n    // ...\n    mavenCentral()\n}\n\ndependencies {\n    implementation 'dev.romainguy:pathway:0.18.0'\n}\n```\n\n## Features\n\n- [Paths from images](#paths-from-images)\n- [Path division](#path-division)\n- [Convert to SVG](#convert-to-svg)\n- [Iterating over a Path](#iterating-over-a-path)\n\n## Paths from images\n\n`Bitmap.toPath()` and `Bitmap.toPaths()` can be used to extract vector contours from images, as\n`Path` object. `toPath()` extracts all the contours in a single `Path` while `toPaths()` returns\na list of contours as separate `Path` instances. Calling `toPaths()` is equivalent to calling\n`toPath().divide()` (see [Path division](#path-division)) but more efficient.\n\nWhen extracting a path from an image, two parameters can be set:\n- `alphaTreshold`: defines the maximum alpha channel value a pixel might have before being\n  considered opaque. Transitions from opaque to transparent are used to define the contours\n  in the image. The default value is 0.0f (meaning any pixel with an alpha \u003e 0.0 is considered\n  to be inside the contour).\n- `minAngle`: defines the minimum angle in degrees between two segments in the contour before\n  they are collapsed to simplify the final geometry. The default value is 15 degrees. Setting\n  this value to 0 will yield an exact vector representation of the contours but will generate\n  complex and expensive paths.\n\n## Path division\n\nPath division can be used to generate a list of paths from a source path. Each contour, defined\nby a \"move\" operation, in the source path is extracted as a separate `Path`. In the following\nexample the `paths` variable contains a list of 2 `Path` instance, each containing one of the\nrectangles originally added to the source `path`:\n\n```kotlin\nval path = Path().apply {\n    addRect(0.0f, 0.0f, 24.0f, 24.0f)\n    addRect(32.0f, 32.0f, 64.0f, 64.0f)\n}\nval paths = path.divide()\n```\n\n## Convert to SVG\n\nTo convert a `Path` to an SVG document, call `Path.toSvg()`. If you only want the path data instead\nof a full SVG document, use `Path.toSvg(document = false)` instead. Exporting a full document will\nproperly honor the path's fill type.\n\n## Iterating over a Path\n\n\u003e [!IMPORTANT]\n\u003e Prefer the new androidx\n\u003e [graphics-path library](https://developer.android.com/reference/kotlin/androidx/graphics/path/package-summary) to\n\u003e iterate over paths\n\n\u003e [!NOTE]\n\u003e As of Android 14 (API 34), iterating over a `Path` can be achieved using the new\n\u003e platform API [getPathIterator()](https://developer.android.com/reference/android/graphics/Path#getPathIterator()).\n\u003e Pathway is however compatible with Android 14.\n\nWith Pathway you can easily iterate over a `Path` object to inspect its segments\n(curves or commands):\n\n```kotlin\nval path = Path().apply {\n    // Build path content\n}\n\nfor (segment in path) {\n    val type = segment.type // The type of segment (move, cubic, quadratic, line, close, etc.)\n    val points = segment.points // The points describing the segment geometry\n}\n```\n\nThis type of iteration is easy to use but may create an allocation per segment iterated over.\nIf you must avoid allocations, Pathway provides a lower-level API to do so:\n\n```kotlin\nval path = Path().apply {\n    // Build path content\n}\n\nval iterator = path.iterator\nval points = FloatArray(8)\n\nwhile (iterator.hasNext()) {\n    val type = iterator.next(points) // The type of segment\n    // Read the segment geometry from the points array depending on the type\n}\n\n```\n\n### Path segments\n\nEach segment in a `Path` can be of one of the following types:\n\n#### Move\n\nMove command. The path segment contains 1 point indicating the move destination.\nThe weight is set 0.0f and not meaningful.\n\n#### Line\n\nLine curve. The path segment contains 2 points indicating the two extremities of\nthe line. The weight is set 0.0f and not meaningful.\n\n#### Quadratic\n\nQuadratic curve. The path segment contains 3 points in the following order:\n- Start point\n- Control point\n- End point\n\nThe weight is set 0.0f and not meaningful.\n\n#### Conic\n\nConic curve. The path segment contains 3 points in the following order:\n- Start point\n- Control point\n- End point\n\nThe curve is weighted by the `PathSegment.weight` property.\n\nConic curves are automatically converted to quadratic curves by default, see\n[Handling conic segments](#handling-conic-segments) below for more information.\n\n#### Cubic\n\nCubic curve. The path segment contains 4 points in the following order:\n- Start point\n- First control point\n- Second control point\n- End point\n\nThe weight is set 0.0f and not meaningful.\n\n#### Close\n\nClose command. Close the current contour by joining the last point added to the\npath with the first point of the current contour. The segment does not contain\nany point. The weight is set 0.0f and not meaningful.\n\n#### Done\n\nDone command. This optional command indicates that no further segment will be\nfound in the path. It typically indicates the end of an iteration over a path\nand can be ignored.\n\n### Handling conic segments\n\nIn some API levels, paths may contain conic curves (weighted quadratics) but the\n`Path` API does not offer a way to add conics to a `Path` object. To work around\nthis, Pathway automatically converts conics into several quadratics by default.\n\nThe conic to quadratic conversion is an approximation controlled by a tolerance\nthreshold, set by default to 0.25f (sub-pixel). If you want to preserve conics\nor control the tolerance, you can use the following APIs:\n\n```kotlin\n// Preserve conics\nval iterator = path.iterator(PathIterator.ConicEvaluation.AsConic)\n\n// Control the tolerance of the conic to quadratic conversion\nval iterator = path.iterator(PathIterator.ConicEvaluation.AsQuadratics, 2.0f)\n\n```\n\n## License\n\nPlease see LICENSE.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromainguy%2Fpathway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fromainguy%2Fpathway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromainguy%2Fpathway/lists"}