⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 surface.c

📁 libminigui-1.3.0.tar.gz。 miniGUI的库函数源代码!
💻 C
📖 第 1 页 / 共 3 页
字号:
    return 0;}static int _PutBoxKey (GAL_Surface* dst, BYTE* dstrow, BYTE* srcrow, Uint32 w, Uint32 h, BITMAP* box){    BYTE* dstpixels = dstrow;    BYTE* srcpixels = srcrow;    Uint32 ckey = box->bmColorKey;    GAL_PixelFormat *dstfmt = dst->format;    int bpp = dstfmt->BytesPerPixel;    unsigned alpha = dstfmt->Amask ? GAL_ALPHA_OPAQUE : 0;    if (bpp == 1) {        while (h--) {            int i;            dstpixels = dstrow;            srcpixels = srcrow;            for (i = 0; i < w; i++) {                if (*srcpixels != ckey)                    *dstpixels = *srcpixels;                dstpixels += bpp;                srcpixels += bpp;            }            srcrow += box->bmPitch;            dstrow += dst->pitch;        }    }    else while ( h-- ) {        dstpixels = dstrow;        srcpixels = srcrow;        DUFFS_LOOP(        {            Uint32 pixel;            unsigned sR;            unsigned sG;            unsigned sB;            RETRIEVE_RGB_PIXEL (srcpixels, bpp, pixel);            if ( pixel != ckey ) {                RGB_FROM_PIXEL (pixel, dstfmt, sR, sG, sB);                ASSEMBLE_RGBA (dstpixels, bpp, dstfmt, sR, sG, sB, alpha);            }            dstpixels += bpp;            srcpixels += bpp;        },        w);        srcrow += box->bmPitch;        dstrow += dst->pitch;    }    return 0;}static int _PutBoxKeyAlphaChannel (GAL_Surface* dst, BYTE* dstrow, BYTE* srcrow, Uint32 w, Uint32 h, BITMAP* box){    BYTE* dstpixels = dstrow;    BYTE* srcpixels = srcrow;    Uint32 ckey = box->bmColorKey;    GAL_PixelFormat *dstfmt = dst->format;    int bpp = dstfmt->BytesPerPixel;    unsigned alpha = box->bmAlpha;    if (bpp == 1)        return -1;    while ( h-- ) {        dstpixels = dstrow;        srcpixels = srcrow;        DUFFS_LOOP(        {            Uint32 pixel;            unsigned sR;            unsigned sG;            unsigned sB;            unsigned dR;            unsigned dG;            unsigned dB;            RETRIEVE_RGB_PIXEL (srcpixels, bpp, pixel);            if ( pixel != ckey ) {                RGB_FROM_PIXEL (pixel, dstfmt, sR, sG, sB);                DISEMBLE_RGB (dstpixels, bpp, dstfmt, pixel, dR, dG, dB);		        ALPHA_BLEND (sR, sG, sB, alpha, dR, dG, dB);                ASSEMBLE_RGBA (dstpixels, bpp, dstfmt, dR, dG, dB, alpha);            }            dstpixels += bpp;            srcpixels += bpp;        },        w);        srcrow += box->bmPitch;        dstrow += dst->pitch;    }    return 0;}int GAL_PutBox (GAL_Surface *dst, const GAL_Rect *dstrect, BITMAP* box){    Uint32 box_x, box_y, off_x, off_y;    int y, w, h;    Uint8 *srcrow, *dstrow;    Uint32 linelen;    GAL_Rect my_dstrect;    /* If 'dstrect' == NULL, then put to (0, 0) */    if (dstrect) {        box_x = dstrect->x;        box_y = dstrect->y;        /* Perform clipping */        if (!GAL_IntersectRect (dstrect, &dst->clip_rect, &my_dstrect)) {            return 0;        }    } else {        box_x = 0;        box_y = 0;        my_dstrect = dst->clip_rect;    }    off_x = my_dstrect.x - box_x;    off_y = my_dstrect.y - box_y;    if (off_x >= box->bmWidth || off_y >= box->bmHeight ||            box->bmBytesPerPixel != dst->format->BytesPerPixel) {        return 0;    }    dstrow = (Uint8 *)dst->pixels + my_dstrect.y * dst->pitch +            my_dstrect.x * dst->format->BytesPerPixel;    srcrow = (Uint8 *)box->bmBits + off_y * box->bmPitch +            off_x * box->bmBytesPerPixel;    w = MIN (my_dstrect.w, box->bmWidth);    h = MIN (my_dstrect.h, box->bmHeight);    linelen = w * box->bmBytesPerPixel;    /* TODO: Check for hardware acceleration here */#if 0    /* Perform software blitting */    if ( GAL_LockSurface (dst) != 0 ) {        return(-1);    }#endif    if (box->bmAlphaPixelFormat != NULL                     && box->bmAlphaPixelFormat != dst->format) {        if ((box->bmType & BMP_TYPE_ALPHA) && (box->bmType & BMP_TYPE_COLORKEY)) {            return _PutBoxKeyAlpha (dst, dstrow, srcrow, w, h, box);        }        else if (box->bmType & BMP_TYPE_ALPHA) {            return _PutBoxAlpha (dst, dstrow, srcrow, w, h, box);        }    }    else if ((box->bmType & BMP_TYPE_ALPHACHANNEL) && (box->bmType & BMP_TYPE_COLORKEY)) {        return _PutBoxKeyAlphaChannel (dst, dstrow, srcrow, w, h, box);    }    else if (box->bmType & BMP_TYPE_COLORKEY) {        return _PutBoxKey (dst, dstrow, srcrow, w, h, box);    }    else if (box->bmType & BMP_TYPE_ALPHACHANNEL) {        return _PutBoxAlphaChannel (dst, dstrow, srcrow, w, h, box);    }    switch (dst->format->BytesPerPixel) {        case 1:            if (((DWORD)srcrow & 3) || ((DWORD)dstrow & 3)                     || (linelen & 3) || (box->bmPitch & 3) || (dst->pitch & 3))                goto slow_copy;            else {                int n = linelen >> 2;                for (y = h; y; --y) {                    GAL_memcpy4 (dstrow, srcrow, n);                    srcrow += box->bmPitch;                    dstrow += dst->pitch;                }            }            break;        case 2:            if ((((DWORD)dstrow & 3) != ((DWORD)srcrow & 3))                     || (box->bmPitch & 3) || (dst->pitch & 3))                goto slow_copy;            for (y = h; y; --y) {                Uint16 *dstpixels = (Uint16 *)dstrow;                Uint16 *srcpixels = (Uint16 *)srcrow;                int n = w;                if ((DWORD)dstpixels & 3) {                    *dstpixels = *srcpixels;                    dstpixels++;                    srcpixels++;                    n--;                }                if (n >> 1)                    GAL_memcpy4 (dstpixels, srcpixels, n >> 1);                if (n & 1)                    dstpixels [n - 1] = srcpixels [n - 1];                srcrow += box->bmPitch;                dstrow += dst->pitch;            }            break;        case 3:            goto slow_copy;        case 4:            for (y = h; y; --y) {                GAL_memcpy4 (dstrow, srcrow, w);                srcrow += box->bmPitch;                dstrow += dst->pitch;            }            break;    }#if 0    GAL_UnlockSurface(dst);#endif    return 0;slow_copy:    for (y = h; y; --y) {        GAL_memcpy (dstrow, srcrow, linelen);        srcrow += box->bmPitch;        dstrow += dst->pitch;    }#if 0    GAL_UnlockSurface (dst);#endif    return 0;}#if 0/* * Lock a surface to directly access the pixels * -- Do not call this from any blit function, as GAL_DrawCursor() may recurse *    Instead, use: *    if ( (surface->flags & GAL_HWSURFACE) == GAL_HWSURFACE ) *               video->LockHWSurface(video, surface); */int GAL_LockSurface (GAL_Surface *surface){    if ( ! surface->locked ) {        /* Perform the lock */        if ( surface->flags & (GAL_HWSURFACE|GAL_ASYNCBLIT) ) {            GAL_VideoDevice *video = current_video;            GAL_VideoDevice *this  = current_video;            if ( video->LockHWSurface(this, surface) < 0 ) {                return(-1);            }        }        if ( surface->flags & GAL_RLEACCEL ) {            GAL_UnRLESurface(surface, 1);            surface->flags |= GAL_RLEACCEL;    /* save accel'd state */        }        /* This needs to be done here in case pixels changes value */        surface->pixels = (Uint8 *)surface->pixels + surface->offset;    }    /* Increment the surface lock count, for recursive locks */    ++surface->locked;    /* Ready to go.. */    return(0);}/* * Unlock a previously locked surface * -- Do not call this from any blit function, as GAL_DrawCursor() may recurse *    Instead, use: *    if ( (surface->flags & GAL_HWSURFACE) == GAL_HWSURFACE ) *               video->UnlockHWSurface(video, surface); */void GAL_UnlockSurface (GAL_Surface *surface){    return;    /* Only perform an unlock if we are locked */    if ( ! surface->locked || (--surface->locked > 0) ) {        return;    }    /* Perform the unlock */    surface->pixels = (Uint8 *)surface->pixels - surface->offset;    /* Unlock hardware or accelerated surfaces */    if ( surface->flags & (GAL_HWSURFACE|GAL_ASYNCBLIT) ) {        GAL_VideoDevice *video = current_video;        GAL_VideoDevice *this  = current_video;        video->UnlockHWSurface(this, surface);    } else {        /* Update RLE encoded surface with new data */        if ( (surface->flags & GAL_RLEACCEL) == GAL_RLEACCEL ) {                surface->flags &= ~GAL_RLEACCEL; /* stop lying */            GAL_RLESurface(surface);        }    }}#endif/*  * Convert a surface into the specified pixel format. */GAL_Surface * GAL_ConvertSurface (GAL_Surface *surface,                    GAL_PixelFormat *format, Uint32 flags){    GAL_Surface *convert;    Uint32 colorkey = 0;    Uint8 alpha = 0;    Uint32 surface_flags;    GAL_Rect bounds;    /* Check for empty destination palette! (results in empty image) */    if ( format->palette != NULL ) {        int i;        for ( i=0; i<format->palette->ncolors; ++i ) {            if ( (format->palette->colors[i].r != 0) ||                 (format->palette->colors[i].g != 0) ||                 (format->palette->colors[i].b != 0) )                break;        }        if ( i == format->palette->ncolors ) {            GAL_SetError("Empty destination palette");            return(NULL);        }    }    /* Create a new surface with the desired format */    convert = GAL_CreateRGBSurface(flags,                surface->w, surface->h, format->BitsPerPixel,        format->Rmask, format->Gmask, format->Bmask, format->Amask);    if ( convert == NULL ) {        return(NULL);    }    /* Copy the palette if any */    if ( format->palette && convert->format->palette ) {        memcpy(convert->format->palette->colors,                format->palette->colors,                format->palette->ncolors*sizeof(GAL_Color));        convert->format->palette->ncolors = format->palette->ncolors;    }    /* Save the original surface color key and alpha */    surface_flags = surface->flags;    if ( (surface_flags & GAL_SRCCOLORKEY) == GAL_SRCCOLORKEY ) {        /* Convert colourkeyed surfaces to RGBA if requested */        if((flags & GAL_SRCCOLORKEY) != GAL_SRCCOLORKEY           && format->Amask) {            surface_flags &= ~GAL_SRCCOLORKEY;        } else {            colorkey = surface->format->colorkey;            GAL_SetColorKey(surface, 0, 0);        }    }    if ( (surface_flags & GAL_SRCALPHA) == GAL_SRCALPHA ) {        alpha = surface->format->alpha;        GAL_SetAlpha(surface, 0, 0);    }    /* Copy over the image data */    bounds.x = 0;    bounds.y = 0;    bounds.w = surface->w;    bounds.h = surface->h;    GAL_LowerBlit(surface, &bounds, convert, &bounds);    /* Clean up the original surface, and update converted surface */    if ( convert != NULL ) {        GAL_SetClipRect(convert, &surface->clip_rect);    }    if ( (surface_flags & GAL_SRCCOLORKEY) == GAL_SRCCOLORKEY ) {        Uint32 cflags = surface_flags&(GAL_SRCCOLORKEY|GAL_RLEACCELOK);        if ( convert != NULL ) {            Uint8 keyR, keyG, keyB;            GAL_GetRGB(colorkey,surface->format,&keyR,&keyG,&keyB);            GAL_SetColorKey(convert, cflags|(flags&GAL_RLEACCELOK),                GAL_MapRGB(convert->format, keyR, keyG, keyB));        }        GAL_SetColorKey(surface, cflags, colorkey);    }    if ( (surface_flags & GAL_SRCALPHA) == GAL_SRCALPHA ) {        Uint32 aflags = surface_flags&(GAL_SRCALPHA|GAL_RLEACCELOK);        if ( convert != NULL ) {                GAL_SetAlpha(convert, aflags|(flags&GAL_RLEACCELOK),                alpha);        }        GAL_SetAlpha(surface, aflags, alpha);    }    /* We're ready to go! */    return(convert);}/* * Free a surface created by the above function. */void GAL_FreeSurface (GAL_Surface *surface){    /* Free anything that's not NULL, and not the screen surface */    if ((surface == NULL) ||        (current_video &&#if 0        ((surface == GAL_ShadowSurface)||(surface == GAL_VideoSurface)))) {#else        (surface == GAL_VideoSurface))) {#endif        return;    }    if ( --surface->refcount > 0 ) {        return;    }    if ( (surface->flags & GAL_RLEACCEL) == GAL_RLEACCEL ) {            GAL_UnRLESurface(surface, 0);    }    if ( surface->format ) {        GAL_FreeFormat(surface->format);        surface->format = NULL;    }    if ( surface->map != NULL ) {        GAL_FreeBlitMap(surface->map);        surface->map = NULL;    }    if ( (surface->flags & GAL_HWSURFACE) == GAL_HWSURFACE ) {        GAL_VideoDevice *video = current_video;        GAL_VideoDevice *this  = current_video;        video->FreeHWSurface(this, surface);    }    if ( surface->pixels &&         ((surface->flags & GAL_PREALLOC) != GAL_PREALLOC) ) {        free(surface->pixels);    }    free(surface);#ifdef CHECK_LEAKS    --surfaces_allocated;#endif}#ifdef _LITE_VERSIONvoid GAL_RequestHWSurface (const REQ_HWSURFACE* request, REP_HWSURFACE* reply){    if (current_video->RequestHWSurface) {        current_video->RequestHWSurface (current_video, request, reply);    }    else if (request->offset == 0) {        reply->offset = 0;    }}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -