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

📄 gvwdib.cpp

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2000, Ghostgum Software Pty Ltd.  All rights reserved.
  
  This file is part of GSview.
  
  This program is distributed with NO WARRANTY OF ANY KIND.  No author
  or distributor accepts any responsibility for the consequences of using it,
  or for whether it serves any particular purpose or works at all, unless he
  or she says so in writing.  Refer to the GSview Free Public Licence 
  (the "Licence") for full details.
  
  Every copy of GSview must include a copy of the Licence, normally in a 
  plain ASCII text file named LICENCE.  The Licence grants you the right 
  to copy, modify and redistribute GSview, but only under certain conditions 
  described in the Licence.  Among other things, the Licence requires that 
  the copyright notice and this notice be preserved on all copies.
*/


// DIB.cpp: implementation of the CDIB class.

// To change this back to using MFC:
// Replace GFile with CFile
// Exception handling around CFile::Read
// CDC not HDC
// delete palette, brush etc, not DeleteObject

#define STRICT
#include <windows.h>
#include <windowsx.h>
extern "C" {
#include "gvcfile.h"
}
#include "gvwdib.h"



#ifdef NOTUSED
#include "stdafx.h"
#include "afxmt.h"
//#include "GSview.h"
#include "DIB.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#endif


// This code assumes that structures elements are PACKED 
// on byte boundaries.

static unsigned long dsc_arch = 0x00000001;  // to determine if we are little endian


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDIB::CDIB(void)
{
    m_palette = NULL;
    m_bitmap = NULL;
    m_colors = NULL;
    m_bits = NULL;
    m_valid = FALSE;
}

CDIB::~CDIB(void)
{
    CleanupAll();
}

DWORD
CDIB::GetDword(LPBYTE pbyte)
{
    if (m_little_endian)
        return (*(LPDWORD)pbyte);
    else
         return ( pbyte[0] | (pbyte[1]<<8) | (pbyte[2]<<16) | (pbyte[3]<<24) );
}

WORD
CDIB::GetWord(LPBYTE pbyte)
{
    if (m_little_endian)
        return (*(LPWORD)pbyte);
    else
        return (WORD)( pbyte[0] | (pbyte[1]<<8) );
}


void
CDIB::Draw(HDC hdc)
{
    Draw(hdc, 0, 0);
}

void CDIB::Draw(HDC hdc, int xOffset, int yOffset)
{
    if (!m_valid) {
	RECT rect;
	GetClipBox(hdc, &rect);
	FillRect(hdc, &rect, (HBRUSH)GetStockObject(LTGRAY_BRUSH));
	return;
    }

    Lock();

    ASSERT(m_valid);

    int palcount = PalCount();
    UINT fuColorUse = DIB_RGB_COLORS;
    DWORD caps = GetDeviceCaps(hdc, RASTERCAPS);

    if (!(caps & RC_STRETCHDIB)) {
	LPTSTR message = TEXT("Device doesn't support StretchDIBits");
	TextOut(hdc, 10, 10, message, lstrlen(message));
	Unlock();
	return;
    }

    if (caps & RC_PALETTE) {
	// palette device
	if ((palcount != 0) && m_palette) {
	    // bitmap has palette, so use it
	    fuColorUse = DIB_PAL_COLORS;
	}
    }
    
    if (fuColorUse == DIB_PAL_COLORS) {
	// device and bitmap both use a palette
	// create a special bitmap header with palette indices
	struct bmi_s {
	    BITMAPINFOHEADER h;
	    WORD pal_index[256];
	} bmi;
	HPALETTE old_palette;
	int i;

	bmi.h.biSize = sizeof(bmi.h);
	bmi.h.biWidth = m_bmp.bmp2.biWidth;
	bmi.h.biHeight = m_bmp.bmp2.biHeight;
	bmi.h.biPlanes = 1;
	bmi.h.biBitCount = m_bmp.bmp2.biBitCount;
	bmi.h.biCompression = 0;
	bmi.h.biSizeImage = 0;      /* default */
	bmi.h.biXPelsPerMeter = 0;  /* default */
	bmi.h.biYPelsPerMeter = 0;  /* default */
	bmi.h.biClrUsed = palcount;
	bmi.h.biClrImportant = palcount;
	for (i = 0; i < palcount; i++)
		bmi.pal_index[i] = (WORD)i;

	old_palette = SelectPalette(hdc, m_palette, FALSE);
	RealizePalette(hdc);
	
	SetStretchBltMode(hdc, COLORONCOLOR);
	StretchDIBits(hdc, xOffset, yOffset, 
	      m_bmp.bmp2.biWidth, m_bmp.bmp2.biHeight,
	      0, 0, m_bmp.bmp2.biWidth, m_bmp.bmp2.biHeight, 
	      m_bits, (BITMAPINFO *)&bmi, fuColorUse, SRCCOPY);

	SelectPalette(hdc, old_palette, FALSE);
    }
    else {
	// either device doesn't use palettes
	// or bitmap does use a colour table
	SetStretchBltMode(hdc, COLORONCOLOR);
// may need to modify target dimensions to allow print preview to work.
// At present, preview should work if bitmap is at printer resolution.
	StretchDIBits(hdc, xOffset, yOffset, 
	      m_bmp.bmp2.biWidth, m_bmp.bmp2.biHeight,
	      0, 0, m_bmp.bmp2.biWidth, m_bmp.bmp2.biHeight, 
	      m_bits, (BITMAPINFO *)&m_bmp, fuColorUse, SRCCOPY);
    }
    Unlock();
}

#ifdef NOTUSED
#ifdef _DEBUG
void CDIB::Dump(CDumpContext& dc) const
{
	dc << "DIB:\n";
	dc << " HeaderSize " << m_bmp.bmp2.biSize << "\n";
	dc << " Width " << m_bmp.bmp2.biWidth << "\n";
	dc << " Height " << m_bmp.bmp2.biHeight << "\n";
	dc << " Planes " << m_bmp.bmp2.biPlanes << "\n";
	dc << " BitCount " << m_bmp.bmp2.biBitCount << "\n";
	dc << " SizeImage " << m_bmp.bmp2.biSizeImage << "\n";
	dc << " XDPI " << m_bmp.bmp2.biXPelsPerMeter << "\n";
	dc << " YDPI " << m_bmp.bmp2.biYPelsPerMeter << "\n";
	dc << " ClrUsed " << m_bmp.bmp2.biClrUsed << "\n";
	dc << " ClrImportant " << m_bmp.bmp2.biClrImportant << "\n";
}
#endif
#endif

void
CDIB::DrawDump(HDC hdc)
{
    TEXTMETRIC tm;
    LOGFONT lf;
    HFONT font;
    int cyHeight;
    int cxLeftMargin;
    int x, y;
    TCHAR str[256];

    Lock();

    memset(&lf, 0, sizeof(lf));
    lf.lfHeight = 8;
    lstrcpy(lf.lfFaceName, TEXT("MS Sans Serif"));
    font = CreateFontIndirect(&lf);
    SelectObject(hdc, font);
    GetTextMetrics(hdc, &tm);
    cyHeight = tm.tmHeight + tm.tmExternalLeading;
    cxLeftMargin = tm.tmAveCharWidth * 2;
    x = cxLeftMargin;
    y = cyHeight;
    wsprintf(str, 
	TEXT("HeaderSize=%d   Width=%d   Height=%d   Planes=%d   BitCount=%d"),
	m_bmp.bmp2.biSize, m_bmp.bmp2.biWidth, m_bmp.bmp2.biHeight,
	(int)m_bmp.bmp2.biPlanes, (int)m_bmp.bmp2.biBitCount);
    TextOut(hdc,x, y, str, lstrlen(str));
    y+= cyHeight;
    wsprintf(str, 
        TEXT("SizeImage=%d   XDPI=%d   YDPI=%d   ClrUsed=%d   ClrImportant=%d"),
	m_bmp.bmp2.biSizeImage, 
	m_bmp.bmp2.biXPelsPerMeter, m_bmp.bmp2.biYPelsPerMeter,
	m_bmp.bmp2.biClrUsed, m_bmp.bmp2.biClrImportant);
    TextOut(hdc, x, y, str, lstrlen(str));
    Unlock();
}


BOOL
CDIB::MakePalette(void)
{
    // Make a palette if needed
    int i;
    int pcount = PalCount();
    LPLOGPALETTE logpalette;
    LPBYTE p = m_colors;
    if (m_palette) {
	DeletePalette(m_palette);
	m_palette = NULL;
    }

    if (pcount == 0)
	return TRUE;

    logpalette = new LOGPALETTE[pcount];
    logpalette->palVersion = 0x300;
    logpalette->palNumEntries = (WORD)pcount;
    for (i = 0; i < pcount; i++) {
	m_bmp.rgb4[i].rgbReserved = logpalette->palPalEntry[i].peFlags = 0;
	m_bmp.rgb4[i].rgbBlue  = logpalette->palPalEntry[i].peBlue  = *p++;
	m_bmp.rgb4[i].rgbGreen = logpalette->palPalEntry[i].peGreen = *p++;
	m_bmp.rgb4[i].rgbRed   = logpalette->palPalEntry[i].peRed   = *p++;
	if (!m_old)
	    p++;
    }
    
    m_palette = CreatePalette(logpalette);
    delete [] logpalette;
    return (m_palette != NULL);
}

void CDIB::CleanupPalette(void)
{
    if (m_palette) {
	DeletePalette(m_palette);
	m_palette = NULL;
	m_valid = FALSE;
    }
}

void CDIB::CleanupBitmap(void)
{
    if (m_bitmap) {
	HGLOBAL hglobal = GlobalHandle(m_bitmap);
	GlobalUnlock(hglobal);
	GlobalFree(hglobal);
	m_bitmap = NULL;
	m_valid = FALSE;
    }
}

void CDIB::CleanupAll(void)
{
    m_valid = FALSE;
    CleanupPalette();
    CleanupBitmap();
}


void CDIB::Release(void)
{
    Lock();
    CleanupAll();
    Unlock();
}

void CDIB::Init(void)
{
    Lock();
    CleanupAll();
    Unlock();
}


BOOL CDIB::Init(HGLOBAL hglobal)
{
    Lock();
    CleanupAll();
    // We are now responsible for freeing this memory
    m_bitmap = (LPBYTE)GlobalLock(hglobal);
    BOOL flag = Init(m_bitmap);
    Unlock();
    return flag;
}

BOOL 
CDIB::Init(LPBYTE pbmp, LPBYTE pbits)
{
    Lock();
    BOOL flag = Init(pbmp);
    m_bits =  pbits;
    Unlock();
    return flag;
}

BOOL 
CDIB::Init(LPBYTE pbmp)
{
    Lock();
    
    CleanupPalette();

    m_little_endian = (*((char *)(&dsc_arch))) == 1;
    m_bmp.bmp2.biSize = GetDword(pbmp);
    pbmp += 4;
    if (m_bmp.bmp2.biSize > 12) {
	// new bitmap
	m_old = FALSE;
	m_bmp.bmp2.biWidth = GetDword(pbmp);
        pbmp += 4;
	m_bmp.bmp2.biHeight = GetDword(pbmp);
        pbmp += 4;
	m_bmp.bmp2.biPlanes = GetWord(pbmp);
        pbmp += 2;
	m_bmp.bmp2.biBitCount = GetWord(pbmp);
        pbmp += 2;
	m_bmp.bmp2.biCompression = GetDword(pbmp);
        pbmp += 4;
	m_bmp.bmp2.biSizeImage = GetDword(pbmp);
        pbmp += 4;
	m_bmp.bmp2.biXPelsPerMeter = GetDword(pbmp);
        pbmp += 4;
	m_bmp.bmp2.biYPelsPerMeter = GetDword(pbmp);
        pbmp += 4;
	m_bmp.bmp2.biClrUsed = GetDword(pbmp);
        pbmp += 4;
	m_bmp.bmp2.biClrImportant = GetDword(pbmp);
        pbmp += 4;
	m_bytewidth = (( m_bmp.bmp2.biWidth * m_bmp.bmp2.biBitCount + 31) 
			& ~31) >> 3;
        m_colors = pbmp;
	pbmp += PalLength();
	m_bits =  pbmp;
    }
    else {
	// old bitmap
	m_old = TRUE;
	m_bmp.bmp2.biWidth = GetWord(pbmp);
        pbmp += 2;
	m_bmp.bmp2.biHeight = GetWord(pbmp);
        pbmp += 2;
	m_bmp.bmp2.biPlanes = GetWord(pbmp);
        pbmp += 2;
	m_bmp.bmp2.biBitCount = GetWord(pbmp);
        pbmp += 2;
	m_bmp.bmp2.biCompression = 0;
	m_bmp.bmp2.biSizeImage = 0;
	m_bmp.bmp2.biXPelsPerMeter = 72;
	m_bmp.bmp2.biYPelsPerMeter = 72;
	m_bmp.bmp2.biClrUsed = 0;
	m_bmp.bmp2.biClrImportant = 0;
	m_bytewidth = (( m_bmp.bmp2.biWidth * m_bmp.bmp2.biBitCount + 31) 
	 		   & ~31) >> 3;
        m_colors = pbmp;
	pbmp += PalLength();
	m_bits =  pbmp;
    }
    m_valid = MakePalette();

    Unlock();
    return m_valid;
}


/* number of colours in colour table */
UINT
CDIB::PalCount(void)
{
    if (m_old) {
	// old bitmap
	if (m_bmp.bmp2.biBitCount == 24)
		return 0;
	return 1 << (m_bmp.bmp2.biBitCount * m_bmp.bmp2.biPlanes);
    }

    // new bitmap
    switch (m_bmp.bmp2.biBitCount) {
	case 16:
	case 24:
	case 32:
	    return 0;
	case 1:
	case 4:
	case 8:
	    return (m_bmp.bmp2.biClrUsed > 0 ? (UINT)m_bmp.bmp2.biClrUsed :
		1 << (m_bmp.bmp2.biBitCount * m_bmp.bmp2.biPlanes));
    }
    // unsupported bitmap format
    return 0;	// should throw an exception
}


// length of colour table in bytes
UINT 
CDIB::PalLength(void)
{
    if ((m_bmp.bmp2.biBitCount == 16) || (m_bmp.bmp2.biBitCount == 32)) {
	if (m_bmp.bmp2.biCompression == BI_BITFIELDS)
	    return 12;	// 3 * DWORD
	return 0;	/* default bit fields */
    }
    return PalCount() * (m_old ? 3 : 4);
}


// pointer to bitmap bits
LPBYTE 
CDIB::GetBits(void)
{
    ASSERT(m_valid);
    if (!m_valid)
	return 0;
    return m_bits;
}

// width of bitmap row in bytes

⌨️ 快捷键说明

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