{"id":13823312,"url":"https://github.com/as/frame","last_synced_at":"2026-01-31T09:46:11.435Z","repository":{"id":57486355,"uuid":"77265890","full_name":"as/frame","owner":"as","description":"Frame provides plan9-like editable text widgets ","archived":false,"fork":false,"pushed_at":"2020-04-21T22:20:21.000Z","size":1197,"stargazers_count":65,"open_issues_count":11,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-08-04T09:01:17.097Z","etag":null,"topics":["box","edit","frame","golang","graphics","libframe","native","plan9","text"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/as.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}},"created_at":"2016-12-24T04:35:24.000Z","updated_at":"2024-06-08T09:12:08.000Z","dependencies_parsed_at":"2022-09-01T22:31:23.493Z","dependency_job_id":null,"html_url":"https://github.com/as/frame","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/as%2Fframe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/as%2Fframe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/as%2Fframe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/as%2Fframe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/as","download_url":"https://codeload.github.com/as/frame/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225453309,"owners_count":17476700,"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":["box","edit","frame","golang","graphics","libframe","native","plan9","text"],"created_at":"2024-08-04T09:00:28.883Z","updated_at":"2026-01-31T09:46:11.377Z","avatar_url":"https://github.com/as.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"## Frame \n[![Go Report Card](https://goreportcard.com/badge/github.com/as/frame)](https://goreportcard.com/report/github.com/as/frame)\n\n## Synopsis\n\nPackage frame implements graphical, editable text widgets compatible with Plan 9's libframe(3). Unlike libframe, the text is\nbyte-addressed and preserves NUL terminated strings. The related `github.com/as/font` package provides a superset of the\n`golang.org/x/font.Face` interface and implements additional functionality for working with Go fonts and frames.\n\n![paint](elastic.png)\n\n## Installation\n\n```\n\tgo get -d -u github.com/as/frame/...\n```\n\n## Updates\n\nNOTE: The API has changed since this README.md was updated. \n\n- The font functionality is no longer embedded in the frame package\n- The frame.New constructor package function has been modified to take a Config struct\n\nRun the provided gofix program under to programatically update your packages:\n\n```\n\tgo get -u github.com/as/frame/...\n\tgo install github.com/as/frame/framefix\n\tframefix github.com/as/ui\n```\n\n## Description\n\nA Frame is a graphical text container. It draws text on a bitmap, using previously-drawn text as a cache. \n\nCreate one using New:\n\n```\n  dst := image.NewRGBA( image.Rect(0,0,100,100), \n  f := frame.New(dst, dst.Bounds(), \u0026Config struct {\n\t\tColor: frame.Mono,\n        Font : font.NewFace(12), \n   }\n```\n\n## Rendering\n\nThe most frequent operations are Insert and Delete. Insert renders text at a given offset without overwriting existing\ntext. Delete deletes a range of text and moves existing text after it into its range. Ranges are defined by two integers\nand behave equivalently to Go slice indices.\n\nInsert and delete are inverses.\n\n```\nf.Insert([]byte(\"hello world.\"), 0)\nf.Delete(0, 11)\n```\n\n## Projection\n\n`PointOf` projects the index of a character to a 2D image.Point on the image. `IndexOf` does the opposite, projecting\nan index to a point.\n\nThey are also inverse operations.\n\n```\n\tf.InsertString(\"hello\")\n\tf.IndexOf(f.PointOf(4))\t// returns: 4\n\tf.PointOf(f.IndexOf(image.Pt(25,25))) // returns: (25, 25)\n```\n\nThere is no method for extracting the values of characters in the frame. The data structures are designed to be fast write-only containers.\n\n\n## Selection\n\nFrames select a continuous range of text with `Select`. The currently-selected range is queried with `Dot`.\n\n```\n\tf.InsertString(\"hello\")\n\tf.Select(0,2)\n\tf.Dot()\t// returns (0,2)\n```\n\n\n## Drawing\n\nBecause the bitmap is an arbitrary image and also a living cache of glyphs, drawing\non the bitmap between rendering operations persists on the underlying glyphs. There\nare a few ways to re-render the bitmap or a region of it.\n\n\n```\nRecolor(pt image.Point, p0, p1 int64, cols Palette)\n  Recolor colors the range p0:p1 by redrawing the foreground, background, and font glyphs\n\nRedraw(pt image.Point, p0, p1 int64, issel bool)\n  Redraw redraws the characters between p0:p1. It accesses the cache of drawn glyph widths\n  to avoid remeasuring strings\n\nRedrawAt(pt image.Point, text, back image.Image)\n  RedrawAt refreshes the entire image to the right of the given pt. Everything below is redrawn.\n\nRefresh()\n  Refresh recomputes the state of the frame from scratch. This is an expensive operation compared\n  to redraw\n\nPaint(pt0, pt1 image.Point, col image.Image)\n  Paint paints the color col on the frame at points pt0-pt1. The result is a Z shaped fill\n  consisting of at-most 3 rectangles. No text is redrawn.\n```\n\n## Examples\n\n- Basic\nhttps://github.com/as/frame/blob/master/example/basic/basic.go\n\n- UTF-8\nhttps://github.com/as/frame/blob/master/example/utf8/utf8.go\n\n- Elastic\nhttps://github.com/as/frame/blob/master/example/elastic/elastic.go\n\n\n## Feature Set\n\n- UTF8\n- ASCII\n- Elastic tabstops\n- Semantic replacement characters\n\n# Note\n\nA frame's text is not addressable. Once the characters are written to the frame, there is no\nmechanism to retrieve value from within the frame. Use a buffer to store text for reading\nand the range addresses of the frame to access bytes from that buffer.\n\nSee `github.com/as/ui/win` for an example.\n\n## See Also\n\nhttp://doc.cat-v.org/plan_9/4th_edition/papers/sam/\n\nSpecifically, the section `Data structures in the terminal` served as a guide\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fas%2Fframe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fas%2Fframe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fas%2Fframe/lists"}