{"id":2296,"date":"2020-01-09T08:37:23","date_gmt":"2020-01-09T08:37:23","guid":{"rendered":"http:\/\/www.richa1.com\/RichardAlbritton\/?p=2296"},"modified":"2020-02-11T21:40:16","modified_gmt":"2020-02-11T21:40:16","slug":"circuitpython-word-wrap-for-label-text","status":"publish","type":"post","link":"https:\/\/www.richa1.com\/RichardAlbritton\/circuitpython-word-wrap-for-label-text\/","title":{"rendered":"CircuitPython word wrap for Label() text"},"content":{"rendered":"\n<p>This example code contains a function called wrap_nicely that can be used to reformat string text and add line brakes to wrap text at a given text count.<\/p>\n\n\n\n<!--more-->\n\n\n\n<pre class=\"wp-block-code\"><code># return a reformatted string with wordwrapping\n#@staticmethod\ndef wrap_nicely(string, max_chars):\n    \"\"\"A helper that will return the string with word-break wrapping.\n    :param str string: The text to be wrapped.\n    :param int max_chars: The maximum number of characters on a line before wrapping.\n    \"\"\"\n    string = string.replace('\\n', '').replace('\\r', '') # strip confusing newlines\n    words = string.split(' ')\n    the_lines = []\n    the_line = \"\"\n    for w in words:\n        if len(the_line+' '+w) &lt;= max_chars:\n            the_line += ' '+w\n        else:\n            the_lines.append(the_line)\n            the_line = w\n    if the_line:\n        the_lines.append(the_line)\n    the_lines[0] = the_lines[0][1:]\n    the_newline = \"\"\n    for w in the_lines:\n        the_newline += '\\n'+w\n    return the_newline<\/code><\/pre>\n\n\n\n<p>There is a glitch with text rendering when the Label.text is updated with this reformatted text. To fix this I recommend updating Label.text with &#8220;&#8221; to clear out whatever is glitching.<\/p>\n\n\n\n<p>Here is the full example code where I have added recalculation of the Label.y position to account for the position change due to the number of text lines.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import time\nimport board\nimport displayio\nfrom adafruit_bitmap_font import bitmap_font\nfrom adafruit_display_text import label\n\ndisplay = board.DISPLAY\n \n# ---------- Set the font and preload letters ---------- \n# Be sure to put your font into a folder named \"fonts\".\nfont = bitmap_font.load_font(\"\/fonts\/Helvetica-Bold-16.bdf\")\n# This will preload the text images.\nfont.load_glyphs(b'abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ- ()')\n\nglyph_box = font.get_bounding_box()\nglyph_h = glyph_box[1] + abs(glyph_box[3])\n \n# ---------- Create the text label object ---------- \n# font: the font used\n# text: some words that you want to display\n# color: set the font color\n# max_glyphs: the number of letters that can appear in this label\ntext_area = label.Label(font, text=\"HELLO WORLD\", color=0xFF00FF, max_glyphs=200)\n\n# Set the location\ntext_area.x = 20\ntext_area.y = 100\n\n# Set the size of the text in whole numbers. 1 = full size and 2 = twice the size.\ntext_area.scale = 1\n\n# return a reformatted string with wordwrapping\n#@staticmethod\ndef wrap_nicely(string, max_chars):\n    \"\"\"A helper that will return the string with word-break wrapping.\n    :param str string: The text to be wrapped.\n    :param int max_chars: The maximum number of characters on a line before wrapping.\n    \"\"\"\n    string = string.replace('\\n', '').replace('\\r', '') # strip confusing newlines\n    words = string.split(' ')\n    the_lines = []\n    the_line = \"\"\n    for w in words:\n        if len(the_line+' '+w) &lt;= max_chars:\n            the_line += ' '+w\n        else:\n            the_lines.append(the_line)\n            the_line = w\n    if the_line:\n        the_lines.append(the_line)\n    the_lines[0] = the_lines[0][1:]\n    the_newline = \"\"\n    for w in the_lines:\n        the_newline += '\\n'+w\n    return the_newline\n\n# Show it\ndisplay.show(text_area)\n\nwhile True:\n    # this is used to clear the text buffer\n    text_area.text = \"\" # Odd things happen without this\n    # Create the Wrapped text string and set it to new_text\n    new_text = wrap_nicely(\"The first command is 0xe1 with 15 (0xf) parameters following. The second and third are 0x11 and 0x29 respectively with delays (0x80) of 120ms (0x78) and no parameters.\", 33)\n    # Calculate the new text_area.y based on the number of text lines.\n    text_area.y = round(new_text.count(\"\\n\")*glyph_h\/2)\n    # Send the new wrapped string to text_area.text\n    text_area.text = new_text\n\n    time.sleep(3)\n    text_area.text = \"\" # Odd things happen without this\n    new_text = wrap_nicely(\"Now this is a fine mess that we are in.\", 13)\n    text_area.y = round(new_text.count(\"\\n\")*glyph_h\/2)\n    text_area.text = new_text\n    time.sleep(3)<\/code><\/pre>\n\n\n\n<p>The wrap_nicely() function is based on a similar function used in the <strong>adafruit_pyportal.py<\/strong> library for CircuitPython.<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/adafruit\/Adafruit_CircuitPython_PyPortal\/blob\/81c82035649007bbccb7d0ec75ce192f3b2ca058\/adafruit_pyportal.py\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">https:\/\/github.com\/adafruit\/Adafruit_CircuitPython_PyPortal\/blob\/81c82035649007bbccb7d0ec75ce192f3b2ca058\/adafruit_pyportal.py<\/a><\/p>\n<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing\"><h3 class=\"sd-title\">Share this:<\/h3><div class=\"sd-content\"><ul><li class=\"share-print\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-print sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/circuitpython-word-wrap-for-label-text\/\" target=\"_blank\" title=\"Click to print\"><span>Print<\/span><\/a><\/li><li class=\"share-email\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-email sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/circuitpython-word-wrap-for-label-text\/?share=email\" target=\"_blank\" title=\"Click to email this to a friend\"><span>Email<\/span><\/a><\/li><li class=\"share-facebook\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-facebook-2296\" class=\"share-facebook sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/circuitpython-word-wrap-for-label-text\/?share=facebook\" target=\"_blank\" title=\"Click to share on Facebook\"><span>Facebook<\/span><\/a><\/li><li class=\"share-twitter\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-twitter-2296\" class=\"share-twitter sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/circuitpython-word-wrap-for-label-text\/?share=twitter\" target=\"_blank\" title=\"Click to share on Twitter\"><span>Twitter<\/span><\/a><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>This example code contains a function called wrap_nicely that can be used to reformat string text and add line brakes to wrap text at a given text count.<\/p>\n<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing\"><h3 class=\"sd-title\">Share this:<\/h3><div class=\"sd-content\"><ul><li class=\"share-print\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-print sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/circuitpython-word-wrap-for-label-text\/\" target=\"_blank\" title=\"Click to print\"><span>Print<\/span><\/a><\/li><li class=\"share-email\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-email sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/circuitpython-word-wrap-for-label-text\/?share=email\" target=\"_blank\" title=\"Click to email this to a friend\"><span>Email<\/span><\/a><\/li><li class=\"share-facebook\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-facebook-2296\" class=\"share-facebook sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/circuitpython-word-wrap-for-label-text\/?share=facebook\" target=\"_blank\" title=\"Click to share on Facebook\"><span>Facebook<\/span><\/a><\/li><li class=\"share-twitter\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-twitter-2296\" class=\"share-twitter sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/circuitpython-word-wrap-for-label-text\/?share=twitter\" target=\"_blank\" title=\"Click to share on Twitter\"><span>Twitter<\/span><\/a><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div>","protected":false},"author":1,"featured_media":2325,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[191,57,79],"tags":[190,189,192],"jetpack_featured_media_url":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-content\/uploads\/2020\/01\/CircuitPython.png","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5AhH6-B2","_links":{"self":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts\/2296"}],"collection":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/comments?post=2296"}],"version-history":[{"count":3,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts\/2296\/revisions"}],"predecessor-version":[{"id":2324,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts\/2296\/revisions\/2324"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/media\/2325"}],"wp:attachment":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/media?parent=2296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/categories?post=2296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/tags?post=2296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}