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

📄 draw.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * draw.c * Copyright (C) 1998-2005 A.J. van Os; Released under GPL * * Description: * Functions to deal with the Draw format */#include <stdlib.h>#include <ctype.h>#include <string.h>#include "DeskLib:KeyCodes.h"#include "DeskLib:Error.h"#include "DeskLib:Menu.h"#include "DeskLib:Template.h"#include "DeskLib:Window.h"#include "DeskLib:EventMsg.h"#include "flexlib:flex.h"#include "drawfile.h"#include "antiword.h"/* The work area must be a little bit larger than the diagram */#define WORKAREA_EXTENSION	    5/* Diagram memory */#define INITIAL_SIZE		32768	/* 32k */#define EXTENSION_SIZE		 4096	/*  4k *//* Main window title */#define WINDOW_TITLE_LEN	   28#define FILENAME_TITLE_LEN	(WINDOW_TITLE_LEN - 10)#if !defined(__GNUC__)intflex_alloc(flex_ptr anchor, int n){	void	*pvTmp;	TRACE_MSG("flex_alloc");	if (anchor == NULL || n < 0) {		return 0;	}	if (n == 0) {		n = 1;	}	pvTmp = malloc(n);	if (pvTmp == NULL) {		return 0;	}	*anchor = pvTmp;	return 1;} /* end of flex_alloc */voidflex_free(flex_ptr anchor){	TRACE_MSG("flex_free");	if (anchor == NULL || *anchor == NULL) {		return;	}	free(*anchor);	*anchor = NULL;} /* end of flex_free */intflex_extend(flex_ptr anchor, int newsize){	void	*pvTmp;	TRACE_MSG("flex_extend");	if (anchor == NULL || newsize < 0) {		return 0;	}	if (newsize == 0) {		newsize = 1;	}	pvTmp = realloc(*anchor, newsize);	if (pvTmp == NULL) {		return 0;	}	*anchor = pvTmp;	return 1;} /* end of flex_extend */#endif /* !__GNUC__ *//* * vCreateMainWindow - create the Main window * * remark: does not return if the Main window can't be created */static window_handletCreateMainWindow(void){	window_handle	tMainWindow;	TRACE_MSG("tCreateMainWindow");	tMainWindow = Window_Create("MainWindow", template_TITLEMIN);	if (tMainWindow == 0) {		werr(1, "I can't find the 'MainWindow' template");	}	return tMainWindow;} /* end of tCreateMainWindow *//* * vCreateScaleWindow - create the Scale view window * * remark: does not return if the Scale view window can't be created */static window_handletCreateScaleWindow(void){	window_handle	tScaleWindow;	TRACE_MSG("tCreateScaleWindow");	tScaleWindow = Window_Create("ScaleView", template_TITLEMIN);	if (tScaleWindow == 0) {		werr(1, "I can't find the 'ScaleView' template");	}	return tScaleWindow;} /* end of tCreateScaleWindow *//* * pCreateDiagram - create and initialize a diagram * * remark: does not return if the diagram can't be created */diagram_type *pCreateDiagram(const char *szTask, const char *szFilename){	diagram_type	*pDiag;	options_type	tOptions;	window_handle	tMainWindow, tScaleWindow;	wimp_box	tBox;	TRACE_MSG("pCreateDiagram");	fail(szTask == NULL || szTask[0] == '\0');	/* Create the main window */	tMainWindow = tCreateMainWindow();	/* Create the scale view window */	tScaleWindow = tCreateScaleWindow();	/* Get the necessary memory */	pDiag = xmalloc(sizeof(diagram_type));	if (flex_alloc((flex_ptr)&pDiag->tInfo.data, INITIAL_SIZE) != 1) {		werr(1, "Memory allocation failed, unable to continue");	}	/* Initialize the diagram */	vGetOptions(&tOptions);	pDiag->tMainWindow = tMainWindow;	pDiag->tScaleWindow = tScaleWindow;	pDiag->iScaleFactorCurr = tOptions.iScaleFactor;	pDiag->iScaleFactorTemp = tOptions.iScaleFactor;	pDiag->tMemorySize = INITIAL_SIZE;	tBox.min.x = 0;	tBox.min.y = -(Drawfile_ScreenToDraw(32 + 3) * 8 + 1);	tBox.max.x = Drawfile_ScreenToDraw(16) * MIN_SCREEN_WIDTH + 1;	tBox.max.y = 0;	Error_CheckFatal(Drawfile_CreateDiagram(&pDiag->tInfo,					pDiag->tMemorySize, szTask, tBox));	DBG_DEC(pDiag->tInfo.length);	pDiag->lXleft = 0;	pDiag->lYtop = 0;	strncpy(pDiag->szFilename,			szBasename(szFilename), sizeof(pDiag->szFilename) - 1);	pDiag->szFilename[sizeof(pDiag->szFilename) - 1] = '\0';	/* Return success */	return pDiag;} /* end of pCreateDiagram *//* * bDestroyDiagram - remove a diagram by freeing the memory it uses */BOOLbDestroyDiagram(event_pollblock *pEvent, void *pvReference){	diagram_type	*pDiag;	window_handle	tWindow;	TRACE_MSG("bDestroyDiagram");	fail(pEvent == NULL);	fail(pvReference == NULL);	if (pEvent == NULL || pvReference == NULL) {		return FALSE;	}	pDiag = (diagram_type *)pvReference;	switch (pEvent->type) {	case event_CLOSE:		tWindow = pEvent->data.openblock.window;		break;	case event_KEY:		tWindow = pEvent->data.key.caret.window;		break;	default:		DBG_DEC(pEvent->type);		return FALSE;	}	if (tWindow != pDiag->tMainWindow) {		return FALSE;	}	/* Delete the main window */	Window_Delete(pDiag->tMainWindow);	pDiag->tMainWindow = 0;	/* Delete the scale window */	Window_Delete(pDiag->tScaleWindow);	pDiag->tScaleWindow = 0;#if defined(__GNUC__)	/*	 * Remove all references to the diagram that will be free-ed	 * by undoing the EventMsg_Claim's from within the Menu_Warn's	 */	while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY,					bSaveTextfile, pDiag))		; /* EMPTY */	while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY,					bSaveDrawfile, pDiag))		; /* EMPTY */	while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY,					bScaleOpenAction, pDiag))		; /* EMPTY */#endif /* __GNUC__ */	/* Free the memory */	if (pDiag->tInfo.data != NULL && pDiag->tMemorySize != 0) {		flex_free((flex_ptr)&pDiag->tInfo.data);	}	/* Just to be on the save side */	pDiag->tInfo.data = NULL;	pDiag->tInfo.length = 0;	pDiag->tMemorySize = 0;	/* Destroy the diagram itself */	pDiag = xfree(pDiag);	return TRUE;} /* end of bDestroyDiagram *//* * vExtendDiagramSize - make sure the diagram is big enough */static voidvExtendDiagramSize(diagram_type *pDiag, size_t tSize){	TRACE_MSG("vExtendDiagramSize");	fail(pDiag == NULL || tSize % 4 != 0);	while (pDiag->tInfo.length + tSize > pDiag->tMemorySize) {		if (flex_extend((flex_ptr)&pDiag->tInfo.data,				pDiag->tMemorySize + EXTENSION_SIZE) != 1) {			werr(1, "Memory extend failed, unable to continue");		}		pDiag->tMemorySize += EXTENSION_SIZE;		NO_DBG_DEC(pDiag->tMemorySize);	}	TRACE_MSG("end of vExtendDiagramSize");} /* end of vExtendDiagramSize *//* * vPrologue2 - prologue part 2; add a font list to a diagram */voidvPrologue2(diagram_type *pDiag, int iWordVersion){	drawfile_object	*pNew;	const font_table_type	*pTmp;	char	*pcTmp;	size_t	tRealSize, tSize;	int	iCount;	TRACE_MSG("vPrologue2");	fail(pDiag == NULL);	if (tGetFontTableLength() == 0) {		return;	}	tRealSize = offsetof(drawfile_object, data);	pTmp = NULL;	while ((pTmp = pGetNextFontTableRecord(pTmp)) != NULL) {		tRealSize += 2 + strlen(pTmp->szOurFontname);	}	DBG_DEC(tRealSize);	tSize = ROUND4(tRealSize);	vExtendDiagramSize(pDiag, tSize);	pNew = xmalloc(tSize);	memset(pNew, 0, tSize);	pNew->type = drawfile_TYPE_FONT_TABLE;	pNew->size = tSize;	pcTmp = (char *)&pNew->data.font_table.font_def[0].font_ref;	iCount = 0;	pTmp = NULL;	while ((pTmp = pGetNextFontTableRecord(pTmp)) != NULL) {		*pcTmp = ++iCount;		pcTmp++;		strcpy(pcTmp, pTmp->szOurFontname);		pcTmp += 1 + strlen(pTmp->szOurFontname);	}	Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo,			pDiag->tMemorySize, pNew, TRUE));	pNew = xfree(pNew);} /* end of vPrologue2 *//* * vSubstring2Diagram - put a sub string into a diagram */voidvSubstring2Diagram(diagram_type *pDiag,	char *szString, size_t tStringLength, long lStringWidth,	UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef,	USHORT usFontSize, USHORT usMaxFontSize){	drawfile_object	*pNew;	long	lSizeX, lSizeY, lOffset, l20, lYMove;	size_t	tRealSize, tSize;	TRACE_MSG("vSubstring2Diagram");	fail(pDiag == NULL || szString == NULL);	fail(pDiag->lXleft < 0);	fail(tStringLength != strlen(szString));	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);	fail(usMaxFontSize < MIN_FONT_SIZE || usMaxFontSize > MAX_FONT_SIZE);	fail(usFontSize > usMaxFontSize);	if (szString[0] == '\0' || tStringLength == 0) {		return;	}	if (tFontRef == 0) {		lOffset = Drawfile_ScreenToDraw(2);		l20 = Drawfile_ScreenToDraw(32 + 3);		lSizeX = Drawfile_ScreenToDraw(16);		lSizeY = Drawfile_ScreenToDraw(32);	} else {		lOffset = lToBaseLine(usMaxFontSize);		l20 = lWord2DrawUnits20(usMaxFontSize);		lSizeX = lWord2DrawUnits00(usFontSize);		lSizeY = lWord2DrawUnits00(usFontSize);	}	lYMove = 0;	/* Up for superscript */	if (bIsSuperscript(usFontstyle)) {		lYMove = lMilliPoints2DrawUnits((((long)usFontSize + 1) / 2) * 375);	}	/* Down for subscript */	if (bIsSubscript(usFontstyle)) {		lYMove = -lMilliPoints2DrawUnits((long)usFontSize * 125);	}	tRealSize = offsetof(drawfile_object, data);	tRealSize += sizeof(drawfile_text) + tStringLength;	tSize = ROUND4(tRealSize);	vExtendDiagramSize(pDiag, tSize);	pNew = xmalloc(tSize);	memset(pNew, 0, tSize);	pNew->type = drawfile_TYPE_TEXT;	pNew->size = tSize;	pNew->data.text.bbox.min.x = (int)pDiag->lXleft;	pNew->data.text.bbox.min.y = (int)(pDiag->lYtop + lYMove);	pNew->data.text.bbox.max.x = (int)(pDiag->lXleft + lStringWidth);	pNew->data.text.bbox.max.y = (int)(pDiag->lYtop + l20 + lYMove);	pNew->data.text.fill.value = (int)ulColor2Color(ucFontColor);	pNew->data.text.bg_hint.value = 0xffffff00;	/* White */	pNew->data.text.style.font_ref = tFontRef;	pNew->data.text.style.reserved[0] = 0;	pNew->data.text.style.reserved[1] = 0;	pNew->data.text.style.reserved[2] = 0;	pNew->data.text.xsize = (int)lSizeX;	pNew->data.text.ysize = (int)lSizeY;	pNew->data.text.base.x = (int)pDiag->lXleft;	pNew->data.text.base.y = (int)(pDiag->lYtop + lOffset + lYMove);	strncpy(pNew->data.text.text, szString, tStringLength);	pNew->data.text.text[tStringLength] = '\0';	Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo,			pDiag->tMemorySize, pNew, TRUE));	pNew = xfree(pNew);	/*draw_translateText(&pDiag->tInfo);*/	pDiag->lXleft += lStringWidth;	TRACE_MSG("leaving vSubstring2Diagram");} /* end of vSubstring2Diagram *//* * vImage2Diagram - put an image into a diagram */voidvImage2Diagram(diagram_type *pDiag, const imagedata_type *pImg,	UCHAR *pucImage, size_t tImageSize){  	drawfile_object	*pNew;	long	lWidth, lHeight;	size_t	tRealSize, tSize;	TRACE_MSG("vImage2Diagram");	fail(pDiag == NULL);	fail(pImg == NULL);	fail(pDiag->lXleft < 0);	fail(pImg->eImageType != imagetype_is_dib &&	     pImg->eImageType != imagetype_is_jpeg);	DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);	lWidth = lPoints2DrawUnits(pImg->iHorSizeScaled);	lHeight = lPoints2DrawUnits(pImg->iVerSizeScaled);	DBG_DEC(lWidth);	DBG_DEC(lHeight);	pDiag->lYtop -= lHeight;	tRealSize = offsetof(drawfile_object, data);	switch (pImg->eImageType) {	case imagetype_is_dib:		tRealSize += sizeof(drawfile_sprite) + tImageSize;		tSize = ROUND4(tRealSize);		vExtendDiagramSize(pDiag, tSize);		pNew = xmalloc(tSize);		memset(pNew, 0, tSize);		pNew->type = drawfile_TYPE_SPRITE;		pNew->size = tSize;		pNew->data.sprite.bbox.min.x = (int)pDiag->lXleft;		pNew->data.sprite.bbox.min.y = (int)pDiag->lYtop;		pNew->data.sprite.bbox.max.x = (int)(pDiag->lXleft + lWidth);		pNew->data.sprite.bbox.max.y = (int)(pDiag->lYtop + lHeight);		memcpy(&pNew->data.sprite.header, pucImage, tImageSize);		break;	case imagetype_is_jpeg:#if defined(DEBUG)		(void)bGetJpegInfo(pucImage, tImageSize);#endif /* DEBUG */		tRealSize += sizeof(drawfile_jpeg) + tImageSize;		tSize = ROUND4(tRealSize);		vExtendDiagramSize(pDiag, tSize);		pNew = xmalloc(tSize);		memset(pNew, 0, tSize);		pNew->type = drawfile_TYPE_JPEG;		pNew->size = tSize;		pNew->data.jpeg.bbox.min.x = (int)pDiag->lXleft;		pNew->data.jpeg.bbox.min.y = (int)pDiag->lYtop;		pNew->data.jpeg.bbox.max.x = (int)(pDiag->lXleft + lWidth);		pNew->data.jpeg.bbox.max.y = (int)(pDiag->lYtop + lHeight);		pNew->data.jpeg.width = (int)lWidth;		pNew->data.jpeg.height = (int)lHeight;		pNew->data.jpeg.xdpi = 90;		pNew->data.jpeg.ydpi = 90;		pNew->data.jpeg.trfm.entries[0][0] = 0x10000;		pNew->data.jpeg.trfm.entries[0][1] = 0;		pNew->data.jpeg.trfm.entries[1][0] = 0;		pNew->data.jpeg.trfm.entries[1][1] = 0x10000;		pNew->data.jpeg.trfm.entries[2][0] = (int)pDiag->lXleft;		pNew->data.jpeg.trfm.entries[2][1] = (int)pDiag->lYtop;		pNew->data.jpeg.len = tImageSize;		memcpy(pNew->data.jpeg.data, pucImage, tImageSize);		break;	default:		DBG_DEC(pImg->eImageType);		pNew = NULL;		break;	}	Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo,					pDiag->tMemorySize, pNew, TRUE));	pNew = xfree(pNew);	pDiag->lXleft = 0;} /* end of vImage2Diagram *//* * bAddDummyImage - add a dummy image * * return TRUE when successful, otherwise FALSE */BOOLbAddDummyImage(diagram_type *pDiag, const imagedata_type *pImg){  	drawfile_object	*pNew;	int	*piTmp;	long	lWidth, lHeight;	size_t	tRealSize, tSize;	TRACE_MSG("bAddDummyImage");	fail(pDiag == NULL);	fail(pImg == NULL);	fail(pDiag->lXleft < 0);	if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) {		return FALSE;	}	DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);	lWidth = lPoints2DrawUnits(pImg->iHorSizeScaled);	lHeight = lPoints2DrawUnits(pImg->iVerSizeScaled);	pDiag->lYtop -= lHeight;	tRealSize = offsetof(drawfile_object, data);	tRealSize += sizeof(drawfile_path) + (14 - 1) * sizeof(int);	tSize = ROUND4(tRealSize);	vExtendDiagramSize(pDiag, tSize);	pNew = xmalloc(tSize);	memset(pNew, 0, tSize);	pNew->type = drawfile_TYPE_PATH;	pNew->size = tSize;	pNew->data.path.bbox.min.x = (int)pDiag->lXleft;	pNew->data.path.bbox.min.y = (int)pDiag->lYtop;	pNew->data.path.bbox.max.x = (int)(pDiag->lXleft + lWidth);	pNew->data.path.bbox.max.y = (int)(pDiag->lYtop + lHeight);	pNew->data.path.fill.value = -1;

⌨️ 快捷键说明

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