HTL will not decode the text returned by format. I think the confusion comes from the documentation which states for the display context text the following:
Use this for simple HTML content - Encodes all HTML
(Source: HTL Specification Section 1.2.1 Display Context)
But this does not mean that this context decodes anything, it encodes HTML tags.
So if sighltyObj.field1 is Hello%20World it will not be rendered as Hello World but as Hello%20World as you already noticed.
The display context text will encode all HTML tags in the given text so that you can't "smuggle" them into a text (see code injection).
So for example:
${'<p>This is my text</p>' @ context='text'}
will create the following HTML
<p>This is my text</p>
Note how the p tags were encoded:
<p> became <p> and </p> became </p>.
The getter for field1 in your sighltyObj will have to do the decoding so that Hello%20World becomes Hello World. There is already a answer on Stackoverflow that shows you how to do this: https://stackoverflow.com/a/6138183/190823
String result = java.net.URLDecoder.decode(url, "UTF-8");