view tools/libgutil.c @ 2298:b5abfff07ca9

Add new DMGrowBuf helper functions dmGrowBufCopyOffsSize() and dmGrowBufConstCopyOffsSize().
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 04 Jul 2019 10:54:16 +0300
parents ef08af6887b7
children 6d12670e0248
line wrap: on
line source

/*
 * Common graphics utility functions for tools
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2012-2015 Tecnic Software productions (TNSP)
 *
 * Please read file 'COPYING' for information on license and distribution.
 */
#include "libgutil.h"


void dmFillRect(SDL_Surface *screen, int x0, int y0, int x1, int y1, Uint32 col)
{
    SDL_Rect rc;
    rc.x = x0;
    rc.y = y0;
    rc.w = x1 - x0 + 1;
    rc.h = y1 - y0 + 1;
    SDL_FillRect(screen, &rc, col);
}


void dmDrawHLine(SDL_Surface *screen, int x0, int x1, int yc, const Uint32 col)
{
    const int bpp = screen->format->BytesPerPixel,
              cx0 = screen->clip_rect.x, cy0 = screen->clip_rect.y,
              cx1 = screen->clip_rect.x + screen->clip_rect.w - 1,
              cy1 = screen->clip_rect.y + screen->clip_rect.h - 1;

    DM_SWAP(int, x0, x1);
    if (yc < cy0|| yc > cy1 || x1 < cx0 || x0 > cx1) return;
    if (x0 < cx0) x0 = cx0;
    if (x1 > cx1) x1 = cx1;

    int x = x1 - x0 + 1;
    Uint8 *pix = ((Uint8 *) screen->pixels) + yc * screen->pitch + (x0 * bpp);
    switch (screen->format->BitsPerPixel)
    {
        case 8:
            while (x--)
                *pix++ = col;
            break;

        case 32:
            {
                Uint32 *p = (Uint32 *) pix;
                while (x--)
                    *p++ = col;
            }
            break;
    }
}


void dmDrawVLine(SDL_Surface *screen, int y0, int y1, int xc, const Uint32 col)
{
    const int bpp = screen->format->BytesPerPixel,
              pitch = screen->pitch / bpp,
              cx0 = screen->clip_rect.x, cy0 = screen->clip_rect.y,
              cx1 = screen->clip_rect.x + screen->clip_rect.w - 1,
              cy1 = screen->clip_rect.y + screen->clip_rect.h - 1;

    DM_SWAP(int, y0, y1);
    if (xc < cx0 || xc > cx1 || y1 < cy0 || y0 > cy1) return;
    if (y0 < cy0) y0 = cy0;
    if (y1 > cy1) y1 = cy1;

    int y = y1 - y0 + 1;
    Uint8 *pix = ((Uint8 *) screen->pixels) + y0 * screen->pitch + (xc * bpp);
    switch (screen->format->BitsPerPixel)
    {
        case 8:
            while (y--)
            {
                *pix = col;
                pix += pitch;
            }
            break;

        case 32:
            {
                Uint32 *p = (Uint32 *) pix;
                while (y--)
                {
                    *p = col;
                    p += pitch;
                }
            }
            break;
    }
}


void dmDrawBox3D(SDL_Surface *screen, int x0, int y0, int x1, int y1, Uint32 ucol, Uint32 dcol)
{
    dmDrawHLine(screen, x0    , x1 - 1, y0, ucol);
    dmDrawHLine(screen, x0 + 1, x1    , y1, dcol);

    dmDrawVLine(screen, y0    , y1 - 1, x0, ucol);
    dmDrawVLine(screen, y0 + 1, y1    , x1, dcol);
}


void dmFillBox3D(SDL_Surface *screen, int x0, int y0, int x1, int y1, Uint32 bgcol, Uint32 ucol, Uint32 dcol)
{
    SDL_Rect rc;

    rc.x = x0 + 1;
    rc.y = y0 + 1;
    rc.w = x1 - x0 - 1;
    rc.h = y1 - y0 - 1;
    SDL_FillRect(screen, &rc, bgcol);

    dmDrawBox3D(screen, x0, y0, x1, y1, ucol, dcol);
}


void dmDrawBMTextConstQ(SDL_Surface *screen, DMBitmapFont *font, int mode, int xc, int yc, const char *fmt)
{
    const char *ptr = fmt;
    DMUnscaledBlitFunc blit = dmGetUnscaledBlitFunc(font->glyphs->format, screen->format, mode);
    Uint8 *orig = font->glyphs->pixels;
    SDL_Surface surf;

    memcpy(&surf, font->glyphs, sizeof(SDL_Surface));

    while (*ptr)
    {
        int ch = toupper(*ptr++);

        if (ch == '_')
        {
            xc += 4;
            continue;
        }

        if (ch < font->maxglyph && ch != ' ')
        {
            DMBitmapGlyph *glyph = &font->glyphMap[ch];

            if (glyph->index >= 0)
            {
                surf.pixels = orig + glyph->index * font->gsize;
                surf.w = glyph->width;
                surf.h = glyph->height;

                blit(&surf, xc, yc, screen);
            }
        }
        xc += font->width;
    }
}


void dmDrawBMTextVAQ(SDL_Surface *screen, DMBitmapFont *font, int mode, int xc, int yc, const char *fmt, va_list ap)
{
    char tmp[512];
    vsnprintf(tmp, sizeof(tmp), fmt, ap);
    dmDrawBMTextConstQ(screen, font, mode, xc, yc, tmp);
}


void dmDrawBMTextQ(SDL_Surface *screen, DMBitmapFont *font, int mode, int xc, int yc, const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    dmDrawBMTextVAQ(screen, font, mode, xc, yc, fmt, ap);
    va_end(ap);
}