📄 gletable.c
字号:
/*
* Copyright (C) AU-System AB, 2000.
* All rights reserved.
*
* This software is covered by the license agreement between
* the end user and AU-System AB, and may be used and copied
* only in accordance with the terms of the said agreement.
*
* AU-System AB does not assume any responsibility or
* liability for any errors or inaccuracies in this
* software, or any consequential, incidental or indirect
* damage arising out of the use of the Generic Layout Engine
* software.
*/
#include "gletable.h"
#include "gleimage.h"
#include "gletext.h"
#include "aapigle.h"
#include "gledef.h"
#ifdef SUPPORT_TABLES
VOID* WIPAlloc(UINT32 size);
VOID WIPFree( VOID* memory );
BOOL GleCloseTableRenderX(GleElement* self, INT16 *xSum, INT16 *ySum, INT16 *ascentMax, INT16 *descenderMax, GleElementType *gleType, UINT16 *currentFontLineHeight, INT8 *myAlign, BOOL *myWrap, INT16 *columnLeftX, INT16 *columnWidth){
*gleType = CloseTable;
return FALSE;
}
GleElement *GleCloseTableConstruct(UINT8 viewId){
GleElement *self;
UINT32 chunkSize;
chunkSize = sizeof(GleElement);
self = (GleElement*)WIPAlloc(chunkSize);
self->chunkSize=chunkSize;
self->type=CloseTable;
#ifdef SUPPORT_PEN_NAVIGATION
self->Contains=&GleElementContains;
#endif
self->Draw=&GleElementDraw;
self->RenderX=&GleCloseTableRenderX;
self->RenderY=&GleElementRenderY;
self->Destruct=&GleElementDestruct;
#ifdef SUPPORT_KEY_NAVIGATION
self->IsMarkable=&GleElementIsMarkable;
#endif
self->Selected=&GleElementSelected;
return (GleElement*)self;
}
BOOL GleElementGetTableColInfo(const GleElement* self, INT16 *colWidth){
GleImage* myImagePtr;
GleText* myTextPtr;
INT16 textLineWidth=0;
const BYTE* p;
INT16 nbrChars;
INT16 nChars;
INT16 nBytes;
INT16 textNbrBytes;
switch (self->type) {
case CloseTable:
return FALSE;
break;
case Image:
myImagePtr = (GleImage*)self;
*colWidth = max(*colWidth, myImagePtr->bounds.extent.x + myImagePtr->hSpace + myImagePtr->hSpace );
return TRUE;
break;
case Text:
myTextPtr = (GleText*)self;
p=myTextPtr->text;
textLineWidth = GLEa_textFontWidth(myTextPtr->text, GLEa_strlen(myTextPtr->text), myTextPtr->format, myTextPtr->isLink);
if(textLineWidth > gle_cell_maxTextWidth) {
textNbrBytes = GLEa_sizeofNchars(myTextPtr->text,GLEa_strlen(myTextPtr->text));
textLineWidth=0;
while((p - ((BYTE*)myTextPtr->text))!=textNbrBytes){
nbrChars=GLEa_textFontWordWrap((GLE_STRING)p,gle_cell_maxTextWidth, myTextPtr->format, myTextPtr->isLink);
nChars = GLEa_strNbrCharsWithoutEndingSpaces((GLE_STRING)p,nbrChars);
nBytes = GLEa_sizeofNchars((GLE_STRING)p,nbrChars);
textLineWidth = max(textLineWidth, GLEa_textFontWidth((GLE_STRING)p,nChars, myTextPtr->format, myTextPtr->isLink));
p += nBytes;
}
textLineWidth = min(textLineWidth, gle_cell_maxTextWidth); /* Just in case... */
}
*colWidth = max(textLineWidth, *colWidth);
return TRUE;
break;
case Break:
return TRUE;
break;
default:
return FALSE;
break;
}
}
VOID GleTableDestruct(GleTable* self){
WIPFree(self->col);
WIPFree(self->colWidth);
WIPFree(self->title);
if(self->rowHeight)
WIPFree(self->rowHeight);
WIPFree(self);
}
VOID GleTableDraw(GleViewType* viewP, const GleTable* self) {
GlePointType pos;
/*
INT16 k;
for( k=0; k<self->noOfColumns; k++)
self->col[k].columnLeftX += GLE_SCREENTOPLEFTX - viewP->horizOffset;
for( k=0; k<self->noOfRows; k++)
self->row[k].rowTopY += GLE_SCREENTOPLEFTY - viewP->horizOffset;
*/
/* pos.x = viewP->viewBounds.topLeft.x; */
pos.x = self->bounds.topLeft.x - viewP->horizOffset;
/* pos.y = viewP->viewBounds.topLeft.y; */
pos.y = self->bounds.topLeft.y - viewP->vertOffset;
/*
for(k=0; k<self->noOfRows; k++){
self->rowHeight[k]=11;
}
for(k=0; k<self->noOfColumns; k++){
self->colWidth[k]=30;
}
self->noOfRows=2;
*/
GLEa_tableDraw(viewP->viewId, pos, self->title, self->noOfCells, self->noOfColumns, self->noOfRows, self->colWidth, self->rowHeight);
/*
for( k=0; k<self->noOfColumns; k++)
self->col[k].columnLeftX -= GLE_SCREENTOPLEFTX - viewP->horizOffset;
for( k=0; k<self->noOfRows; k++)
self->row[k].rowTopY -= GLE_SCREENTOPLEFTY - viewP->horizOffset;
*/
/*
GleRectangleType textBounds = self->bounds;
FntSetFont(boldFont);
textBounds.topLeft.x += GLE_SCREENTOPLEFTX - viewP->horizOffset;
textBounds.topLeft.y += GLE_SCREENTOPLEFTY - viewP->vertOffset;
GLEa_drawChars(&self->title,StrLen(&self->title), FALSE, (GleRectangleType*)&textBounds);
*/
}
BOOL GleTableRenderX(GleTable* self, INT16 *xSum, INT16 *ySum, INT16 *ascentMax, INT16 *descenderMax, GleElementType *gleType, UINT16 *currentFontLineHeight, INT8 *myAlign, BOOL *myWrap, INT16 *columnLeftX, INT16 *columnWidth, VOID* viewP) {
if(!*xSum)
{
INT16 cellYSum=0;
INT16 cellHeightMax=0;
GleElement* rowStart=0;
INT16 nbrObjects=0;
INT8 align=ALIGN_LEFT;
INT8 alignNext=ALIGN_LEFT;
BOOL wrap=TRUE;
INT16 xOffset=0;
GleText* multipleRowTextPtr=0;
GleElement* p=self->next;
GleElement* pTemp=p;
GleElement* firstTableDataPtr=0;
GleElement* p2;
BOOL rowFinished = FALSE;
UINT16 colNr=self->noOfColumns-1;
UINT16 k;
INT8 rowNr;
INT16 xOffsetMain;
*gleType = p->type;
*ySum += gle_cell_vBefore - gle_cell_vBetween;
/* Initialize the columnwidth to 20 pixels */
for( k=0; k< self->noOfColumns; k++)
self->colWidth[k] = gle_cell_defaultWidth;
self->noOfCells = 0;
self->noOfRows = 0;
/* Calculate the number of cells, number of rows and the columnwidths */
while (*gleType != CloseTable)
{
/* while more content in cell (gleType!=CloseTable && gleType!=TableData) */
while(GleElementGetTableColInfo(p, &self->colWidth[colNr]))
p=p->next;
*gleType = p->type;
if (*gleType==TableData)
self->noOfCells++;
/* Step over the CloseTable or TableData */
p=p->next;
if(!colNr)
self->noOfRows++;
colNr=(colNr+1)% self->noOfColumns;
}
/* Allocate array of TableRowDataType */
if(!self->rowHeight)
self->rowHeight = WIPAlloc(sizeof(INT16)*(self->noOfRows));
for( k=0; k< self->noOfRows; k++)
self->rowHeight[k] = 2;
rowNr = -1;
/* Calculate the total with of the table */
self->tableWidth = gle_cell_hBefore + gle_cell_hAfter - gle_cell_hBetween;
for( k=0; k< self->noOfColumns ; k++)
self->tableWidth += self->colWidth[k] + gle_cell_hBetween;
self->bounds.extent.x = min(*columnWidth, self->tableWidth);
switch (*myAlign)
{
case ALIGN_CENTER:
xOffsetMain=*columnLeftX+(*columnWidth - self->bounds.extent.x)/2;
break;
case ALIGN_RIGHT:
xOffsetMain=*columnLeftX+(*columnWidth - self->bounds.extent.x);
break;
default:
xOffsetMain=*columnLeftX;
break;
}
self->bounds.topLeft.x = *columnLeftX + xOffsetMain;
/* Set the Column's left x coordinate */
self->col[0].columnLeftX = self->bounds.topLeft.x+gle_cell_hBefore;
for( k=1; k< self->noOfColumns ; k++)
self->col[k].columnLeftX = self->col[k-1].columnLeftX + self->colWidth[k-1]+gle_cell_hBetween;
self->bounds.topLeft.y = *ySum;
cellYSum=*ySum;
colNr=self->noOfColumns-1;
p=pTemp;
*gleType = p->type;
/* Now render the table cell by cell... */
if (*gleType == TableData)
firstTableDataPtr = p;
while (*gleType != CloseTable)
{
while ((*gleType != TableData) && (*gleType != CloseTable)) /* while more content in cell (gleType!=CloseTable && gleType!=TableData) */
{
rowStart=p;
*ascentMax=0;
*descenderMax = 0;
nbrObjects=0;
while (p->RenderX(p, xSum, &cellYSum, ascentMax, descenderMax, gleType, currentFontLineHeight, &self->col[colNr].align, &wrap, &self->col[colNr].columnLeftX, &self->colWidth[colNr], viewP))
{
nbrObjects++;
p=p->next;
if(!p)
break;
}
switch (self->col[colNr].align)
{
case ALIGN_CENTER:
xOffset=self->col[colNr].columnLeftX+(self->colWidth[colNr]-*xSum)/2;
break;
case ALIGN_RIGHT:
xOffset=self->col[colNr].columnLeftX+(self->colWidth[colNr]-*xSum);
break;
default:
xOffset=self->col[colNr].columnLeftX;
break;
}
if (multipleRowTextPtr)
{
GleTextLastRowRenderY(multipleRowTextPtr, xSum, &self->col[colNr].align, ascentMax, descenderMax);
multipleRowTextPtr = 0;
}
p2=rowStart;
for ( k=0 ; k<nbrObjects ; k++)
{
p2->RenderY(p2, &xOffset, &cellYSum, ascentMax);
p2=p2->next;
}
if ((*gleType == Text) && p)
{
/* Save multipleRowTextPtr in case of multiple rows, and update descenderMax */
GleTextMultipleRowCheck((GleText*)p, xSum, &multipleRowTextPtr, descenderMax, columnWidth, xOffset);
if (multipleRowTextPtr)
p=p->next;
else
*xSum=0;
cellYSum+=*descenderMax + *ascentMax;
*descenderMax = 0;
*ascentMax = 0;
}
else
{
cellYSum+=*descenderMax + *ascentMax;
*descenderMax = 0;
*ascentMax = 0;
multipleRowTextPtr=0;
*xSum=0;
}
if (*gleType == Break)
p=p->next; /* Step over the object*/
}
/* Cell rendered */
if ((cellYSum-*ySum)>cellHeightMax)
cellHeightMax=cellYSum-*ySum;
colNr=(colNr+1)% self->noOfColumns;
/* If new row or end of table assign rowinfo */
if ((!colNr) || (*gleType==CloseTable) || (p->next->type==CloseTable))
{
if (firstTableDataPtr )
{
colNr=0;
while(firstTableDataPtr != p)
{
if (firstTableDataPtr->type == TableData)
colNr=(colNr+1)% self->noOfColumns;
firstTableDataPtr = firstTableDataPtr->next;
}
colNr=0;
}
firstTableDataPtr = p;
*ySum+=cellHeightMax+gle_cell_vBetween;
if(rowNr!=-1)
self->rowHeight[rowNr]=cellHeightMax;
rowNr++;
if(p->next)
if((p->next->type==CloseTable) && !colNr && (rowNr<self->noOfRows)) {
cellHeightMax=gle_cell_defaultHeight;
if(rowNr!=-1)
self->rowHeight[rowNr]=cellHeightMax;
*ySum+=cellHeightMax+gle_cell_vBetween;
}
cellHeightMax=gle_cell_defaultHeight;
}
if (*gleType==TableData)
{
cellYSum=*ySum;
p=p->next;
*gleType = p->type;
}
}
*ySum+=gle_cell_vAfter;
*gleType = Table;
*xSum = self->tableWidth;
}
return(FALSE);
}
GleElement *GleTableConstruct(UINT8 viewId, const WCHAR* title, INT8 myNoOfColumns, const CHAR* myAlign) {
GleTable *self;
INT32 n1;
UINT16 chunkSize;
INT16 k=0;
INT16 nullChar = 0;
if(title)
n1 = GLEa_sizeofString(title);
else
n1 = GLEa_sizeofString((WCHAR*)&nullChar);
self = (GleTable*)WIPAlloc(sizeof(GleTable));
self->col = WIPAlloc(sizeof(TableColDataType)*(myNoOfColumns));
self->colWidth = WIPAlloc(sizeof(INT16)*(myNoOfColumns));
self->title = WIPAlloc(n1);
chunkSize=sizeof(GleTable) + sizeof(TableColDataType)*(myNoOfColumns);
chunkSize+=sizeof(TableColDataType)*(myNoOfColumns);
chunkSize+=sizeof(INT16)*(myNoOfColumns);
self->noOfRows=0;
self->noOfColumns=myNoOfColumns;
self->chunkSize=chunkSize;
self->rowHeight = 0;
self->type=Table;
if (title)
GLEa_strcpyWchar2Gle(self->title, title);
else
GLEa_strcpyWchar2Gle(self->title, (WCHAR*)&nullChar);
if (myAlign)
{
while (myAlign[k] && (k<myNoOfColumns))
{
switch (myAlign[k])
{
case 'C':
self->col[k].align=ALIGN_CENTER;
break;
case 'R':
self->col[k].align=ALIGN_RIGHT;
break;
default:
self->col[k].align=ALIGN_LEFT;
break;
}
k++;
}
}
while (k<myNoOfColumns)
{
self->col[k].align=ALIGN_LEFT;
k++;
}
#ifdef SUPPORT_PEN_NAVIGATION
self->Contains=&GleElementContains;
#endif
self->Draw=&GleTableDraw;
self->RenderX=&GleTableRenderX;
self->RenderY=&GleElementRenderY;
self->Destruct=&GleTableDestruct;
#ifdef SUPPORT_KEY_NAVIGATION
self->IsMarkable=&GleElementIsMarkable;
#endif
self->Selected=&GleElementSelected;
return (GleElement*)self;
}
VOID GleTableDataDraw(const GleTableData* self) {
/*
if (myTableDataPtr->myTable)
{
WMLobject* self= (WMLobject*) myTableDataPtr->myTable;
WMLtableAtr* myTableAtrPtr = (WMLtableAtr*) MemHandleLock(self->h);
horisOffset = myTableAtrPtr->horisOffset;
MemHandleUnlock(self->h);
}
*/
/*
GleRectangleType r = self->bounds;
r.topLeft.x +=1+GLE_SCREENTOPLEFTX-viewP->horizOffset;
r.topLeft.y +=1+GLE_SCREENTOPLEFTY-viewP->vertOffset;
r.extent.x -=2;
r.extent.y -=2;
WinDrawRectangleFrame(1,(RectangleType*)&r);
*/
/*
Line(myTableDataPtr->bounds.topLeft.x, myTableDataPtr->bounds.topLeft.y, myTableDataPtr->bounds.topLeft.x+myTableDataPtr->bounds.extent.x, myTableDataPtr->bounds.topLeft.y);
r.topLeft.x -= horisOffset;
r.topLeft.y -= viewP->vertOffset;
RctDrawCorners(&r);
*/
}
BOOL GleTableDataRenderX(GleTableData* self, INT16 *xSum, INT16 *ySum, INT16 *ascentMax, INT16 *descenderMax, GleElementType *gleType, UINT16 *currentFontLineHeight, INT8 *myAlign, BOOL *myWrap, INT16 *columnLeftX, INT16 *columnWidth)
{
*gleType = self->type;
return (FALSE);
}
GleElement *GleTableDataConstruct(UINT8 viewId)
{
GleTableData* self;
UINT16 chunkSize = sizeof(GleTableData);
self = (GleTableData*)WIPAlloc(chunkSize);
self->type = TableData;
self->chunkSize = chunkSize;
#ifdef SUPPORT_PEN_NAVIGATION
self->Contains=&GleElementContains;
#endif
self->Draw=&GleTableDataDraw;
self->RenderX=&GleTableDataRenderX;
self->RenderY=&GleElementRenderY;
self->Destruct=&GleElementDestruct;
#ifdef SUPPORT_KEY_NAVIGATION
self->IsMarkable=&GleElementIsMarkable;
#endif
self->Selected=&GleElementSelected;
return (GleElement*)self;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -