QuickPrint is a text drawing library for the LÖVE Framework.
Version: v1.0.9a
- Virtual tab stops
- Can print to LÖVE Text Objects
- Basic support for scaled text (for pixel-art LÖVE ImageFonts)
- Tweak per-font vertical metrics and scale using an intermediate table
local quickPrint = require("quick_print")
local qp = quickPrint.new()
local tabs = {0, 128, 160, 256}
function love.update(dt)
tabs[2] = love.mouse.getX()
end
function love.draw()
qp:reset()
qp:setTabs(tabs)
qp:print("Hello ", "World! ", "Lorem ", "Ipsum")
qp:setTabs()
end
Check out the demo files for more examples.
QuickPrint updates an internal cursor position with every draw. When virtual tab stops are enabled, the next write is positioned relative to the current tab X position. It can draw text to the screen/canvas, or add text to a LÖVE Text object.
Functions take effect immediately (there is no reshaping step, and limited memory of previous drawing operations), so it's limited in the kinds of layouts it supports. The library was originally written for debug-printing.
QuickPrint's writing functions are split into "plain" and "formatted" categories. The plain functions convert all values to be printed to strings. As a result, LÖVE coloredtext
sequences won't work. The formatted writing functions do not apply any type conversion, and are programmed to handle coloredtext
.
Creates and returns a new quick_print state table.
quickPrint.new(ref_w, ref_h)
ref_w
: (math.huge) Reference width for the cursor. Affects formatted print calls with non-left alignment.ref_h
: (math.huge) Reference height for the cursor. Doesn't affect printing, but may help with other tasks such as setting a draw scissor.
Returns: A new qp
state table.
Registers a font with the auxiliary font database (see Auxiliary Data section). All fonts are registered upon first being used with QuickPrint, but you may register fonts ahead of time to apply additional tweaks. This can be helpful with LÖVE ImageFonts. Note that if there is an existing aux table for this font, it will be overwritten by a new one.
local aux = quickPrint.registerFont(font)
font
: The LÖVE Font object to register.
Returns: The aux data table for this font.
Gets a font's auxiliary data table (see Auxiliary Data section). If not found, creates, registers and returns a new table.
local aux = quickPrint.getAux(font)
font
: The LÖVE Font object to register.
Returns: The font's auxiliary data table.
Gets the LÖVE graphics state font, or the font associated with a LÖVE Text object which is assigned to qp
.
qp:getFont()
Returns: A LÖVE Font object.
Assigns a LÖVE Text object to qp
, or removes any existing object. All print commands will be directed to the Text object instead of the framebuffer/canvas. The qp
table should be reset after calling, and you should call Text:clear()
to ensure you are working with a clean slate.
qp:setTextObject(text_object)
text_object
: The LÖVE Text object to assign, or false/nil to remove any existing Text object.
Returns the currently assigned qp
Text object, or nil if none is assigned.
local text_object = qp:getTextObject()
Returns: A LÖVE Text object or nil.
Assigns a table of virtual tab stops, or removes any existing tab sequence. Each entry is either a number representing the tab's absolute X position, or a sub-table containing x
and align
fields. Although the X positions are absolute, they should be ordered left-to-right in the table.
qp:setTabs(tabs)
tabs
: A sequence of tab stops, or false/nil to remove any assigned tabs.
Gets the currently-assigned table of tabs, or nil if no tabs are assigned.
local tabs_t = qp:getTabs()
Returns: Table of tabs if present, or nil if nothing is assigned.
Sets the current tab index. Does not check if the index is valid or that the qp state has a tabs table assigned. Note that the cursor will not automatically go backwards to a tab that is behind.
qp:setTabIndex(i)
i
: The tab index to jump to.
Gets the tab index, or false if tab state is invalid.
local tab_i = qp:getTabIndex()
Returns: The current tab index, or false if tab state is invalid.
Sets the horizontal align mode. Alignment behavior varies between plain and formatted print functions. justify
mode behaves like left
in plain functions. Some printing functions have arguments which override this setting.
qp:setAlign(align)
align
: The LÖVE align mode. Can beleft
,center
,right
, orjustify
.
See: LÖVE Wiki: AlignMode
Gets the horizontal align mode.
local align = qp:getAlign()
Returns: The align LÖVE enum.
Sets the default horizontal align mode, which is applied by qp:reset()
.
qp:setDefaultAlign(align)
align
: The LÖVE align mode. Can beleft
,center
,right
, orjustify
.
See: LÖVE Wiki: AlignMode
Gets the default horizontal align mode.
local default_align = qp:getAlign()
Returns: The default align LÖVE enum.
Sets the vertical align mode. Text is placed relative to the cursor Y and the current font's vertical metrics.
qp:setVAlign(v_align)
v_align
: The vertical align mode. Can betop
,middle
,true-middle
,baseline
, orbottom
.
The vertical align modes are:
top
: (default) Cursor is at the top of the text.
middle
: Cursor is at the midpoint between the ascent and baseline metrics.
true-middle
: Cursor is at half the font height.
bottom
: Cursor is at the bottom of the text.
NOTE: When using baseline
or middle
vertical alignment with LÖVE ImageFonts, you must set the baseline metric in the font's aux table. (Except for height, ImageFonts do not have valid vertical metrics.) Otherwise, the text will appear at the wrong vertical position. See Auxiliary Data for more info.
Gets the vertical align mode.
local v_align = qp:getVAlign()
Returns: The vertical align mode.
Sets the default vertical align mode, applied in qp:reset()
.
qp:setDefaultVAlign(v_align)
v_align
: The vertical align mode. Can betop
,middle
,true-middle
,baseline
, orbottom
. (See qp:setVAlign() for more info.)
Gets the default vertical align mode.
local default_v_align = qp:getDefaultVAlign()
Returns: The default vertical align mode.
Moves the X cursor by a number of pixels. (Cursor X advance is generally only useful with left alignment. The other align modes are intended to be used with virtual tab stops.) Clears kerning memory.
qp:advanceX(width)
width
: Number of pixels to move
Moves the X cursor by the pixel-width of a string, measured in reference to the current active font. Clears kerning memory.
qp:advanceXStr(str)
str
: The string whose width will be used (viaFont:getWidth()
.)
Moves the X cursor to at least the requested minimum position. Clears kerning memory, even if the X position is unaffected.
qp:advanceXMin(x_min)
x_min
: The minimum position.
Moves the X cursor right in "coarse" steps, acting somewhat like a tab stop without involving the qp.tabs
table. Clears kerning memory.
qp:advanceXMod(coarse_x, margin)
-
coarse_x
: The "snap-to" width to use when positioning the cursor, in pixels. -
margin
: (0) Adds pixel padding to the current X position, making it jump to the next coarse position earlier. Use to ensure there is a buffer of empty space between printed text.
If tab stops are assigned, moves the X cursor to the current virtual tab stop, if it is currently behind. Increments the tab stop index. Clears kerning memory. If no tabs are assigned, does nothing.
qp:advanceTab()
Moves the cursor to an arbitrary position, relative to the origin. Clears kerning memory and invalidates tab stop state.
qp:setPosition(x, y)
x
: X position, relative toqp.origin_x
.y
: Y position, relative toqp.origin_y
.
Moves the cursor to an arbitrary horizontal position, relative to the origin. Clears kerning memory and invalidates tab stop state.
qp:setXPosition(x)
x
: X position, relative toqp.origin_x
.
Moves the cursor to an arbitrary vertical position, relative to the origin. Does not clear kerning memory or tab stop state.
qp:setYPosition(y)
y
: Y position, relative toqp.origin_y
.
Gets the current cursor position, relative to the origin.
local x, y = qp:getPosition()
Returns: The cursor X and Y positions (qp.x
and qp.y
).
Gets the current cursor X position, relative to the origin.
local x = qp:getXPosition()
Returns: The cursor X position (qp.x
).
Gets the current cursor Y position, relative to the origin.
local y = qp:getYPosition()
Returns: The cursor Y position (qp.y
).
Moves the cursor, relative to the current position. Resets kerning memory and invalidates tab stop state.
qp:movePosition(dx, dy)
x
: Amount to add to the current X position (qp.x
).y
: Amount to add to the current Y position (qp.y
).
Moves the cursor horizontally, relative to the current position. Resets kerning memory and invalidates tab stop state.
qp:moveXPosition(dx)
x
: Amount to add to the current X position (qp.x
).
Moves the cursor vertically, relative to the current position. Does not reset kerning memory or tab stop state.
qp:moveYPosition(dy)
y
: Amount to add to the current Y position (qp.y
).
Repositions the qp
origin (top-left printing area). Resets cursor position to (0, 0). Resets kerning memory.
qp:setOrigin(origin_x, origin_y)
origin_x
: New X origin.origin_y
: New Y origin.
Repositions the qp
X origin (left printing area). Resets cursor position to (0, 0). Resets kerning memory.
qp:setXOrigin(origin_x)
origin_x
: New X origin.
Repositions the qp
Y origin (top printing area). Resets cursor position to (0, 0). Resets kerning memory.
qp:setYOrigin(origin_y)
origin_y
: New Y origin.
Gets the current qp
origin.
local orig_x, orig_y = qp:getOrigin()
Returns: The qp
origin X and Y (qp.origin_x
and qp.origin_y
).
Gets the current qp
X axis origin.
local orig_x = qp:getXOrigin()
Returns: The qp
X origin (qp.origin_x
).
Gets the current qp
Y axis origin
local orig_y = qp:getYOrigin()
Returns: The qp
Y origin (qp.origin_y
).
Moves the qp
origin relative to its current location. Resets cursor position to (0, 0). Resets kerning memory.
qp:moveOrigin(dx, dy)
:
dx
: Amount to add to the current X origin (qp.origin_x
).dy
: Amount to add to the current Y origin (qp.origin_y
).
Sets the current reference width and height (of the printing area). Resets kerning memory.
qp:setReferenceDimensions(ref_w, ref_h)
ref_w
: New base width (qp.ref_w
).ref_h
: New base height (qp.ref_h
).
Note: Reference height is not currently used by QuickPrint, but is provided in case it helps with positioning and applying scissor-boxes.
Gets the current reference dimensions.
local ref_w, ref_h = qp:getReferenceDimensions()
Returns: The current reference dimensions.
Sets the qp
reference width (of the printing area). Resets kerning memory.
qp:setReferenceWidth(ref_w)
ref_w
: The new reference width.
Gets the qp
reference width.
local ref_w = qp:getReferenceWidth()
Returns: The reference width.
Sets the qp
reference height (of the printing area). Resets kerning memory.
qp:setReferenceHeight(ref_h)
ref_h
: The new reference height.
Note: Reference height is not currently used by QuickPrint, but is provided in case it helps with positioning and applying scissor-boxes.
Gets the current reference height.
local ref_h = qp:getReferenceHeight()
Returns: The reference height.
Sets the qp
scale. Intended to help with drawing pixel art ImageFonts within a scaled interface. These values will be passed as the sx
and sy
arguments for love.graphics.print()
and love.graphics.printf()
, and the cursor will attempt to take the scale into account when moving forward.
qp:setScale(sx, sy)
sx
X scale. 1.0 is normal size, 2.0 is double, 0.5 is half, etc.sy
(sx) Y scale.
Gets the current qp
scale.
local sx, sy = qp:getScale()
Returns: The X scale and Y scale values (qp.sx
, qp.sy
).
Sets a vertical padding value, which is applied whenever the cursor moves down a line.
qp:setVerticalPadding(pad_v)
pad_v
Additional padding (in pixels).
Note: It may be more effective to set a custom line height multiplier in your LÖVE Font objects. See: Font:setLineHeight()
Gets the current vertical padding value.
local pad_v = qp:getVerticalPadding()
Returns: The vertical padding value (qp.pad_v
)
Moves cursor to (0, 0), resets the alignment modes to the defaults, and resets the tab stop index to 1. It does not clear the qp.tabs
table, nor does it remove bound Text objects. Clears kerning memory.
qp:reset()
Moves cursor down by a number of lines. Line height is determined by the current font, its line height setting, and the qp
's Y scaling. Vertical padding (qp.pad_v
) is applied once per call. Clears kerning memory.
qp:down(qty)
qty
: (1) How many lines to move down. Numbers less than 1 are ignored.
Clears kerning memory, and nothing else.
qp:clearKerningMemory()
In all plain writing functions, values are converted to strings before being passed to love.graphics.print()
.
Writes a varargs series of strings to a line.
qp:write(...)
...
Varargs list of variables to write.
A version of qp:write()
that takes one sequence (array table).
qp:writeSeq(tbl)
tbl
: Table of values to write. Values can be any type exceptnil
.
Versions of qp:write()
which take exactly 1 to 4 arguments. Additional arguments are ignored.
qp:write1(s1)
qp:write2(s1, s2)
qp:write3(s1, s2, s3)
qp:write4(s1, s2, s3, s4)
s1
: The first value to write.s2
: The second value.s3
: The third value.s4
: The fourth value.
Writes a varargs list of arguments to a line, and then moves the cursor to the start of the next line.
qp:print(...)
...
Varargs list of variables to write.
Version of qp:print()
that takes one sequence (array table).
qp:printSeq(tbl)
tbl
: Table of values to write. Values can be any type exceptnil
.
Versions of qp:print()
which take exactly 1 to 4 arguments. Additional arguments are ignored.
qp:print1(s1)
qp:print2(s1, s2)
qp:print3(s1, s2, s3)
qp:print4(s1, s2, s3, s4)
s1
: The first value to write.s2
: The second value.s3
: The third value.s4
: The fourth value.
These do not convert values to strings, and are programmed to support coloredtext
sequences. Unlike the plain functions, they take only one string or coloredtext
sequence per call.
Prints one string or coloredtext
sequence using formatting features provided by love.graphics.printf()
. This function assumes that the text will not exceed one line (or that the caller is not concerned if it happens to wrap). If you use horizontal align modes other than "left"
, you must set a reference width (qp.ref_w
), or else the text will render infinitely to the right. This function is also affected by virtual tab stop state. It does not advance the X cursor.
qp:writefSingle(text, align)
text
: The string orcoloredtext
sequence to print.align
: (qp.align
) LÖVE AlignMode enum:"left"
,"center"
,"right"
or"justify"
.
Like qp:writefSingle()
, but automatically moves the cursor down one line after printing.
qp:printfSingle(text, align)
text
: The string orcoloredtext
sequence to print.align
: (qp.align
) LÖVE AlignMode enum:"left"
,"center"
,"right"
or"justify"
.
Prints one string or coloredtext
sequence using formatting features provided by love.graphics.printf()
, and then moves the cursor down to the next free line. Unlike qp:writefSingle()
and qp:printfSingle()
, this does not take the virtual tab state into account. It will also generate some throwaway tables and strings in order to calculate the new Y cursor position.
qp:printf(text, align)
text
: The string orcoloredtext
sequence to print.align
: (qp.pf_align
) LÖVE AlignMode enum:"left"
,"center"
,"right"
or"justify"
.
Added in 1.0.6, The quickPrint.aux_db
table holds supplemental metadata for fonts.
An aux data table contains the following fields:
-
height
: Defaults tofont:getHeight()
. -
ascent
: Defaults tofont:getAscent()
. -
descent
: Defaults tofont:getDescent()
. -
baseline
: Defaults tofont:getBaseline()
. -
sx
: (1.0) Horizontal scale, multiplied withqp.sx
. -
sy
: (1.0) Vertical scale, multiplied withqp.sy
. -
ox
: (0) Horizontal drawing offset in pixels. Not scaled byaux.sx
. -
oy
: (0) Vertical drawing offset in pixels. Not scaled byaux.sy
.
The ascent, descent and baseline metrics are invalid for LÖVE ImageFonts, so if you want to use baseline vertical alignment with them, you should change those settings in their aux tables.
As Font objects are used as keys, a font may have only one aux data table assigned at a time. The aux_db
table uses weak keys, so it won't prevent Fonts from being cleaned by the garbage collector.
-
QuickPrint does not currently handle RTL text (planned for LÖVE 12).
-
Text objects do not support multiple simultaneous fonts, so you shouldn't change a Text object's font as you write to it.
-
QuickPrint is not optimized, and cannot be optimized very much given its design. (It's quick as in quick and dirty.) If you have a lot of text that rarely changes, you can save some CPU cycles by printing it to a LÖVE Text object and drawing that, only clearing and rewriting the Text when there's a change. Rendering to a canvas is another option.
-
When performing multiple writes to a single line, QuickPrint holds a reference to the last font used. This could prevent it from being cleaned by the garbage collector. The reference is dropped whenever kerning state is cleared, so you can drop it manually by calling
qp:clearKerningMemory()
.
- In LÖVE 11.4, adding empty or whitespace-only strings to a Text Object crashes the application.
- This is fixed in LÖVE 12.
_love11TextGuard()
is implemented as a workaround. It will be removed when the library is upgraded to LÖVE 12.
- In LÖVE 11.4, small
wraplimit
values given toText:addf()
crash the application.- This is fixed in LÖVE 12.
Text:setf()
andlove.graphics.printf()
are not affected. - Workaround: If using
Text:addf()
, find a minimum working value for your font(s) and never make the reference width smaller than that.
- This is fixed in LÖVE 12.