{"id":20750555,"url":"https://github.com/micycle1/ptext","last_synced_at":"2025-09-27T20:31:45.832Z","repository":{"id":133574931,"uuid":"319458957","full_name":"micycle1/PText","owner":"micycle1","description":"Precise text metrics \u0026 manipulation in Processing","archived":false,"fork":false,"pushed_at":"2023-03-12T22:40:38.000Z","size":8772,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-17T08:37:41.859Z","etag":null,"topics":["geometry","processing","processing-library"],"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/micycle1.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}},"created_at":"2020-12-07T22:19:17.000Z","updated_at":"2023-11-28T13:43:11.000Z","dependencies_parsed_at":"2023-12-28T23:21:11.856Z","dependency_job_id":null,"html_url":"https://github.com/micycle1/PText","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micycle1%2FPText","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micycle1%2FPText/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micycle1%2FPText/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micycle1%2FPText/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/micycle1","download_url":"https://codeload.github.com/micycle1/PText/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234460512,"owners_count":18836837,"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":["geometry","processing","processing-library"],"created_at":"2024-11-17T08:27:51.773Z","updated_at":"2025-09-27T20:31:45.275Z","avatar_url":"https://github.com/micycle1.png","language":"Java","readme":"\u003ch3 align=\"center\"\u003e 🚧 This README (and library) is under construction 🚧 \u003c/h3\u003e\n\n# PText\n\n**PText** bridges the gap between Processing's PFont and PShape classes, providing some much needed functionality when working with text in Processing.\n\nPText extends `PShape`, meaning that is stores text in a vector format. With this, it offers methods to:\n\n* Easily manipulate text dimensions\n* Get a text's exact bounds (dimensions)\n* Accurately get text's ascent and descent (unlike Processing's existing methods — see [appendix](#Appendix))\n* Manipulate text characteristics (such as shear and per-character rotation)\n* Visualise per-character bounds, whitespace, and vertices\n\n# API\n\nThe PText API is catalogued below.\n\n## Text\n\n* **`setText(text)`**\n* **`setFont(fontNameString, fontSize)`**\n* **`setFont(PFont)`**\n\n## Dimensions\n\n* **`scale(both)`**\n* **`scale(x, y)`**\n* **`setScale(both)`**\n* **`setScale(x, y)`**\n\n### Width\n\n* **`setTextWidth(n)`**\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/micycle1/\"\u003e\n  \u003cimg src=\"resources/horizontal_resize.gif\" alt=\"example\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n* **`scaleWidth(n)`**\n* **`getTextWidth()`**\n\n\n\n### Height\n\n* **`setTextHeight(n)`**\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/micycle1/\"\u003e\n  \u003cimg src=\"resources/vertical_resize.gif\" alt=\"example\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n* **`scaleHeight(n)`**\n* **`getTextHeight()`**\n\n## Other Text Metrics\n\n* **`getTextAscent()`**\n* **`getTextDescent()`**\n* **`getFontAscent()`**\n* **`getFontDescent()`**\n* **`getWhiteSpaceLeft()`**\n* **`getWhiteSpaceRight()`**\n* **`getCharWidth(character)`**\n* **`getCharHeight(character)`**\n* **`getCharWhitespace(character)`**\n\n## Text Manipulation\n\n* **`setCharacterSpacing(n)`**\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/micycle1/\"\u003e\n  \u003cimg src=\"resources/char_spacing2.gif\" alt=\"example\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n* **`setCharacterRotation(charIndex, angle)`**\n\n  \u003e TODO image\n\n* **`setShearX(maxShear)`**\n\n  \u003e TODO image\n\n## Rendering\n\n* **`shape(myPText, x, y)`**\n  \n  Use Processing's `shape()` method to draw the PText like a `PShape` (alignment will be `LEFT`, `BASELINE`). \n\n* **`draw(x, y, alignX, alignY)`**\n\n  Or call `draw()` on the PText object to specify a specific X and Y alignment (similar to `textAlign()`).\n## Debug\n\n* **`debug()`**\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/micycle1/\"\u003e\n  \u003cimg src=\"resources/debug.gif\" alt=\"example\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# Example\n\nResizing a PText shape using setTextWidth() and setTextHeight(), using debug() to show \n\n```\nimport pText.PText;\n\nPText text;\n\nvoid setup() {\n  \n  size(1280, 720);\n  smooth(4);\n\n  text = new PText(this, \"Bauhaus 93\", 192);\n  \n  text.setText(\"hello\");\n  \n  text.setFill(color(55, 255, 90));\n  text.setStrokeWeight(1);\n\n  text.setScale(1, 1);\n  //shapeMode(CENTER);\n  text.setTextWidth(width);\n  text.setTextHeight(height);\n  \n    noFill(); // you must call global noFill() after any setText(), otherwise text can't be filled\n}\n\nvoid draw() {\n\n  background(255);\n\n  shape(text, mouseX, mouseY);\n  //text.debug(mouseX, mouseY);\n}\n```\n\n# Appendix\n\nUsing the inbuilt functions `textWidth()`, `textAscent()`, and `textDescent()` are an easy way to get a *good* approximate result for the height and width of a string (of a given font), but they are not *exact*.\n\nWhy? \n\n- `textAscent()` returns text height above the baseline **based on the letter 'd'**\n- `textDescent()` returns text height below the baseline **based on the letter 'p'**.\n- `textWidth()` includes glyph whitespace (aka padding; ideally we want to ignore this for the first and last characters)\n\n`textAscent() + textDescent()` therefore measures the **maximum height** of a string in a given font and font size, and not the height of a specific string. In other words, if your text doesn't include both 'd' and 'p' characters, then using these methods to determine text height will overestimate the result.\n\n# TODO\n\n- [x] Scale whitespace (to increase/decrease spacing between letters, independent of font size)\n- [x] Display dimension labels (such as ascent \u0026 descent) in debug mode\n- [x] String ascent: return the max ascent of the string's **current** characters\n- [x] String descent: return the max descent of the string's **current** characters\n- [ ] Allow multiple fonts within one PText at once?\n- [ ] Support multiple lines / blocks of text","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicycle1%2Fptext","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicycle1%2Fptext","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicycle1%2Fptext/lists"}