summaryrefslogtreecommitdiff
path: root/Horloge/Digistring.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Horloge/Digistring.cpp')
-rw-r--r--Horloge/Digistring.cpp904
1 files changed, 904 insertions, 0 deletions
diff --git a/Horloge/Digistring.cpp b/Horloge/Digistring.cpp
new file mode 100644
index 0000000..a0cc6b7
--- /dev/null
+++ b/Horloge/Digistring.cpp
@@ -0,0 +1,904 @@
+// Digistring.cpp : implementation file
+//
+// Copyright (C) 2000 by Michel Wassink
+// All rights reserved
+//
+// This is free software.
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is
+// not sold for profit without the authors written consent, and
+// providing that this notice and the authors name and all copyright
+// notices remains intact. If the source code in this file is used in
+// any commercial application then a statement along the lines of
+// "Portions Copyright © 2000 Michel Wassink" must be included in
+// the startup banner, "About" box or printed documentation. An email
+// letting me know that you are using it would be nice as well. That's
+// not much to ask considering the amount of work that went into this.
+//
+// No warrantee of any kind, expressed or implied, is included with this
+// software; use at your own risk, responsibility for damages (if any) to
+// anyone resulting from the use of this software rests entirely with the
+// user.
+//
+// Send bug reports, bug fixes, enhancements, requests, flames, etc., and
+// I'll try to keep a version up to date. I can be reached as follows:
+// mwassink@csi.com (private site)
+// An email letting me know that you are using it would be nice.
+/////////////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "Digistring.h"
+#include "Curvefit.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+// Segment numbering:
+// ----- 13 ----- 0
+//|\ | /| 8 0 12 | | 1 2
+//| \|/ | 1 2 | |
+// -- -- == 6 7 ----- == 3
+//| /|\ | 3 4 | |
+//|/ | \| 9 5 11 | | 4 5
+// ----- 10 ----- 6
+
+#define MAXSEGCHAR7 12 // Number of supported 7 segment characters
+#define MAXSEGCHAR14 40 // Number of supported 14 segment characters
+#define MAXSEGSEMCOL 2 // Number of supported 3 segment characters
+#define NORM_DIGIHEIGHT 83 // All characters must have this height
+
+////////////////////////////////////////////////////////////////////////////////
+// For 14 segments display...
+// SP 0 1 2 3 4 5 6
+WORD CHAR_SEGM14[MAXSEGCHAR14] = {0x0000, 0x3F00, 0x1800, 0x36C0, 0x3CC0, 0x19C0, 0x2DC0, 0x2FC0,
+// 7 8 9 - A B C D E F G H
+ 0x3800, 0x3FC0, 0x3DC0, 0x00C0, 0x3BC0, 0x3CA1, 0x2700, 0x3C21, 0x27C0, 0x23C0, 0x2F80, 0x1BC0,
+// I J K L M N O P Q R S
+ 0x2421, 0x1E00, 0x0354, 0x0700, 0x1B06, 0x1B12, 0x3F00, 0x33C0, 0x3F10, 0x33D0, 0x2DC0,
+// T U V W X Y Z * +
+ 0x2021, 0x1F00, 0x030C, 0x1B18, 0x001E, 0x11E0, 0x240C, 0x00FF, 0x00E1};
+// straight style
+CPoint PtSeg14N0[5] = {CPoint(20,13), CPoint(20,36), CPoint(24,40), CPoint(28,36), CPoint(28,13)};
+CPoint PtSeg14N1[4] = {CPoint( 5, 5), CPoint(15,35), CPoint(20,37), CPoint(18,25)};
+CPoint PtSeg14N6[6] = {CPoint( 6,41), CPoint(14,45), CPoint(18,45), CPoint(22,41), CPoint(18,37),
+ CPoint(14,37)};
+CPoint PtSeg14N8[4] = {CPoint( 4, 7), CPoint( 4,40), CPoint(11,36), CPoint(11,26)};
+CPoint PtSeg14N13[4] = {CPoint( 6, 4), CPoint(11,11), CPoint(37,11), CPoint(42, 4)};
+BYTE TpSeg14N0[5] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO, PT_LINETO};
+BYTE TpSeg14N1[4] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO};
+BYTE TpSeg14N6[6] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO, PT_LINETO,
+ PT_LINETO};
+BYTE TpSeg14N8[4] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO};
+BYTE TpSeg14N13[4] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO};
+
+// smooth style PT_BEZIERTO
+CPoint PtSeg14N0S[13] ={CPoint(20,12), CPoint(20,25), CPoint(22,36), CPoint(23,39), CPoint(24,40),
+ CPoint(25,39), CPoint(26,36), CPoint(28,25), CPoint(28,12), CPoint(26,10),
+ CPoint(24, 9), CPoint(22,10), CPoint(20,12)};
+CPoint PtSeg14N1S[10] ={CPoint(10,10), CPoint(10,13), CPoint(11,20), CPoint(13,28), CPoint(21,38),
+ CPoint(21,37), CPoint(19,26), CPoint(15,16), CPoint(11,10), CPoint(10,10)};
+CPoint PtSeg14N6S[6] = {CPoint( 8,41), CPoint(12,45), CPoint(16,45), CPoint(23,41), CPoint(16,37),
+ CPoint(12,37)};
+CPoint PtSeg14N8S[10]= {CPoint( 4, 7), CPoint( 4,39), CPoint( 5,40), CPoint( 6,40), CPoint( 9,37),
+ CPoint(11,33), CPoint(11,25), CPoint( 9,14), CPoint( 5, 6), CPoint( 4, 7)};
+CPoint PtSeg14N13S[17]={CPoint( 8, 4), CPoint( 7, 5), CPoint( 7, 6), CPoint( 9, 8), CPoint(12, 9),
+ CPoint(14,11), CPoint(19,11), CPoint(21, 9), CPoint(24, 7), CPoint(27, 9),
+ CPoint(29,11), CPoint(34,11), CPoint(36, 9), CPoint(39, 8), CPoint(41, 6),
+ CPoint(41, 5), CPoint(40, 4)};
+BYTE TpSeg14N0S[13]= {PT_MOVETO, PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO,
+ PT_BEZIERTO, PT_BEZIERTO, PT_LINETO, PT_LINETO, PT_BEZIERTO,
+ PT_BEZIERTO, PT_BEZIERTO, PT_LINETO};
+BYTE TpSeg14N1S[10] ={PT_MOVETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO,
+ PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO};
+BYTE TpSeg14N6S[6] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO, PT_LINETO,
+ PT_LINETO};
+BYTE TpSeg14N8S[10] ={PT_MOVETO, PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO,
+ PT_BEZIERTO, PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO};
+BYTE TpSeg14N13S[17]={PT_MOVETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO,
+ PT_LINETO, PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO,
+ PT_LINETO, PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO,
+ PT_BEZIERTO, PT_LINETO};
+///////////////////////////////////////////////////////////////////////////////
+// For 7 segments display...
+// SP 0 1 2 3 4 5
+BYTE CHAR_SEGM7[MAXSEGCHAR7] = {0x00, 0x77, 0x24, 0x5D, 0x6D, 0x2E, 0x6B,
+// 6 7 8 9 -
+ 0x7B, 0x25, 0x7F, 0x6F, 0x08};
+// straight style
+CPoint PtSeg7N0[4] = {CPoint( 5, 4), CPoint(12,11), CPoint(36,11), CPoint(43, 4)};
+CPoint PtSeg7N1[4] = {CPoint( 4, 6), CPoint( 4,40), CPoint(11,36), CPoint(11,13)};
+CPoint PtSeg7N3[6] = {CPoint( 6,41), CPoint(14,45), CPoint(34,45), CPoint(42,41), CPoint(34,37),
+ CPoint(14,37)}; // 3
+BYTE TpSeg7N0[4] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO};
+BYTE TpSeg7N1[4] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO};
+BYTE TpSeg7N3[6] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO, PT_LINETO,
+ PT_LINETO};
+
+// smooth style PT_BEZIERTO
+CPoint PtSeg7N0S[7] = {CPoint( 6, 4), CPoint( 5, 5), CPoint( 5, 6), CPoint( 8, 9), CPoint(12,11),
+ CPoint(36,11), CPoint(39, 4)};
+CPoint PtSeg7N1S[7] = {CPoint( 4, 9), CPoint( 4,39), CPoint( 6,40), CPoint( 7,40), CPoint( 9,38),
+ CPoint(11,36), CPoint(11,12)};
+CPoint PtSeg7N2S[10] = {CPoint(37,36), CPoint(39,38), CPoint(41,40), CPoint(42,40), CPoint(44,39),
+ CPoint(44, 6), CPoint(42, 4), CPoint(41, 4), CPoint(39, 8), CPoint(37,12)};
+CPoint PtSeg7N3S[6] = {CPoint( 8,41), CPoint(12,45), CPoint(36,45), CPoint(40,41), CPoint(36,37),
+ CPoint(12,37)};
+BYTE TpSeg7N0S[7] = {PT_MOVETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO,
+ PT_LINETO, PT_LINETO};
+BYTE TpSeg7N1S[7] = {PT_MOVETO, PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO,
+ PT_LINETO, PT_LINETO};
+BYTE TpSeg7N2S[10] = {PT_MOVETO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO, PT_LINETO,
+ PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO};
+BYTE TpSeg7N3S[6] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO, PT_LINETO,
+ PT_LINETO};
+
+// For 3 segments semicoloncombi display...
+// . :
+BYTE CHAR_SEMCOL[MAXSEGSEMCOL] = {0x04, 0x03};
+
+CPoint PtSegScN0[4] = {CPoint( 4,23), CPoint( 4,32), CPoint(13,32), CPoint(13,23)};
+CPoint PtSegScN1[4] = {CPoint( 4,50), CPoint( 4,59), CPoint(13,59), CPoint(13,50)};
+CPoint PtSegScN2[4] = {CPoint( 4,68), CPoint( 4,77), CPoint(13,77), CPoint(13,68)};
+BYTE TpSegScN0[4] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO};
+BYTE TpSegScN1[4] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO};
+BYTE TpSegScN2[4] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_LINETO};
+
+// Functions for mirroring points...
+CPoint PointMirror(const CPoint &P, const CPoint &M)
+{
+ return CPoint(P.x + 2*(M.x - P.x), P.y + 2*(M.y - P.y));
+}
+
+CPoint LineMirrorX(const CPoint &P, int X)
+{
+ return CPoint(P.x + 2*(X - P.x), P.y);
+}
+
+CPoint LineMirrorY(const CPoint &P, int Y)
+{
+ return CPoint(P.x, P.y + 2*(Y - P.y));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CDSegment
+CDSegment::CDSegment()
+{
+ m_paPoints = NULL;
+ m_paTypes = NULL;
+}
+
+CDSegment::CDSegment(const CDSegment& Segment)
+{
+ ASSERT(Segment.m_paPoints != NULL); // Do not copy an unitialized segment
+
+ m_nCount = Segment.m_nCount;
+
+ m_paPoints = new CPoint[m_nCount];
+ m_paTypes = new BYTE[m_nCount];
+ if (m_paPoints != NULL && m_paTypes != NULL)
+ {
+ memcpy(m_paPoints, Segment.m_paPoints, m_nCount * sizeof(CPoint));
+ memcpy(m_paTypes, Segment.m_paTypes, m_nCount * sizeof(BYTE));
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+CDSegment::~CDSegment()
+{
+ FreeSegment();
+}
+
+void CDSegment::DefPoints(const POINT* lpaPoints, const BYTE* lpaTypes, int nCount)
+{
+ FreeSegment();
+
+ m_paPoints = new CPoint[nCount];
+ m_paTypes = new BYTE[nCount];
+ m_nCount = nCount;
+ if (m_paPoints != NULL && m_paTypes != NULL)
+ {
+ memcpy(m_paPoints, lpaPoints, m_nCount * sizeof(CPoint));
+ memcpy(m_paTypes, lpaTypes, m_nCount * sizeof(BYTE));
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+CDSegment CDSegment::operator=(const CDSegment &Segment)
+{
+ CPoint *pNewPoints;
+ BYTE * pNewTypes;
+
+ m_nCount = Segment.m_nCount;
+
+ pNewPoints = new CPoint[m_nCount];
+ pNewTypes = new BYTE[m_nCount];
+ memcpy(pNewPoints, Segment.m_paPoints, m_nCount * sizeof(CPoint));
+ memcpy(pNewTypes, Segment.m_paTypes, m_nCount * sizeof(BYTE));
+ FreeSegment(); // Get rid of old stuff
+ m_paPoints = pNewPoints;
+ m_paTypes = pNewTypes;
+
+ return *this;
+}
+
+void CDSegment::FreeSegment()
+{
+ if (m_paPoints != NULL && m_paTypes != NULL)
+ {
+ delete[] m_paPoints;
+ delete[] m_paTypes;
+ m_paPoints = NULL;
+ m_paTypes = NULL;
+ }
+}
+
+void CDSegment::Draw(CDC *pDC, CDoubleRect DrawPlace, int iWidth) const
+{
+ int i, nBez,b;
+ CPoint * paPoints;
+ double daContr[4];
+ double *pBezPts;
+ double dRelWidth, dRelHeight;
+
+ paPoints = new CPoint[m_nCount];
+ if (paPoints == NULL) return;
+
+ dRelWidth = DrawPlace.Width() / iWidth;
+ dRelHeight = DrawPlace.Height() / NORM_DIGIHEIGHT;
+ for (i = 0; i < m_nCount; i++)
+ {
+ if (m_paTypes[i] != PT_BEZIERTO)
+ {
+ paPoints[i] = CPoint(DrawPlace.left + dRelWidth * m_paPoints[i].x + 0.5,
+ DrawPlace.top + dRelHeight * m_paPoints[i].y + 0.5);
+ }
+ }
+
+ for (i = 0; i < m_nCount; i++)
+ {
+ if (m_paTypes[i] == PT_MOVETO)
+ {
+ pDC->MoveTo(paPoints[i]);
+ }
+ else if (m_paTypes[i] == PT_LINETO)
+ {
+ VERIFY(pDC->LineTo(paPoints[i]));
+ }
+ else if (m_paTypes[i] == PT_BEZIERTO)
+ {
+ // Look for the first non-bezier point(This is the EndPoint)...
+ nBez = 0;
+ do
+ {
+ nBez++;
+ } while (m_paTypes[i+nBez] == PT_BEZIERTO);
+
+ pBezPts = new double[2*(nBez+2)];
+ for (b = 0; b < (nBez+2)*2; b += 2)
+ {
+ pBezPts[b ] = DrawPlace.left + dRelWidth * m_paPoints[i-1+b/2].x;
+ pBezPts[b+1] = DrawPlace.top + dRelHeight * m_paPoints[i-1+b/2].y;
+ }
+ CalcBezier(pBezPts, 2*(nBez+2), daContr);
+ delete[] pBezPts;
+
+ paPoints[i ].x = daContr[0] + 0.5;
+ paPoints[i ].y = daContr[1] + 0.5;
+ paPoints[i+1].x = daContr[2] + 0.5;
+ paPoints[i+1].y = daContr[3] + 0.5;
+ paPoints[i+2] = paPoints[i+nBez];
+
+ VERIFY(pDC->PolyBezierTo(&paPoints[i], 3));
+ i += nBez;
+ }
+ } // for
+ delete[] paPoints;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CDigiChar
+
+CDigiChar::CDigiChar()
+{
+ m_Width = 49;
+ m_wSegmData = 0x0000; // All segments in offcolor
+}
+
+CDigiChar::~CDigiChar()
+{
+
+}
+
+void CDigiChar::Draw(CDC *pDC, CDoubleRect DrawPlace, CPen *pOffPen, CPen *pOnPen,
+ CBrush *pOffBrush, CBrush *pOnBrush)
+{
+ WORD SegMask;
+ DSegmentVector::iterator SegmIterator;
+
+ SegMask = 1;
+ for (SegmIterator = m_SegmentVector.begin(); SegmIterator != m_SegmentVector.end();
+ SegmIterator++)
+ {
+ if (m_wSegmData & SegMask)
+ {
+ pDC->SelectObject(pOnBrush);
+ pDC->SelectObject(pOnPen);
+ }
+ else
+ {
+ pDC->SelectObject(pOffBrush);
+ pDC->SelectObject(pOffPen);
+ }
+
+ pDC->BeginPath();
+ SegmIterator->Draw(pDC, DrawPlace, m_Width);
+ pDC->EndPath();
+ pDC->StrokeAndFillPath();
+
+ SegMask <<= 1;
+ }
+}
+void CDigiChar::SetElementData(WORD wSegmData, int /*iDispStyle*/)
+{
+ m_wSegmData = wSegmData;
+}
+
+int CDigiChar::GetNormWidth() const
+{
+ return m_Width;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CDigi7Segment
+
+CDigi7Segment::CDigi7Segment()
+{
+ m_Width = 49;
+ m_NSegments = 7;
+}
+
+void CDigi7Segment::SetElementData(WORD wSegmData, int iDispStyle)
+{
+ int i, p;
+ CDSegment TmpSegm;
+ LPPOINT lpTmpSegPoints = NULL;
+ LPPOINT lpSegPoints;
+ LPBYTE lpType;
+ int nCount;
+
+ m_SegmentVector.clear();
+ for (i = 0; i < m_NSegments; i++)
+ {
+ switch(i)
+ {
+ case 0:
+ case 6: if (iDispStyle & CDigistring::DS_SMOOTH)
+ {
+ lpSegPoints = PtSeg7N0S;
+ lpType = TpSeg7N0S;
+ nCount = 7;
+ }
+ else
+ {
+ lpSegPoints = PtSeg7N0;
+ lpType = TpSeg7N0;
+ nCount = 4;
+ }
+ break;
+ case 1:
+ case 4:if (iDispStyle & CDigistring::DS_SMOOTH)
+ {
+ lpSegPoints = PtSeg7N1S;
+ lpType = TpSeg7N1S;
+ nCount = 7;
+ }
+ else
+ {
+ lpSegPoints = PtSeg7N1;
+ lpType = TpSeg7N1;
+ nCount = 4;
+ }
+ break;
+ case 2:
+ case 5: if (iDispStyle & CDigistring::DS_SMOOTH)
+ {
+ lpSegPoints = PtSeg7N2S;
+ lpType = TpSeg7N2S;
+ nCount = 10;
+ }
+ else
+ {
+ lpSegPoints = PtSeg7N1;
+ lpType = TpSeg7N1;
+ nCount = 4;
+ }
+ break;
+ case 3: if (iDispStyle & CDigistring::DS_SMOOTH)
+ {
+ lpSegPoints = PtSeg7N3S;
+ lpType = TpSeg7N3S;
+ nCount = 6;
+ }
+ else
+ {
+ lpSegPoints = PtSeg7N3;
+ lpType = TpSeg7N3;
+ nCount = 6;
+ }
+ break;
+ }
+
+ switch(i)
+ {
+ case 6: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = LineMirrorY(lpSegPoints[p], 41);break;
+ case 2: if (!(iDispStyle & CDigistring::DS_SMOOTH))
+ {
+ lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = LineMirrorX(lpSegPoints[p], (m_Width-1)/2);
+ }
+ break;
+ case 4: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = LineMirrorY(lpSegPoints[p], 41);break;
+ case 5: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ if (iDispStyle & CDigistring::DS_SMOOTH)
+ lpTmpSegPoints[p] = LineMirrorY(lpSegPoints[p], 41);
+ else
+ lpTmpSegPoints[p] = PointMirror(lpSegPoints[p], CPoint((m_Width-1)/2, 41));
+ break;
+ }
+
+ if (lpTmpSegPoints == NULL)
+ TmpSegm.DefPoints(lpSegPoints, lpType, nCount);
+ else
+ {
+ TmpSegm.DefPoints(lpTmpSegPoints, lpType, nCount);
+ delete[] lpTmpSegPoints;
+ lpTmpSegPoints = NULL;
+ }
+ m_SegmentVector.push_back(TmpSegm);
+ }
+ m_wSegmData = wSegmData;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CDigi14Segment
+
+CDigi14Segment::CDigi14Segment()
+{
+ m_Width = 49;
+ m_NSegments = 14;
+}
+
+void CDigi14Segment::SetElementData(WORD wSegmData, int iDispStyle)
+{
+ int i, p;
+ CDSegment x;
+ LPPOINT lpTmpSegPoints = NULL;
+ LPPOINT lpSegPoints;
+ LPBYTE lpType;
+ int nCount;
+
+ m_SegmentVector.clear();
+ for (i = 0; i < m_NSegments; i++)
+ {
+ switch(i)
+ {
+ case 0:
+ case 5: if (iDispStyle & CDigistring::DS_SMOOTH)
+ {
+ lpSegPoints = PtSeg14N0S;
+ lpType = TpSeg14N0S;
+ nCount = 13;
+ }
+ else
+ {
+ lpSegPoints = PtSeg14N0;
+ lpType = TpSeg14N0;
+ nCount = 5;
+ }
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ if (iDispStyle & CDigistring::DS_SMOOTH)
+ {
+ lpSegPoints = PtSeg14N1S;
+ lpType = TpSeg14N1S;
+ nCount = 10;
+ }
+ else
+ {
+ lpSegPoints = PtSeg14N1;
+ lpType = TpSeg14N1;
+ nCount = 5;
+ }
+ break;
+ case 6:
+ case 7:
+ if (iDispStyle & CDigistring::DS_SMOOTH)
+ {
+ lpSegPoints = PtSeg14N6S;
+ lpType = TpSeg14N6S;
+ nCount = 6;
+ }
+ else
+ {
+ lpSegPoints = PtSeg14N6;
+ lpType = TpSeg14N6;
+ nCount = 6;
+ }
+ break;
+ case 8:
+ case 9:
+ case 11:
+ case 12:
+ if (iDispStyle & CDigistring::DS_SMOOTH)
+ {
+ lpSegPoints = PtSeg14N8S;
+ lpType = TpSeg14N8S;
+ nCount = 10;
+ }
+ else
+ {
+ lpSegPoints = PtSeg14N8;
+ lpType = TpSeg14N8;
+ nCount = 4;
+ }
+ break;
+ case 13:
+ case 10:
+ if (iDispStyle & CDigistring::DS_SMOOTH)
+ {
+ lpSegPoints = PtSeg14N13S;
+ lpType = TpSeg14N13S;
+ nCount = 17;
+ }
+ else
+ {
+ lpSegPoints = PtSeg14N13;
+ lpType = TpSeg14N13;
+ nCount = 4;
+ }
+ break;
+ }
+
+ switch(i)
+ {
+ case 5: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = LineMirrorY(lpSegPoints[p], 41);break;
+ case 2: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = LineMirrorX(lpSegPoints[p], (m_Width-1)/2);break;
+ case 3: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = LineMirrorY(lpSegPoints[p], 41);break;
+ case 4: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = PointMirror(lpSegPoints[p], CPoint((m_Width-1)/2, 41));break;
+ case 7: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = LineMirrorX(lpSegPoints[p], (m_Width-1)/2);break;
+ case 9: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = LineMirrorY(lpSegPoints[p], 41);break;
+ case 11: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = PointMirror(lpSegPoints[p], CPoint((m_Width-1)/2, 41));break;
+ case 12: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = LineMirrorX(lpSegPoints[p], (m_Width-1)/2);break;
+ case 10: lpTmpSegPoints = new CPoint[nCount];
+ for (p = 0; p < nCount; p++)
+ lpTmpSegPoints[p] = LineMirrorY(lpSegPoints[p], 41);break;
+ }
+
+ if (lpTmpSegPoints == NULL)
+ x.DefPoints(lpSegPoints, lpType, nCount);
+ else
+ {
+ x.DefPoints(lpTmpSegPoints, lpType, nCount);
+ delete[] lpTmpSegPoints;
+ lpTmpSegPoints = NULL;
+ }
+ m_SegmentVector.push_back(x);
+ }
+ m_wSegmData = wSegmData;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CDigiSemiColonCombi
+
+CDigiColonDotChar::CDigiColonDotChar()
+{
+ m_Width = 18;
+ m_NSegments = 3;
+}
+
+void CDigiColonDotChar::SetElementData(WORD wSegmData, int /*iDispStyle*/)
+{
+ int i;
+ CDSegment DSegment;
+ LPPOINT lpSegPoints;
+ LPBYTE lpType;
+ int nCount;
+
+ m_SegmentVector.clear();
+
+ for (i = 0; i < m_NSegments; i++)
+ {
+ switch(i)
+ {
+ case 0:lpSegPoints = PtSegScN0;
+ lpType = TpSegScN0;
+ nCount = 4; break;
+ case 1:
+ lpSegPoints = PtSegScN1;
+ lpType = TpSegScN1;
+ nCount = 4; break;
+ case 2:
+ lpSegPoints = PtSegScN2;
+ lpType = TpSegScN2;
+ nCount = 4; break;
+ }
+ DSegment.DefPoints(lpSegPoints, lpType, nCount);
+ m_SegmentVector.push_back(DSegment);
+ }
+
+ m_wSegmData = wSegmData;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CDigistring
+
+CDigistring::CDigistring()
+ : m_strText("EMPTY")
+{
+ m_DispStyle = DS_SZ_PROP;
+ m_BackColor = BLACK;
+ m_Modified = TRUE;
+ m_OffColor = DARKGREEN;
+ m_OnColor = LIGHTGREEN;
+}
+
+CDigistring::~CDigistring()
+{
+ m_CharVector.clear();
+}
+
+void CDigistring::SetText(LPCTSTR lpszText)
+{
+ if (m_strText != lpszText)
+ {
+ m_strText = lpszText;
+ m_Modified = TRUE;
+ Invalidate();
+ }
+}
+
+void CDigistring::Format(LPCTSTR lpszFormat, ...)
+{
+ TCHAR szMessage[256];
+
+ va_list argp;
+ va_start(argp, lpszFormat);
+ _vsntprintf(szMessage, 255, lpszFormat, argp);
+ va_end(argp);
+
+ SetText(szMessage);
+}
+
+void CDigistring::SetColor(COLORREF OffColor, COLORREF OnColor)
+{
+ if (m_OnColor == OnColor && m_OffColor == OffColor)
+ return;
+ m_OnColor = OnColor;
+ m_OffColor = OffColor;
+ Invalidate();
+}
+
+void CDigistring::SetBackColor(COLORREF BackColor /* = BLACK */)
+{
+ if (m_BackColor == BackColor)
+ return;
+ m_BackColor = BackColor;
+ Invalidate();
+}
+
+BOOL CDigistring::ModifyDigiStyle(DWORD dwRemove, DWORD dwAdd)
+{
+ ASSERT(!(dwRemove & dwAdd));
+ if (dwRemove & dwAdd)
+ return FALSE;
+
+ m_DispStyle |= dwAdd;
+ m_DispStyle &= ~dwRemove;
+
+ m_Modified = TRUE;
+ Invalidate();
+ return TRUE;
+}
+
+CDigiChar * CDigistring::DefineChar(TCHAR cChar)
+{
+ int iIndex;
+ CDigiChar * pDChar = NULL;
+
+ if (cChar >= _T('0') && cChar <= _T('9')
+ || cChar == _T(' ') || cChar == _T('-'))
+ {
+ if (cChar == _T(' '))
+ {
+ iIndex = 0;
+ }
+ else if (cChar == _T('-'))
+ {
+ iIndex = 11;
+ }
+ else
+ {
+ iIndex = cChar - _T('0') + 1;
+ }
+
+ if (m_DispStyle & DS_STYLE14)
+ {
+ pDChar = new CDigi14Segment;
+ pDChar->SetElementData(CHAR_SEGM14[iIndex], m_DispStyle);
+ }
+ else
+ {
+ pDChar = new CDigi7Segment;
+ pDChar->SetElementData(CHAR_SEGM7[iIndex], m_DispStyle);
+ }
+ }
+ else if (cChar >= _T('A') && cChar <= _T('Z'))
+ {
+ iIndex = cChar - _T('A') + 12;
+ pDChar = new CDigi14Segment;
+ pDChar->SetElementData(CHAR_SEGM14[iIndex], m_DispStyle);
+ }
+ else
+ {
+ iIndex = 0;
+ switch(cChar)
+ {
+ case _T(':'): iIndex++;
+ case _T('.'): pDChar = new CDigiColonDotChar;
+ pDChar->SetElementData(CHAR_SEMCOL[iIndex], m_DispStyle);
+ break;
+ case _T('*'): iIndex = MAXSEGCHAR14 - 2; pDChar = new CDigi14Segment;
+ pDChar->SetElementData(CHAR_SEGM14[iIndex], m_DispStyle);
+ break;
+ case _T('+'): iIndex = MAXSEGCHAR14 - 1; pDChar = new CDigi14Segment;
+ pDChar->SetElementData(CHAR_SEGM14[iIndex], m_DispStyle);
+ break;
+ default : ASSERT(FALSE);
+ }
+ }
+ return pDChar;
+}
+
+void CDigistring::BuildString()
+{
+ CDigiChar * pDChar;
+ if (!m_Modified) return;
+ m_CharVector.clear();
+
+ m_strText.MakeUpper();
+ for (int i = 0; i < m_strText.GetLength(); i++)
+ {
+ if ((pDChar = DefineChar(m_strText[i])) != NULL)
+ {
+ m_CharVector.push_back(*pDChar);
+ delete pDChar;
+ }
+ }
+
+ m_Modified = FALSE;
+}
+
+BEGIN_MESSAGE_MAP(CDigistring, CStatic)
+ //{{AFX_MSG_MAP(CDigistring)
+ ON_WM_PAINT()
+ ON_WM_ERASEBKGND()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CDigistring message handlers
+
+void CDigistring::OnPaint()
+{
+ CRect rect;
+ CDoubleRect CharRect;
+ GetClientRect(&rect);
+
+ CPaintDC dc(this); // device context for painting
+ dc.SetBkColor(m_BackColor);
+ CMemDC memDC(&dc, &rect);
+
+ CBrush hBrushOff, hBrushOn;
+ hBrushOff.CreateSolidBrush(m_OffColor);
+ hBrushOn.CreateSolidBrush(m_OnColor);
+ CBrush *pOldBrush = memDC.SelectObject(&hBrushOn);
+
+ int r = int(GetRValue(m_OffColor) * 0.75 + GetRValue(m_BackColor) * 0.25);
+ int g = int(GetGValue(m_OffColor) * 0.75 + GetGValue(m_BackColor) * 0.25);
+ int b = int(GetBValue(m_OffColor) * 0.75 + GetBValue(m_BackColor) * 0.25);
+
+ CPen OffPen(PS_SOLID | PS_ENDCAP_ROUND, 1, RGB(r,g,b));
+ r = int(GetRValue(m_OnColor) * 0.75 + GetRValue(m_BackColor) * 0.25);
+ g = int(GetGValue(m_OnColor) * 0.75 + GetGValue(m_BackColor) * 0.25);
+ b = int(GetBValue(m_OnColor) * 0.75 + GetBValue(m_BackColor) * 0.25);
+ CPen OnPen(PS_SOLID | PS_ENDCAP_ROUND, 1, RGB(r,g,b));
+ CPen *pOldPen = memDC.SelectObject(&OffPen);
+
+ int iTotWidth = 0;
+ double dRelWidth, dRelHeight;
+ // TODO: Add your message handler code here
+
+ DigiCharVector::iterator CharIterator;
+
+ // Calculate resizing factors...
+ BuildString();
+ for (CharIterator = m_CharVector.begin(); CharIterator != m_CharVector.end();
+ CharIterator++)
+ {
+ iTotWidth += CharIterator->GetNormWidth();
+ }
+ dRelWidth = double(rect.Width()) / iTotWidth;
+ dRelHeight = double(rect.Height()) / NORM_DIGIHEIGHT;
+
+ // If proportional make offset for centered text
+ if (m_DispStyle & DS_SZ_PROP)
+ {
+ if (dRelWidth < dRelHeight)
+ dRelHeight = dRelWidth;
+ else
+ dRelWidth = dRelHeight;
+
+ CharRect.left = (rect.Width() - dRelWidth * iTotWidth) / 2;
+ CharRect.top = (rect.Height() - dRelHeight * NORM_DIGIHEIGHT) / 2;
+ }
+ else
+ CharRect.SetRectEmpty();
+
+ // Draw all characters...
+ for (CharIterator = m_CharVector.begin(); CharIterator != m_CharVector.end();
+ CharIterator++)
+ {
+ CharRect.SetRect(CharRect.left, CharRect.top,
+ CharRect.left + dRelWidth * CharIterator->GetNormWidth(),
+ CharRect.top + dRelHeight * NORM_DIGIHEIGHT);
+
+ CharIterator->Draw(&memDC, CharRect, &OffPen, &OnPen, &hBrushOff, &hBrushOn);
+
+ CharRect.left += dRelWidth * CharIterator->GetNormWidth();
+ }
+
+ // Mama says: Clean up your mess!
+ memDC.SelectObject(pOldPen);
+ memDC.SelectObject(pOldBrush);
+ OffPen.DeleteObject();
+ OnPen.DeleteObject();
+ hBrushOff.DeleteObject();
+ hBrushOn.DeleteObject();
+}
+
+BOOL CDigistring::OnEraseBkgnd(CDC* /*pDC*/)
+{
+ // Don't erase the background to avoid flickering
+ // Background is painted in CMemDC::CMemDC(); with FillSolidRect();
+ return FALSE;
+}