Преглед изворни кода

* cucul_set_size() does nothing if a graphical backend is attached. Added

documentation to explain this behaviour.
tags/v0.99.beta14
Sam Hocevar sam пре 19 година
родитељ
комит
05e98f2254
1 измењених фајлова са 113 додато и 95 уклоњено
  1. +113
    -95
      cucul/cucul.c

+ 113
- 95
cucul/cucul.c Прегледај датотеку

@@ -26,7 +26,8 @@
#include "cucul.h"
#include "cucul_internals.h"

static void cucul_read_environment(cucul_t *qq);
static void cucul_read_environment(cucul_t *);
void _cucul_set_size(cucul_t *, unsigned int, unsigned int);

/** \brief Initialise \e libcucul.
*
@@ -74,118 +75,46 @@ cucul_t * cucul_init(void)
return qq;
}

/** \brief Set the screen size.
/** \brief Set the canvas size.
*
* This function sets the screen width and height, in character cells.
* This function sets the canvas width and height, in character cells.
*
* \param width The desired screen width
* \param height The desired screen height
* It is an error to try to resize the canvas if an output driver has
* been attached to the canvas using caca_attach(). You need to remove
* the output driver using caca_detach() before you can change the
* canvas size again.
*
* However, the caca output driver can cause a canvas resize through
* user interaction. See the caca_event() documentation for more about
* this.
*
* \param width The desired canvas width
* \param height The desired canvas height
*/
void cucul_set_size(cucul_t *qq, unsigned int width, unsigned int height)
{
unsigned int x, y, old_width, old_height, new_size, old_size;

old_width = qq->width;
old_height = qq->height;
old_size = old_width * old_height;

qq->width = width;
qq->height = height;
new_size = width * height;

/* Step 1: if new area is bigger, resize the memory area now. */
if(new_size > old_size)
{
qq->chars = realloc(qq->chars, new_size * sizeof(uint32_t));
qq->attr = realloc(qq->attr, new_size * sizeof(uint8_t));
}

/* Step 2: move line data if necessary. */
if(width == old_width)
{
/* Width did not change, which means we do not need to move data. */
;
}
else if(width > old_width)
{
/* New width is bigger than old width, which means we need to
* copy lines starting from the bottom of the screen otherwise
* we will overwrite information. */
for(y = height < old_height ? height : old_height; y--; )
{
for(x = old_width; x--; )
{
qq->chars[y * width + x] = qq->chars[y * old_width + x];
qq->attr[y * width + x] = qq->attr[y * old_width + x];
}
if(qq->refcount)
return;

/* Zero the end of the line */
for(x = width - old_width; x--; )
qq->chars[y * width + old_width + x] = (uint32_t)' ';
memset(qq->attr + y * width + old_width, 0,
width - old_width);
}
}
else
{
/* New width is smaller. Copy as many lines as possible. Ignore
* the first line, it is already in place. */
unsigned int lines = height < old_height ? height : old_height;

for(y = 1; y < lines; y++)
{
for(x = 0; x < width; x++)
{
qq->chars[y * width + x] = qq->chars[y * old_width + x];
qq->attr[y * width + x] = qq->attr[y * old_width + x];
}
}
}

/* Step 3: fill the bottom of the new screen if necessary. */
if(height > old_height)
{
/* Zero the bottom of the screen */
for(x = (height - old_height) * width; x--; )
qq->chars[old_height * width + x] = (uint32_t)' ';
memset(qq->attr + old_height * width, 0,
(height - old_height) * width);
}

/* Step 4: if new area is smaller, resize memory area now. */
if(new_size <= old_size)
{
qq->chars = realloc(qq->chars, new_size * sizeof(uint32_t));
qq->attr = realloc(qq->attr, new_size * sizeof(uint8_t));
}

/* Recompute the scratch line and the empty line */
if(width != old_width)
{
qq->empty_line = realloc(qq->empty_line, width + 1);
memset(qq->empty_line, ' ', width);
qq->empty_line[width] = '\0';

qq->scratch_line = realloc(qq->scratch_line, width + 1);
}
cucul_set_size_internal(qq, width, height);
}

/** \brief Get the screen width.
/** \brief Get the canvas width.
*
* This function returns the current screen width, in character cells.
* This function returns the current canvas width, in character cells.
*
* \return The screen width.
* \return The canvas width.
*/
unsigned int cucul_get_width(cucul_t *qq)
{
return qq->width;
}

/** \brief Get the screen height.
/** \brief Get the canvas height.
*
* This function returns the current screen height, in character cells.
* This function returns the current canvas height, in character cells.
*
* \return The screen height.
* \return The canvas height.
*/
unsigned int cucul_get_height(cucul_t *qq)
{
@@ -394,3 +323,92 @@ static void cucul_read_environment(cucul_t * qq)
#endif
}

void _cucul_set_size(cucul_t *qq, unsigned int width, unsigned int height)
{
unsigned int x, y, old_width, old_height, new_size, old_size;

old_width = qq->width;
old_height = qq->height;
old_size = old_width * old_height;

qq->width = width;
qq->height = height;
new_size = width * height;

/* Step 1: if new area is bigger, resize the memory area now. */
if(new_size > old_size)
{
qq->chars = realloc(qq->chars, new_size * sizeof(uint32_t));
qq->attr = realloc(qq->attr, new_size * sizeof(uint8_t));
}

/* Step 2: move line data if necessary. */
if(width == old_width)
{
/* Width did not change, which means we do not need to move data. */
;
}
else if(width > old_width)
{
/* New width is bigger than old width, which means we need to
* copy lines starting from the bottom of the screen otherwise
* we will overwrite information. */
for(y = height < old_height ? height : old_height; y--; )
{
for(x = old_width; x--; )
{
qq->chars[y * width + x] = qq->chars[y * old_width + x];
qq->attr[y * width + x] = qq->attr[y * old_width + x];
}

/* Zero the end of the line */
for(x = width - old_width; x--; )
qq->chars[y * width + old_width + x] = (uint32_t)' ';
memset(qq->attr + y * width + old_width, 0,
width - old_width);
}
}
else
{
/* New width is smaller. Copy as many lines as possible. Ignore
* the first line, it is already in place. */
unsigned int lines = height < old_height ? height : old_height;

for(y = 1; y < lines; y++)
{
for(x = 0; x < width; x++)
{
qq->chars[y * width + x] = qq->chars[y * old_width + x];
qq->attr[y * width + x] = qq->attr[y * old_width + x];
}
}
}

/* Step 3: fill the bottom of the new screen if necessary. */
if(height > old_height)
{
/* Zero the bottom of the screen */
for(x = (height - old_height) * width; x--; )
qq->chars[old_height * width + x] = (uint32_t)' ';
memset(qq->attr + old_height * width, 0,
(height - old_height) * width);
}

/* Step 4: if new area is smaller, resize memory area now. */
if(new_size <= old_size)
{
qq->chars = realloc(qq->chars, new_size * sizeof(uint32_t));
qq->attr = realloc(qq->attr, new_size * sizeof(uint8_t));
}

/* Recompute the scratch line and the empty line */
if(width != old_width)
{
qq->empty_line = realloc(qq->empty_line, width + 1);
memset(qq->empty_line, ' ', width);
qq->empty_line[width] = '\0';

qq->scratch_line = realloc(qq->scratch_line, width + 1);
}
}


Loading…
Откажи
Сачувај