📄 draw.c
字号:
/* * 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 + -