summaryrefslogtreecommitdiff
path: root/displaybase.h
blob: c85f3a3ad1bc6f98ef5f96ca3f9b4b3f9dd068b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/*************************************************************** -*- c++ -*-
 *                                                                         *
 *   displaybase.h - Base class for rendering a teletext cRenderPage to    *
 *                   an actual VDR OSD.                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   Changelog:                                                            *
 *     2005-03    initial version (c) Udo Richter                          *
 *                                                                         *
 ***************************************************************************/

#ifndef OSDTELETEXT_DISPLAYBASE_H_
#define OSDTELETEXT_DISPLAYBASE_H_

#include "txtrender.h"
#include <vdr/osd.h>

class cDisplay : public cRenderPage {
    // Class that extends the virtual cRenderPage with the capability
    // to render its contents to an OSD of variable size.
    // Renders incrementally - just changes
    // plus adds some more display features like message display.
    
public:
    enum enumZoom {
        // Zoom up upper/lower half of page
        Zoom_Off,
        Zoom_Upper,
        Zoom_Lower
    } Zoom;

protected:
    bool Concealed;
    // Hidden text internal state
    
    bool Blinked;
    // Blinking text internal state
    
    int FlushLock;
    // Lock counter for bundeling OSD flushes
    
    bool Boxed;
    // Page is 'boxed mode' transparent
    
    int Width;
    int Height;
    // OSD pixel dimension
    
    tColor Background;
    // Color to be used for black background
    // - allow transparency

    cOsd *osd;
    // The osd object. If creation fails, may be NULL
    
    int ScaleX,ScaleY;
    int OffsetX,OffsetY;
    // Virtual coordinate system, see InitScaler
    
    const cFont *MessageFont;
    int MessageX,MessageY,MessageW,MessageH;
    // Message overlay window, position and font

    class cBox {
        // helper class. Represents a character's box in virtual coordinates
    public:
        int XMin,YMin,XMax,YMax;
        inline void SetToCharacter(int x, int y);
    };
    friend class cBox;
    
    class cVirtualCoordinate {
        // helper class. Represents a coordinate in virtual display space
        // and in OSD pixel coordinates.
    public:
        int OsdX,OsdY;
        int VirtX,VirtY;
        inline void VirtualToPixel(cDisplay *Display, int x, int y);
        inline void IncPixelX(cDisplay *Display);
        inline void IncPixelY(cDisplay *Display);
    };
    friend class cVirtualCoordinate;
    
public:
    cDisplay(int width, int height);
    virtual ~cDisplay();
    bool Valid() { return (osd!=NULL); }
    // After creation, check for Valid(). Destroy, if not valid.
        
protected:  
    void InitScaler();
    // Initialize transformation for OSD->Virtual coordinates
    // Some words about scaling:
    
    // OSD display is variable width x height, with 3 pixels border
    // on all sides. There is a virtual coordinate system projected
    // on this, with (3,3) mapped to (0,0) and (width-3,height-3) 
    // mapped to (480<<16,250<<16).
    // The idea is, that each font pixel uses a virtual rectangle
    // of (1<<16,1<<16) size.
    
    // ScaleX,ScaleY represent the (virtual) width and height of a 
    // physical OSD pixel.
    // OffsetX,OffsetY default to 3,3 to represent the border offset,
    // but may be used differently.

public:
    bool GetBlink() { return Blinked; }
    bool SetBlink(bool blink);
    // Switch blink frequently to get blinking chars
    // Returns true if there are blinking characters.
    
    bool GetConceal() { return Concealed; }
    bool SetConceal(bool conceal);
    // Hidden text. Set to true to see hidden text.
    // Returns true if there are concealed characters.
    
    enumZoom GetZoom() { return Zoom; }
    void SetZoom(enumZoom zoom);
    // Zoom to upper/lower half of page

    void SetBackgroundColor(tColor c);
    tColor GetBackgroundColor() { return Background; }
    // Set the background color for black. Allows transparent black.

    // Color mapping interface.
    virtual tColor GetColorRGB(enumTeletextColor ttc, int Area);
    // Map a teletext color to an OSD color in #Area.

    virtual tColor GetColorRGBAlternate(enumTeletextColor ttc, int Area);
    // For color collision:
    // Map this teletext color to an OSD color in #Area, but dont
    // return same as GetColorRGB(). Used to solve conflicts if
    // foreground and background are mapped to same color.
    // Defaults to 1:1 identity. Not needed if all colors actually 
    // supported by OSD.

    int GetColorIndex(enumTeletextColor ttc, int Area) {
        // Map this teletext color to an OSD color index in #Area.
        if (!osd) return 0;
        cBitmap *bm=osd->GetBitmap(Area);
        if (!bm) return 0;
        return bm->Index(GetColorRGB(ttc,Area));
    }
        
    int GetColorIndexAlternate(enumTeletextColor ttc, int Area) {
        // Map this teletext color to an OSD color index in #Area.
        if (!osd) return 0;
        cBitmap *bm=osd->GetBitmap(Area);
        if (!bm) return 0;
        return bm->Index(GetColorRGBAlternate(ttc,Area));
    }

        
    
protected:
    void InitPalette();
    // Initialize palette(s) for OSD

    void DrawDisplay();
    // Draw all dirty characters from cRenderPage buffer to OSD
    
    void CleanDisplay();
    // Clean OSD completely
    
    virtual void DrawChar(int x, int y, cTeletextChar c);
    // Draw a single character to OSD
    

public:
    void HoldFlush() { FlushLock++; }
    // Hold all OSD flush updates to bundle operations.
    
    void ReleaseFlush() { FlushLock--; Flush(); }
    // Release hold of flush updates. After last release,
    // the flush will be done

protected:
    void Flush() {
        // Commit all changes from OSD internal bitmaps to device
        // All draw operations inside cDisplay should call it,
        // no one outside should need to call it.
        
        if (FlushLock>0) return;
        if (!osd) return;
        if (IsDirty()) DrawDisplay();
        osd->Flush();
    }

public: 
    void RenderTeletextCode(unsigned char *PageCode);
    // Interprete teletext code referenced by PageCode
    // and draw the whole page content into OSD.
    // PageCode must be a 40*24+12 bytes buffer

    void DrawText(int x, int y, const char *text, int len);
    // Draw some characters in teletext page.
    // Max len chars, fill up with spaces
    
    void DrawClock();
    // Draw current time to OSD
    
    void DrawPageId(const char *text)   
        { DrawText(0,0,text,8); }
    // Draw Page ID string to OSD   
        
    void DrawMessage(const char *txt);
    // Draw a framed, centered message box to OSD
    
    void ClearMessage();
    // Remove message box and redraw hidden content
};



inline void cDisplay::cBox::SetToCharacter(int x, int y) {
    // Virtual box area of a character
    XMin=(x*12)<<16;
    YMin=(y*10)<<16;
    XMax=XMin+(12<<16)-1;
    YMax=YMin+(10<<16)-1;
}

inline void cDisplay::cVirtualCoordinate::VirtualToPixel(cDisplay *Display, int x, int y) {
    // Map virtual coordinate to OSD pixel  
    OsdX=x/Display->ScaleX+Display->OffsetX;
    OsdY=y/Display->ScaleY+Display->OffsetY;
    
    // map OSD pixel back to virtual coordinate, use center of pixel
    VirtX=(OsdX-Display->OffsetX)*Display->ScaleX+Display->ScaleX/2;
    VirtY=(OsdY-Display->OffsetY)*Display->ScaleY+Display->ScaleY/2;
}

inline void cDisplay::cVirtualCoordinate::IncPixelX(cDisplay *Display) {
    // Move one OSD pixel
    OsdX++;
    VirtX+=Display->ScaleX;
}
inline void cDisplay::cVirtualCoordinate::IncPixelY(cDisplay *Display) {
    // Move one OSD pixel
    OsdY++;
    VirtY+=Display->ScaleY;
}

#endif