|
|
1.1 root 1: #include <windows.h>
2: #include <windowsx.h>
3: #include <string.h>
4: #include "app.h"
5:
6: #include "grid.hxx"
7:
8: //+--------------------------------------------------------
9: // Class: CFontSelect
10: //
11: // Purpose: Select/Deselect a font
12: //
13: // History: 22-Jan-1993 asmusf created
14: //----------------------------------------------------------
15:
16: // pure inline
17:
18: //+--------------------------------------------------------
19: // Class: CGridIt
20: //
21: // Purpose: Iterate over a grid
22: //
23: // History: 22-Jan-1993 asmusf created
24: //----------------------------------------------------------
25:
26: // pure inline
27:
28: //+--------------------------------------------------------
29: // Class: CLineGrid
30: //
31: // Purpose: Create an n x m Grid of lines
32: //
33: // History: 22-Jan-1993 asmusf created
34: //----------------------------------------------------------
35:
36: CLineGrid::CLineGrid(UINT cCol, UINT cRow, SIZE size )
37: {
38: _size = size;
39: _cCol = cCol;
40: _cRow = cRow;
41: SetStyle();
42: SetWeight();
43: }
44:
45: void CLineGrid::SetStyle(int iStyle)
46: {
47: _iStyle = iStyle;
48: }
49:
50: void CLineGrid::SetWeight(int nWeight)
51: {
52: _nWeight = nWeight*20; // internal twips, API is points
53: }
54:
55: void CLineGrid::Paint(CCanvas& canvas, RECT rc, POINT pt)
56: {
57: int cx, cy;
58: UINT i;
59:
60: // set up pen
61: CBlackPen pen(canvas, _iStyle, _nWeight);
62:
63: // Draw the grid
64: for(cx = pt.x, i=0; i<=_cCol; i++, cx+=_size.cx )
65: {
66: if( cx >= rc.left && cx <= rc.right )
67: {
68: canvas.Line(cx, pt.y,
69: cx, pt.y+_cRow*_size.cy);
70: }
71: }
72: for(cy = pt.y, i=0; i<=_cRow; i++, cy+=_size.cy )
73: {
74: if( cy >= rc.top && cy <= rc.bottom )
75: {
76: canvas.Line(pt.x, cy,
77: pt.x+_cCol*_size.cx, cy);
78: }
79: }
80: }
81:
82: //+--------------------------------------------------------
83: // Class: CTextGrid
84: //
85: // Purpose: Create an n x m grid of textual elements
86: //
87: // History: 22-Jan-1993 asmusf created
88: //----------------------------------------------------------
89:
90: void CTextGrid::SetFont(HFONT hfont)
91: {
92: _font = hfont;
93: }
94:
95: void CTextGrid :: Paint(CCanvas& canvas, RECT rc, POINT pt)
96: {
97: // Choose text alignment
98: SetTextAlign(HDC(canvas), TA_BASELINE|TA_CENTER);
99:
100: CFontSelect fs(canvas, _font);
101:
102: for( CGridIt It( _cCol, _cRow, _size, pt ); !It.Done(); ++It)
103: {
104: if( It.Cx()+_size.cx > rc.left && It.Cx() < rc.right &&
105: It.Cy()+_size.cy > rc.top && It.Cy() < rc.bottom )
106: {
107: DrawElement(canvas, It.Cx()+_ptOrg.x, It.Cy()+_ptOrg.y,
108: It.Col(), It.Row());
109: }
110: }
111: }
112:
113: UINT CTextGrid::Hittest(POINT pt, POINT ptTest)
114: {
115: for( CGridIt It( _cCol, _cRow, _size, pt ); !It.Done(); ++It)
116: {
117: if( It.Cx() <= ptTest.x && It.Cy() <= ptTest.y &&
118: It.Cx()+_size.cx > ptTest.x && It.Cy() +_size.cy > ptTest.y)
119: {
120: return _cRow* It.Col()+ It.Row() + _iEltOffset;
121: }
122: }
123: return 0xFFFF;
124: }
125:
126: //+--------------------------------------------------------
127: // Class: CCharGrid
128: //
129: // Purpose: Create an n x m Grid of single characters
130: //
131: // History: 22-Jan-1993 asmusf created
132: //----------------------------------------------------------
133:
134: CCharGrid :: CCharGrid(UINT cCol, UINT cRow, SIZE size, UINT iEltOffset)
135: {
136: _size = size;
137: _cCol = cCol;
138: _cRow = cRow;
139: _iEltOffset = iEltOffset;
140: SetTextOrg();
141: }
142:
143: void CCharGrid::DrawElement(CCanvas& canvas, COORD x, COORD y, UINT i, UINT j)
144: {
145: canvas.Char(x, y, (_cRow*i+j +_iEltOffset));
146: }
147:
148: //+--------------------------------------------------------
149: // Class: CCodeGrid
150: //
151: // Purpose: Create an n x m Grid, numbered in sequence
152: //
153: // History: 22-Jan-1993 asmusf created
154: //----------------------------------------------------------
155: CCodeGrid :: CCodeGrid(UINT cCol, UINT cRow, SIZE size, UINT iEltOffset)
156: {
157: _size = size;
158: _cCol = cCol;
159: _cRow = cRow;
160: _iEltOffset = iEltOffset;
161: SetTextOrg();
162: SetFormat();
163: }
164:
165: void CCodeGrid :: SetFormat(UINT fuFormat, UINT cDigits)
166: {
167: _cDigits = cDigits;
168:
1.1.1.2 ! root 169: _szFormat[0]=TEXT('%');
1.1 root 170: if( fuFormat == DECIMAL )
171: {
172: _cDigits = 4; // Constraint:
173: // This format for Decimal
1.1.1.2 ! root 174: _szFormat[1]=TEXT('3'); // really only works with _cDigits == 4
! 175: _szFormat[2]=TEXT('d'); //
! 176: _szFormat[3]=TEXT(' '); // (blank padding for better positioning)
1.1 root 177: }
178: else //
179: {
1.1.1.2 ! root 180: _szFormat[1]=TEXT('0');
1.1 root 181: _szFormat[2]=_cDigits%10+'0';
1.1.1.2 ! root 182: _szFormat[3]=TEXT('X');
1.1 root 183: }
1.1.1.2 ! root 184: _szFormat[4]=TEXT('\0');
1.1 root 185: }
186:
187: void CCodeGrid::DrawElement(CCanvas &canvas, COORD x, COORD y, UINT i, UINT j)
188: {
189: TCHAR sz[10];
190: wsprintf( sz,_szFormat, (_cRow*i+j+_iEltOffset));
191: canvas.Text(x, y, sz, _cDigits);
192: }
193:
194:
195: //+--------------------------------------------------------
196: // Class: CCharBlock
197: //
198: // Purpose: Create an n x m lined block of characters and codes
199: //
200: // History: 22-Jan-1993 asmusf created
201: //----------------------------------------------------------
202:
203: CCharBlock::CCharBlock(UINT cCol, UINT cRow, UINT iBlockOffset, const CBlockFormat &bf) :
204: _Line(cCol, cRow, bf._size),
205: _Char(cCol, cRow, bf._size, iBlockOffset),
206: _Code(cCol, cRow, bf._size, iBlockOffset)
207: {
208: // LINE GRID
209: _Line.SetStyle(PS_SOLID);
210:
211: // LARGE CHARACTER each cell
212: _Char.SetFont(bf._fontChar);
213:
214: // CODE POINT label each cell
215: _Code.SetTextOrg(bf._size.cx/2, 9*bf._size.cy/10);
216: _Code.SetFont(bf._fontCode);
217: _Code.SetFormat(HEXADECIMAL,4);
218: }
219:
220: void CCharBlock::Paint(CCanvas& canvas, RECT rc, POINT pt)
221: {
222: _Line.Paint(canvas, rc, pt);
223: _Char.Paint(canvas, rc, pt);
224: _Code.Paint(canvas, rc, pt);
225: }
226:
227: UINT CCharBlock::Hittest(POINT pt, POINT ptTest)
228: {
229: return _Code.Hittest(pt, ptTest);
230: }
231:
232: void CCharBlock :: SetFormat(UINT fuFormat)
233: {
234: _Code.SetFormat(fuFormat&DECIMAL,4);
235: }
236:
237: void CCharBlock::SetFont(HFONT font)
238: {
239: _Char.SetFont(font);
240: }
241:
242: //+--------------------------------------------------------
243: // Class: CBlockFrame
244: //
245: // Purpose: Create an n x m frame around a block of characters
246: //
247: // History: 22-Jan-1993 asmusf created
248: //----------------------------------------------------------
249:
250: CBlockFrame::CBlockFrame(UINT cCol, UINT cRow, POINT pt, UINT iBlockOffset,
251: TCHAR * szHeader, const CFrameFormat &ff):
252: CCharBlock(cCol, cRow, iBlockOffset, ff ),
253: _size(ff._size),
254: _Cols(cCol, 1, ff._size, iBlockOffset/16),
255: _cRow(cRow),
256: _cCol(cCol)
257: {
258:
259: // COLUMN label above first row
260: _Cols.SetFormat(HEXADECIMAL,3);
261: _Cols.SetFont(ff._fontLabel);
262:
263:
264: // if not first block on page, suppress row labels
265: if( iBlockOffset % 0x100 )
266: {
267: _pRows = NULL;
268: }
269: else
270: {
271: // ROW label to left of first column
272: _pRows = new CCodeGrid(1, cRow, ff._size);
273: _pRows->SetFont(ff._fontLabel);
274: }
275:
276: // BLOCK HEADER
277: _szHeader = new TCHAR[lstrlen(szHeader)+sizeof(TCHAR)];
278: lstrcpy(_szHeader, szHeader);
279: _fontHeader = ff._fontHeader;
280:
281: }
282:
283: CBlockFrame::~CBlockFrame()
284: {
285: delete _pRows;
286: delete _szHeader;
287: }
288:
289:
290: void CBlockFrame::Paint(CCanvas& canvas, RECT rc, POINT pt)
291: {
292: Draw(canvas, pt);
293: {
294: POINT ptCols = {pt.x, pt.y-_size.cy};
295: _Cols.Paint(canvas, rc, ptCols);
296: }
297: CCharBlock::Paint(canvas, rc, pt);
298:
299: // these two are optional. Test first, then draw
300: if(_pRows )
301: {
302: POINT ptRows = {pt.x-_size.cx, pt.y};
303: _pRows->Paint(canvas, rc, ptRows);
304: }
305: }
306:
307: void CBlockFrame::Draw(CCanvas& canvas, POINT pt)
308: {
309: UINT dy = 3*_size.cy/2; // height of short uprights
310: UINT cx = _cCol*_size.cx;
311: UINT cy = _cRow*_size.cy;
312:
313: // set up pen
314: CBlackPen pen(canvas, PS_SOLID, 40); // Solid Black 40/20 points
315:
316: //Draw block divider lines
317:
318: canvas.Line(pt.x, pt.y-dy, pt.x, pt.y+cy); // left edge
319: canvas.Line(pt.x+cx, pt.y-dy, pt.x+cx, pt.y+cy); // right edge
320: canvas.Line(pt.x, pt.y, pt.x+cx, pt.y); // top edge
321: canvas.Line(pt.x, pt.y+cy, pt.x+cx, pt.y+cy); // bottom
322:
323: CFontSelect fs(canvas, _fontHeader);
324:
325: SetTextAlign(canvas, TA_BASELINE|TA_LEFT);
326: canvas.Text(pt.x + _size.cx/6,
327: pt.y - 6*_size.cy/5,
328: _szHeader,
329: lstrlen(_szHeader));
330: }
331:
332: // The following Array contains the widhts of the Unicode blocks in
333: // columns. Each Block has a corresponding entry in the stringtable
334: // giving its block header. "Unassigned" blocks can span page boun-
335: // daries.
336:
337: static UINT aBlockWidth[]=
338: {
339: 2,6,2,6, // 0000
340: 8,8, // 0100
341: 5,6,5, // 0200
342: 8,8, // 0300
343: 16, // 0400
344: 3,6,7, // 0500
345: 16, // 0600
346: 32, // 0700 - 0800
347: 8,8, // 0900
348: 8,8, // 0A00
349: 8,8, // 0B00
350: 8,8, // 0C00
351: 8,8, // 0D00
352: 8,8, // 0E00
353: 16, // 0F00
354: 6,4,6, // 1100
355: 240, // 1200 - 1F00
356: 7,3,3,3, // 2000
357: 5,4,7, // 2100
358: 16, // 2200
359: 16, // 2300
360: 4,2,10, // 2400
361: 8,2,6, // 2500
362: 16, // 2600
363: 12, // 2700
364: 132, // 2800 - 2F00
365: 4,6,6, // 3000
366: 3,6,7, // 3100
367: 16, // 3200
368: 8,8, // 3300
369: 144, // 3400 - 3C00
370: 3,13, // 3D00
371: 256, // 3E00 - 4D00
372: 82*16, // 4E00 - 9FF0
373: 64*16, // A000 - E000
374: 25*16, // E000 - F800
375: 32, // F900 - FA00
376: 48, // FB00 - FD00
377: 3,2,2,9, // FE00
378: 15,1, // FF00
379: 200 // Sentinel
380: };
381:
382: //+--------------------------------------------------------
383: // Class: CBlockFormat
384: //
385: // Purpose: Block formatting
386: //
387: // History: 22-Jan-1993 asmusf created
388: //----------------------------------------------------------
389:
390: CBlockFormat::CBlockFormat() :
391: _fontCode (TEXT("Arial Narrow"), -6),
392: #ifdef UNICODE
393: _fontChar (TEXT("Lucida Sans Unicode"), -16, TRUE)
394: #else
395: _fontChar (TEXT("Lucida Sans"), -16, TRUE)
396: #endif
397: {
398: };
399:
400: //+--------------------------------------------------------
401: // Class: CFrameFormat
402: //
403: // Purpose: Frame formatting
404: //
405: // History: 22-Jan-1993 asmusf created
406: //----------------------------------------------------------
407:
408: CFrameFormat::CFrameFormat() :
409: _fontHeader (TEXT("Arial"), -12, TRUE),
410: _fontLabel (TEXT("Arial"), -10, TRUE)
411: {
412: }
413:
414: //+--------------------------------------------------------
415: // Class: CPageFormat
416: //
417: // Purpose: Page formatting
418: //
419: // History: 22-Jan-1993 asmusf created
420: //----------------------------------------------------------
421: CPageFormat::CPageFormat(UINT fuFormat) :
422: _fontPageNum (TEXT("Times New Roman"), -10, FALSE)
423: {
424: _size.cx = 4*INCH2/5;
425: _size.cy = INCH2;
426:
427: SetFormat(fuFormat);
428: }
429:
430: void CPageFormat::SetFormat(UINT fuFormat)
431: {
432: _fuFormat = fuFormat;
433:
434: if( fuFormat & PAGEPRINT )
435: {
436: _pt.x= INCH2+(INCH2*7)/10;
437: _pt.y= INCH1+(INCH1*7)/10;
438: }
439: else
440: {
441: _pt.x= INCH2;
442: _pt.y= INCH1;
443: }
444:
445: // locations of headers / footers
446: _ptPE[0].x = _pt.x-_size.cx;
447: _ptPE[0].y = _size.cy/2;
448: _ptPE[1].x = _pt.x+_size.cx*16;
449: _ptPE[1].y = _size.cy/2;
450: _ptPE[2].x = _pt.x+(_size.cx*15)/2;
451: _ptPE[2].y = _pt.y+(_size.cy*33)/2;
452: }
453:
454: //+--------------------------------------------------------
455: // Class: CPage
456: //
457: // Purpose: One or more blocks
458: //
459: // History: 22-Jan-1993 asmusf created
460: //----------------------------------------------------------
461: CPage::CPage(HINSTANCE hInst, CPageFormat &pf, UINT nPage) :
462: _cBlock(0),
463: _pf(pf),
464: _hInst(hInst),
465: _PageHeadL (1, 1, pf._size,nPage*256 ),
466: _PageHeadR (1, 1, pf._size,(nPage+1)*256-1),
467: _PageNums (1, 1, pf._size,nPage+1 )
468: // page numbers are 1 based on output
469: {
470: // Set up page elementss
471:
472: _PageHeadL.SetFont(pf._fontLabel);
473: _PageHeadR.SetFont(pf._fontLabel);
474: _PageNums.SetFont(pf._fontPageNum);
475:
476: InitPage( nPage);
477: SetFormat(_pf._fuFormat);
478: }
479:
480: CPage::~CPage()
481: {
482: while( _cBlock )
483: {
484: delete _apBlock[--_cBlock];
485: }
486: }
487:
488:
489:
490: void CPage::SetFormat(UINT fuFormat)
491: {
492: // set it
493: _pf.SetFormat(fuFormat);
494:
495: // apply it
496: for( UINT i = 0; i < _cBlock ; ++i )
497: {
498: _apBlock[i]->SetFormat(fuFormat&MASKROOT);
499: }
500:
501: _PageHeadL.SetFormat(HEXADECIMAL, 4);
502: _PageHeadR.SetFormat(HEXADECIMAL, 4);
503: _PageNums.SetFormat(DECIMAL);
504: }
505:
506:
507: void CPage::Paint(CCanvas& canvas, RECT rc)
508: {
509: for( UINT i = 0; i < _cBlock; ++i )
510: {
511: _apBlock[i]->Paint(canvas, rc, _aptBlock[i]);
512: }
513:
514: if( _pf._fuFormat & PAGEELEMS )
515: {
516: _PageHeadL.Paint(canvas, rc, _pf._ptPE[0]);
517: _PageHeadR.Paint(canvas, rc, _pf._ptPE[1]);
518: _PageNums.Paint (canvas, rc, _pf._ptPE[2]);
519: }
520: }
521:
522: UINT CPage::Hittest(POINT ptTest)
523: {
524: UINT uHit = 0xFFFF;
525:
526: for( UINT i = 0; i < _cBlock && uHit ==0xFFFF ; ++i )
527: {
528: uHit = _apBlock[i]->Hittest(_aptBlock[i], ptTest);
529: }
530: return uHit;
531: }
532:
533: //-- protected member functions...
534:
535: UINT CPage::InitPage(UINT nPage)
536: {
537: UINT iEnd = 0;
538: TCHAR szBlockHeader[40];
539: UINT i;
540: POINT ptBlock=_pf._pt;
541:
542: // Set up blocks
543:
544: for( i=0; i < sizeof(aBlockWidth)/sizeof(UINT); i++ )
545: {
546: if( nPage*16 < (iEnd+=aBlockWidth[i]) )
547: {
548: break;
549: }
550: }
551: UINT iStart = max(nPage*16, iEnd-aBlockWidth[i]);
552:
553: do
554: {
555: LoadString(_hInst, i, szBlockHeader, 40);
556: _apBlock[_cBlock]= new CBlockFrame(
557: min( aBlockWidth[i], // grid width in columns
558: (nPage+1)*16-iStart),// (but at most to end of page)
559: 16, // cRow always 16
560: ptBlock, // grid origin
561: iStart*16, // first char offset
562: szBlockHeader, // header string
563: _pf); // common formatting
564:
565: _aptBlock[_cBlock] = ptBlock;
566: _cBlock++;
567:
568: ptBlock.x+=_pf._size.cx*aBlockWidth[i];
569: iStart=iEnd;
570: }
571: while(
572: (i++ < sizeof(aBlockWidth)/sizeof(UINT))
573: &&
574: ((nPage+1)*16 >= (iEnd+=aBlockWidth[i]))
575: &&
576: (_cBlock < 4)
577: );
578:
579:
580: return _cBlock;
581: }
582:
583:
584: void CPage::SetFont(HFONT hfont)
585: {
586: for( UINT i = 0; i < _cBlock ; ++i )
587: {
588: _apBlock[i]->SetFont(hfont);
589: }
590: }
591:
592: //+--------------------------------------------------------
593: // Class: CModel
594: //
595: // Purpose: Iterator over pages
596: //
597: // History: 22-Jan-1993 asmusf created
598: //----------------------------------------------------------
599: CModel::CModel(HINSTANCE hInst, UINT fuFormat) :
600: _iPage(0),
601: #ifdef UNICODE
602: _macPage(0x100),
603: #else
604: _macPage(1),
605: #endif
606: _pf(fuFormat),
607: _hInst(hInst)
608: {
609: _pPage = new CPage(hInst, _pf, _iPage);
610: }
611:
612: CModel::~CModel()
613: {
614: delete _pPage;
615: }
616:
617: void CModel::NextPage()
618: {
619: SetPage(_iPage+=(_iPage+1<_macPage? 1 : 0));
620: }
621:
622: void CModel::PrevPage()
623: {
624: SetPage(_iPage-=(_iPage? 1 : 0));
625: }
626:
627: void CModel::NextSection()
628: {
629: SetPage(_iPage+=(_iPage+16<_macPage? 16 : 0));
630: }
631:
632: void CModel::PrevSection()
633: {
634: SetPage(_iPage-=(_iPage >= 16 ? 16 : 0));
635: }
636:
637: void CModel::SetPage(UINT nPage)
638: {
639: delete _pPage;
640: _pPage = new CPage(_hInst, _pf, nPage);
641: }
642:
643: void CModel::GetFormat(UINT &fuFormat)
644: {
645: fuFormat=_pf._fuFormat;
646: }
647:
648: void CModel::SetFormat(UINT fuFormat)
649: {
650: _pPage->SetFormat(fuFormat);
651: }
652:
653: HFONT CModel::GetFont()
654: {
655: return _pf._fontChar;
656: }
657:
658: BOOL CModel::CreateFont(LOGFONT &lf)
659: {
660: if(_pf._fontChar.Create(lf))
661: {
662: _pPage->SetFont(_pf._fontChar);
663: return TRUE;
664: }
665: return FALSE;
666: }
667:
668: BOOL CModel::ChooseFont(HWND hwnd)
669: {
670: if(_pf._fontChar.Choose(hwnd))
671: {
672: _pPage->SetFont(_pf._fontChar);
673: return TRUE;
674: }
675: return FALSE;
676: }
677:
678: UINT CModel::Hittest( POINT pt)
679: {
680: return _pPage->Hittest( pt);
681: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.