Llosa de Viango Tollos – tollosDraw.c

Introduction

Features

Getting started

Download


Libraries

  Tollos libraries

  Device libraries

    boards

    microcontrollers

    peripherals


Background

  Sample application

  Troubleshooting

tollosDraw.c – draw (display) device functions

The draw functions provide access to display device(s) (LCDs, etc.), including text and graphics functions.

Display takes three steps:

  1. Initialize the display device using drawInit
  2. Build up an image in the screen buffer (maintained by Tollos) by setting pels or using drawing functions such as drawLine or text functions such as drawf (draw formatted string)
  3. Write the screen buffer to the device with drawWrite.

The model here is that supported display devices have a rectangular screen with a fixed number of pels (pixels) addressed in X and Y, where the origin of both is zero, and the pel addressed by X=0 and Y=0 is at the bottom left of the screen.

The number of pels in X and Y (and other characteristics) are reported in a drawConfig structure when the display device is initialized.

The model for pels is that each has a value in the range 0..255 in red, green, and blue (where 0 is black and 255 is 100% of each primary). A given device (screen) may not support 8-bit colours or even greyscale, so the nearest available value will be used. The chosen value can be determined by reading back a pel. The following drawRGB constants are provided; they are initialized to the 16 IBM PC CGA colours: BLACK CGA_DARKBLUE CGA_DARKGREEN CGA_DARKCYAN CGA_DARKRED CGA_DARKPINK CGA_BROWN PALEGREY DARKGREY CGA_BLUE CGA_GREEN CGA_CYAN CGA_RED CGA_PINK CGA_YELLOW WHITE.

Tollos maintains state in addition to the screen buffer to simplify use of the screen; this includes (defaults shown in brackets):

  • current pen colour (used for drawing lines and text, etc.) [black]
  • current canvas (background) color, used for clearing the screen, a rectangle, or a pel and optionally used when drawing text [white]
  • X position for next drawing operation [0]
  • Y position for next drawing operation [0]
  • The DRAW_BOUNDS flag [0].

While drawing, errors include parameters out of range, such as X or Y values outside the range of a 16-bit signed integer (−32768..32767). To report these, draw functions that receive bad parameters set the DRAW_BOUNDS flag rather than returning a negative return code. This allows a check for errors to be made at convenient intervals rather than at after every function call. DRAW_BOUNDS is cleared when the screen is cleared or written, as described in the relevant functions.

Text processing:

Tollos maintains additional state for text characters; this includes (defaults shown in brackets):

  • current font; fonts are bitmap fonts held in fontInfo structures [tollosFont5x7]
  • X position for next character [0]
  • Y position for next character (baseline pel) [top of screen, adjusted for font height and descent of first character]
  • Whether to write pen, canvas, both, or neither kind of pel from the character; the last of these can be used to measure the width of characters, formatted strings, etc.

When pen or canvas pels are written for a character the X and Y positions are first wrapped to the next row (or to the top of the screen) if there is insufficient space for the character and the character is then written. In all cases the X position is then incremented by the width of the character, +1 optional spacing. The leading (gap) between character rows is 1 pel (optional). See the drawPutc function for more detail on text drawing.
Functions
 drawBox   draw a box with corner at current position
 drawCanvas   set the canvas (background) colour
 drawClear   clear all screen pels to the canvas colour
 drawEllipse   draw an ellipse around the current position
 drawf   draw a text string with formatting
 drawFill   fill a simple polygon
 drawGetFont   get the current font
 drawGetPel   get the colour of a pel
 drawInit   initialize display and discover its configuration
 drawLine   draw a line from current position
 drawPel   set pel at current X and Y to pen or canvas colour
 drawPen   set the pen (foreground) colour
 drawPutc   display character on screen
 drawQuery   query a draw state item
 drawSetFont   set new current font
 drawSetPel   set a pel to a specific colour
 drawStop   stop the display device
 drawTextBits   sets text drawing behavior
 drawTextXY   set Text X and Y position
 drawWrite   write buffer to screen (display to user)
 drawXY   set X and Y position

drawBox – draw a box with corner at current position

void drawBox(int x, int y, flag fill);

x – X coordinate of opposite corner

y – Y coordinate to opposite corner

fill – 1 to fill the box with the canvas colour; 0 to leave the inside of the box unchanged

This draws a line box using the current pen colour. The box is drawn such that the current position forms one corner and x, y sets the opposite corner. The pels within the line box will be filled with the canvase colour if fill=1.

The current X and Y are not changed.

If x or y would not fit in 16 bits, DRAW_BOUNDS is set to 1 and no box (or fill) is drawn.

drawCanvas – set the canvas (background) colour

void drawCanvas(drawRGB rgb);

rgb – colour value [0..255 in each]

This sets the Canvas RGB value. No error is possible.

drawClear – clear all screen pels to the canvas colour

void drawClear(void);

This clears the screen buffer and resets the text X and Y position so the next character written will appear at top left. The DRAW_BOUNDS flag is cleared.

No other state is affected. No error is possible.

drawEllipse – draw an ellipse around the current position

void drawEllipse(int a, int b);

a – radius (semiaxis) in the X dimension (pels)

b – radius (semiaxis) in the Y dimension (pels)

This draws an ellipse centred on the current position using the pen colour. The ellipse will have its axes parallel to the X and Y axes of the screen; its width will be 2*a+1 pels and its height 2*b+1. Hence, if a == b a circle (in pel space) is drawn.

To draw a circle when pels are not square, use the screen pitch values to scale the value of a or b.

If a or b is negative or greater than 896, DRAW_BOUNDS is set and no oval is drawn.

The algorithm used is that given in Getting Raster Ellipses Right, M. Douglas McIlroy, ACM Transactions on Graphics (TOG) Volume 11, No. 3, July 1992 (doi>10.1145/130881.130892).

The arithmetic used in the algorithm fits in 32-bit signed integers for values of a and b less than 896; confirmed experimentally.

drawf – draw a text string with formatting

int drawf(const char *format, ...);

format – format and data string

... – other arguments as required

returns the number (count) of characters sent

See the tollosUtil strf function for a description of supported format strings (a subset of the C printf rules).

drawFill – fill a simple polygon

void drawFill(int x, int y);

x – X coordinate to fill from

y – Y coordinate to fill from

This fills an area bounded by pixels in the pen colour with pixels in the canvas colour. x and y give the start point of the fill; if that point is in the pen colour no fill is carried out.

In order to limit the time and memory requirements of this function, only simple shapes (in general, convex polygons) will be completely filled; the fill may be incomplete if there are concave vertices (line junctions at an angle that points into the fill area) or if there are ‘islands’ of pen colour pels within the area.

The fill area is assumed to be four-connected; that is, the fill will stop on reaching a pen-coloured pel horizontally or vertically – it will not pass between pels that touch diagonally (it can therefore be used to fill ellipses or circles drawn by drawEllipse, etc.).

If x or y is offscreen, DRAW_BOUNDS is set to 1 and no fill is attempted.

drawGetFont – get the current font

void drawGetFont(const fontInfo **font);

font – set to the pointer to the current font

No error is possible.

drawGetPel – get the colour of a pel

void drawGetPel(int x, int y, drawRGB *rgb);

x – the X coordinate of the pel

y – the Y coordinate of the pel

rgb – returned colour value [0..255 in each]

This returns the RGB values of the pel at x, y. If x or y is offscreen, 0 is returned for all three values. If x or y would not fit in 16 bits, DRAW_BOUNDS is set to 1.

drawInit – initialize display and discover its configuration

int drawInit(drawConfig *config);

config – configuration structure (always set)

returns 0 if OK, negative if error (e.g., device not available, or a bus error)

This function initializes the display, clears the screen buffer to white, writes the cleared buffer to the device, and sets the configuration structure so the caller can determine the device geometry and characteristics.

General state is initialized such that X=0, Y=0, the foreground colour is black and the background white. The DRAW_BOUNDS flag is cleared.

The text state is initialized so that the first character written using drawPutc will appear at the top left of the screen (by default, in the tollosFont5x7 font writing both foreground and background).

The screen buffer is cleared to white and the configuration and state are set even if an error occurred during device initialization.

Note that it is not always possible to determine if the device or screen is available, because some devices are ‘write only’.

The following items are reported in the display configuration structure:

  • type – device type (binary, greyscale, or colour)
  • width – screen width (pels)
  • height – screen height (pels)
  • depth – screen depth (bits/pel, maximum 32)
  • xpitch – horizontal dot pitch (micrometers)
  • ypitch – vertical dot pitch (micrometers)
  • writetime – typical time to write a full screen of pels to the physical device (microseconds); this is an estimate, not a guarantee.

drawLine – draw a line from current position

void drawLine(int x, int y);

x – X coordinate to draw line to

y – Y coordinate to draw line to

This draws a line from the current position to x, y, using the pen colour; the current position is then updated to be x, y. A compact version of Bresenham’s algorithm is used.

If x or y would not fit in 16 bits, DRAW_BOUNDS is set to 1 and no line is drawn.

drawPel – set pel at current X and Y to pen or canvas colour

void drawPel(flag pel);

pel – 0 to set pel to canvas, 1 to set to pen colour

Only the screen buffer is affected. No error is possible.

drawPen – set the pen (foreground) colour

void drawPen(drawRGB rgb);

rgb – colour value [0..255 in each]

This sets the Pen RGB value. No error is possible.

drawPutc – display character on screen

void drawPutc(int ch);

ch – character to display

The character is displayed using the current font, text X and Y position, and pen and canvas colours. The character rectangle defined in the font is positioned such that its left column will be at the text X position and its bottom left corner will be d pels below the text Y position (where d is the font descent – the number of rows below the baseline).

For each bit with a value of 1 in the character the corresponding pel is written with the pen colour, provided that TEXT_PEN is 1. For each bit with a value of 0 in the character the corresponding pel is written with the canvas colour, provided that TEXT_CANVAS is 1.

If either TEXT_PEN or TEXT_CANVAS is set, this function will ensure a maximum width of the character is written to the screen: if there is insufficient space to the right of the character, the rest of the line is cleared (if TEXT_CANVAS is set) and then the text X and Y positions are wrapped to the next row (which may then wrap to the top of the screen). The character is then written.

In all cases the X position is then incremented by the width of the character, +1 pel of spacing if FONT_SPACE (an attribute of the font) is set.

If wrap to a new row takes place, leading of one pel is added if FONT_LEAD is set. Any spacing or leading will be written with the canvas colour if TEXT_CANVAS is set.

If neither TEXT_PEN nor TEXT_CANVAS is set, no line wrap takes place and so the change in X position will reflect the width of the character (and any spacing) always; this can be used to measure the width of characters, formatted strings, etc. In this case the text Y position is unchanged.

An ASCII control character (code point < 0x20, or 0x7f) is only treated as a control character if the current font does not define a character at that code point and either TEXT_PEN or TEXT_CANVAS is set. Control characters are ignored (have no effect) except for the following:

  • CR: sets the X position to 0
  • LF: move the Y position down a line (may cause a wrap to top of the screen when the next character is written)
  • FF: clear the screen and reset the X and Y positions so the next character will appear at top left
  • TAB: moves the X position to the next tab position that is at least nwidth+FONT_SPACE pels to the right; a tab position is textTab*(nwidth+FONT_SPACE) pels; this may cause a line wrap when the next character is written.

If a character is not in a font and is not a control character then the first character in the font will be displayed.

Characters are permitted to touch all edges of the screen (it is not required to have pel space to the right or below), even if FONT_SPACE and/or FONT_LEAD are set.

The text X and Y positions are not necessarily on-screen; however, they are limited to 32 bits. The text X position will be constrained to the screen width if a line wrap takes place, and similarly the text Y position will be constrained to the screen height if a line wrap causes a wrap to the top of the screen to take place.

drawQuery – query a draw state item

int drawQuery(uint item);

item – a constant listed in tollosDraw.h

returns current value of the item, or −1 if the item is unknown

Valid items are:

DRAW_X – drawing position

DRAW_Y – ..

DRAW_PEN_R – pen colour

DRAW_PEN_G – ..

DRAW_PEN_B – ..

DRAW_CANVAS_R – canvas color

DRAW_CANVAS_G – ..

DRAW_CANVAS_B – ..

DRAW_BOUNDS – bounds error bit

TEXT_X – text write position

TEXT_Y – ..

TEXT_PEN – 1 if 1 bits write (in pen colour)

TEXT_CANVAS – 1 if 0 bits write (in canvas colour)

Notes:

  1. DRAW_X and DRAW_Y values will always fit in 16 bits
  2. Colour values(_R, _G, _B) have values in the range 0..255
  3. DRAW_BOUNDS, TEXT_PEN, and TEXT_CANVAS will be 0 or 1
  4. TEXT_X and TEXT_Y may have any 32-bit value

drawSetFont – set new current font

void drawSetFont(const fontInfo *font);

font – the font to be the new current font

The font is a filled-in and valid Tollos fontInfo structure, with associated data.

No other state (such as text X and Y position) is affected. No error is possible.

drawSetPel – set a pel to a specific colour

void drawSetPel(int x, int y, drawRGB rgb);

x – pel X coordinate

y – pel Y coordinate

rgb – colour value [0..255 in each]

This sets the pel at x, y to the RGB value; if x or y would not fit in 16 bits this has no effect other than to set DRAW_BOUNDS to 1.

drawStop – stop the display device

void drawStop(void);

This puts the device into a clean or low power/off mode, if appropriate. For LCDs this should save power as well as properly discharging the display. No error is possible.

drawTextBits – sets text drawing behavior

void drawTextBits(flag canvas, flag pen);

canvas – non-0 to write font 0 bits in canvas colour

pen – non-0 to write font 1 bits in pen colour

This sets the TEXT_CANVAS and TEXT_PEN flags which control the writing of font 0 and 1 bits to the screen. If both are 0 no pels will be written but characters can be measured.

See drawPutc for more detail. No error is possible.

drawTextXY – set Text X and Y position

void drawTextXY(int x, int y);

x – X coordinate

y – Y coordinate

This sets the text X and Y positions; x or y may be off-screen; this is not an error – they will be brought on-screen when the next character is placed by drawPutc.

drawWrite – write buffer to screen (display to user)

int drawWrite(void);

returns 0 if OK, negative if error (e.g., bus error)

This function sends the screen buffer to the device. Depending on the device, this may send the whole buffer to the device, or it may send only parts that have changed since the last call to drawWrite.

The DRAW_BOUNDS flag is cleared.

drawXY – set X and Y position

void drawXY(int x, int y);

x – X coordinate

y – Y coordinate

This moves the current position to x, y; if x or y would not fit in 16 bits, DRAW_BOUNDS is set to 1 and the current position is not changed.

Tollos and these web pages were written by Mike Cowlishaw; Please send me any corrections, suggestions, etc.
All content © Mike Cowlishaw, 2010–2012, except where marked otherwise. All rights reserved. The pages here are for non-commercial use only (see the separate licence for Tollos source code). Privacy policy: the Speleotrove website records no personal information and sets no ‘cookies’. However, statistics, etc. might be recorded by the web hosting service.

This page was last updated on 2011-10-17 by c2wiki.