How to linebreak or word wrap with blf.draw

I try to linebreak or wordwrap output to the 3dview but i cant get it working.
How is the right way to do it?

game_message = "GameTime - asdfasdfasdf\n abc def 123"


def draw_callback_px(self, context):
    """Draw game messages on viewport"""
    font_id = font_info['font_id']
    blf.position(font_id, 2, 80, 0)
    blf.size(font_id, 25, 72)
    blf.word_wrap(font_id, 100)
    blf.draw(font_id, game_message)

I’d try doing the linebreaks in code, something like this (untested):

uiScale = context.preferences.view.ui_scale

(...)

def draw_callback_px(args):
    fontID = 0
    blf.size(fontID, int(16.0 * uiScale), 0)
    lineHeight = blf.dimensions(fontID, 'M')[1] * 2.0

    posX = ...
    posY = ...

    for line in game_message.split('\n'):
        blf.position(fontID, posX, posY, 0)
        blf.draw(fontID, line)
        posY -= lineHeight
1 Like

Thanks for the answer and workaround.

I take a look at docs again and see the constant blf.WORD_WRAP got the value 128 for 2.78, for 2.80 the value is 64.
https://docs.blender.org/api/blender_python_api_current/blf.html
https://docs.blender.org/api/current/blf.html

word_warp should be working since 2015: https://developer.blender.org/D1493

Could it be blf.word_wrap is not working cause the constant is changed accidantly?
Can someone confirm word_warp is working in 2.78, i would make a bug report.

Use blf.enable(blf.WORD_WRAP) to enable wrap. Needed for recognizing "\n".
Use blf.word_wrap(fontid, px) for automatic wrapping of long strings (the above must be enabled).

Disable the wrapping at the end of drawing with blf.disable(blf.WORD_WRAP).

st_1 = "Line 1\nLine 2\n\nLine 4\n"

st_2 = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."""

blf.enable(1, blf.WORD_WRAP)
blf.color(1, 1, 1, 1, 1)
blf.position(1, 20, 500, 0)

blf.word_wrap(1, 300)  # pixels

blf.draw(1, st_1 + st_2)
blf.disable(1, blf.WORD_WRAP)
3 Likes

Oh wow, there’s a BLF effect for that! that’s good to know.

Like @kaio explained, you’re supposed to enable that with blf.enable(constant) for the effect to work, the same way you do with the other effects (blf.SHADOW, blf.ROTATION etc.).