VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpTxt.cpp@ 44528

Last change on this file since 44528 was 44528, checked in by vboxsync, 12 years ago

header (C) fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.1 KB
Line 
1/* $Id: VBoxDispVrdpTxt.cpp 44528 2013-02-04 14:27:54Z vboxsync $ */
2
3/** @file
4 * VBox XPDM Display driver
5 */
6
7/*
8 * Copyright (C) 2012 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "VBoxDisp.h"
20#include <VBox/RemoteDesktop/VRDEOrders.h>
21#include <iprt/crc.h>
22
23/*
24 * The client's glyph cache theoretically consists of 10 caches:
25 * cache index: 0 1 2 3 4 5 6 7 8 9
26 * glyph size (max): 0x4 0x4 0x8 0x8 0x10 0x20 0x40 0x80 0x100 0x800
27 * glyphs: 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0x40
28 *
29 * Glyph size is the size of the 1 BPP glyph bitmap bytes rounded up to 32 bit dword:
30 * glyph size = (((w + 7) / 8) * h + 3) & ~3
31 *
32 * Following simplifications are used:
33 * * Cache index 9 is not used, such huge glyphs (~40x40 pixel) are unlikely,
34 * (especially for raster fonts) so without it all caches contain up to 0xfe
35 * characters.
36 * * Maximum string length is 0xfe, so a string can always
37 * be placed in the cache, even if the string consists of
38 * all different characters.
39 *
40 * The driver always sends glyphs to the host.
41 * The host maintains the glyph cache. Performance issues:
42 * - increased the CPU load to copy glyph info.
43 * + eliminates the driver side of the cache.
44 * + lets the host to optimize memory usage.
45 *
46 * Therefore, on a textout the driver must send to the host
47 * The string attributes:
48 * - number of glyphs;
49 * - flags: HORIZONTAL, VERTICAL, CHAR_INC_EQUAL_BM_BASE, ... (1);
50 * - glyph increment for monospaced font (== 0 for not monospaced font) or a flag fMonospaced;
51 * - the bounding box of the string background (prclOpaque or the pstro->rclBkGround);
52 * - the foreground and background colors;
53 * - the mix (two ROP2);
54 * - ... (1).
55 * The glyph information for each glyph in the string:
56 * - unique glyph handle 64 bit for use of crc64;
57 * - the glyph bitmap coordinates on the screen;
58 * - width, height of the glyph;
59 * - the glyph origin in the bitmap (2);
60 * - the 1BPP glyph bitmap;
61 * - whether it is a 'space' character (3);
62 * - ... (1).
63 *
64 * Remarks:
65 * (1) to be defined;
66 * (2) might be not necessary;
67 * (3) it seems to be not necessary to know the codepoint value,
68 * strings are considered to be a set of bitmaps from
69 * the cache space. But reporting that the glyph actually
70 * represents a 'space' character might allow some optimizations.
71 *
72 * The VRDEORDERTEXT consists of the string info and glyph infos.
73 *
74 */
75
76static BOOL vrdpReportGlyph(GLYPHPOS *pGlyphPos, uint8_t **ppu8Ptr, uint8_t *pu8End)
77{
78 uint32_t cbOrder;
79 uint32_t cbBitmap;
80
81 VRDEORDERGLYPH *pOrder = (VRDEORDERGLYPH *)*ppu8Ptr;
82
83 GLYPHBITS *pgb = pGlyphPos->pgdf->pgb;
84
85 /* BYTE-aligned 1BPP bitmap of the glyph. The array includes padding at the end to DWORD-align. */
86 cbBitmap = (pgb->sizlBitmap.cx + 7) / 8; /* Line size in bytes. */
87 cbBitmap *= pgb->sizlBitmap.cy; /* Size of bitmap. */
88 cbBitmap = (cbBitmap + 3) & ~3; /* DWORD align. */
89
90 cbOrder = (uint32_t)((uint8_t *)&pOrder->au8Bitmap - (uint8_t *)pOrder);
91
92 cbOrder += cbBitmap;
93
94 if (*ppu8Ptr + cbOrder > pu8End)
95 {
96 return FALSE;
97 }
98
99 pOrder->o32NextGlyph = cbOrder;
100
101 pOrder->u64Handle = RTCrc64Start();
102 pOrder->u64Handle = RTCrc64Process(pOrder->u64Handle, pgb->aj, cbBitmap);
103 pOrder->u64Handle = RTCrc64Process(pOrder->u64Handle, &pgb->ptlOrigin, sizeof (pgb->ptlOrigin));
104 pOrder->u64Handle = RTCrc64Finish(pOrder->u64Handle);
105
106 pOrder->x = (int16_t)pGlyphPos->ptl.x;
107 pOrder->y = (int16_t)pGlyphPos->ptl.y;
108
109 pOrder->w = (uint16_t)pgb->sizlBitmap.cx;
110 pOrder->h = (uint16_t)pgb->sizlBitmap.cy;
111
112 pOrder->xOrigin = (int16_t)pgb->ptlOrigin.x;
113 pOrder->yOrigin = (int16_t)pgb->ptlOrigin.y;
114
115 /* 1BPP bitmap. Rows are byte aligned. Size is (((w + 7)/8) * h + 3) & ~3. */
116 memcpy (pOrder->au8Bitmap, pgb->aj, cbBitmap);
117
118 *ppu8Ptr += cbOrder;
119
120 return TRUE;
121}
122
123static uint32_t vrdpSizeofTextOrder(ULONG cGlyphs, ULONG cbMaxGlyph)
124{
125 uint32_t cb = sizeof (VRDEORDERTEXT);
126
127 cb += cGlyphs * (sizeof (VRDEORDERGLYPH) + cbMaxGlyph);
128
129 return cb;
130}
131
132BOOL vrdpReportText(PVBOXDISPDEV pDev, VRDPCLIPRECTS *pClipRects, STROBJ *pstro, FONTOBJ *pfo,
133 RECTL *prclOpaque, ULONG ulForeRGB, ULONG ulBackRGB)
134{
135 FONTINFO fi;
136 uint32_t cbOrderMax;
137 VRDEORDERTEXT *pOrder;
138 BOOL fResult;
139 uint8_t *pu8GlyphPtr;
140 uint8_t *pu8GlyphEnd;
141
142 LOGF(("pDev %p, pClipRects %p, pstro %p, pfo %p, prclOpaque %p, ulForeRGB %x, ulBackRGB %x",
143 pDev, pClipRects, pstro, pfo, prclOpaque, ulForeRGB, ulBackRGB));
144
145 if (pstro->ulCharInc > 0xFF)
146 {
147 return FALSE;
148 }
149
150 /* The driver can get vertical strings with both SO_HORIZONTAL and SO_VERTICAL bits equal to zero. */
151 if ( (pstro->flAccel & SO_HORIZONTAL) == 0
152 || (pstro->flAccel & SO_REVERSED) != 0)
153 {
154 /* Do not support (yet) the vertical and right to left strings.
155 * @todo implement and test.
156 */
157 return FALSE;
158 }
159
160 memset (&fi, 0, sizeof (fi));
161
162 FONTOBJ_vGetInfo (pfo, sizeof (fi), &fi);
163
164 if ( fi.cjMaxGlyph1 == 0
165 || fi.cjMaxGlyph1 > VRDP_TEXT_MAX_GLYPH_SIZE)
166 {
167 /* No 1BPP bitmaps or the bitmap is larger than the cache supports. */
168 LOG(("fi.cjMaxGlyph1 = %x. Return FALSE", fi.cjMaxGlyph1));
169 return FALSE;
170 }
171
172 cbOrderMax = vrdpSizeofTextOrder(pstro->cGlyphs, fi.cjMaxGlyph1);
173
174 LOG(("pstro->cGlyphs = %d, fi.cjMaxGlyph1 = 0x%x, cbOrderMax = 0x%x.", pstro->cGlyphs, fi.cjMaxGlyph1, cbOrderMax));
175
176 pOrder = (VRDEORDERTEXT *)EngAllocMem(0, cbOrderMax, MEM_ALLOC_TAG);
177
178 if (!pOrder)
179 {
180 LOG(("pOrder = %x. Return FALSE", pOrder));
181 return FALSE;
182 }
183
184 pu8GlyphPtr = (uint8_t *)&pOrder[1]; /* Follows the order header. */
185 pu8GlyphEnd = (uint8_t *)pOrder + cbOrderMax;
186
187 pOrder->xBkGround = (int16_t)pstro->rclBkGround.left;
188 pOrder->yBkGround = (int16_t)pstro->rclBkGround.top;
189 pOrder->wBkGround = (uint16_t)(pstro->rclBkGround.right - pstro->rclBkGround.left);
190 pOrder->hBkGround = (uint16_t)(pstro->rclBkGround.bottom - pstro->rclBkGround.top);
191
192 if (prclOpaque)
193 {
194 pOrder->xOpaque = (int16_t)prclOpaque->left;
195 pOrder->yOpaque = (int16_t)prclOpaque->top;
196 pOrder->wOpaque = (uint16_t)(prclOpaque->right - prclOpaque->left);
197 pOrder->hOpaque = (uint16_t)(prclOpaque->bottom - prclOpaque->top);
198 }
199 else
200 {
201 pOrder->xOpaque = 0;
202 pOrder->yOpaque = 0;
203 pOrder->wOpaque = 0;
204 pOrder->hOpaque = 0;
205 }
206
207 pOrder->u16MaxGlyph = (uint16_t)fi.cjMaxGlyph1;
208
209 pOrder->u8Glyphs = (uint8_t)pstro->cGlyphs;
210
211 pOrder->u8Flags = (uint8_t)pstro->flAccel;
212
213 pOrder->u8CharInc = (uint8_t)pstro->ulCharInc;
214
215 pOrder->u32FgRGB = ulForeRGB;
216 pOrder->u32BgRGB = ulBackRGB;
217
218 LOG(("pstro->pgp %p.", pstro->pgp));
219
220 /* Enumerate glyphs. */
221 STROBJ_vEnumStart(pstro);
222
223 fResult = TRUE;
224
225 for (;;)
226 {
227 ULONG i;
228 ULONG cGlyphs = 0;
229 GLYPHPOS *pGlyphPos = NULL;
230
231 BOOL fMore = STROBJ_bEnum (pstro, &cGlyphs, &pGlyphPos);
232
233 LOG(("cGlyphs %d.", cGlyphs));
234
235 for (i = 0; i < cGlyphs; i++)
236 {
237 fResult = vrdpReportGlyph(&pGlyphPos[i], &pu8GlyphPtr, pu8GlyphEnd);
238
239 if (!fResult)
240 {
241 break;
242 }
243 }
244
245 if (!fMore || !fResult)
246 {
247 break;
248 }
249 }
250
251 LOG(("fResult %d", fResult));
252
253 if (fResult)
254 {
255 pOrder->cbOrder = (uint32_t)(pu8GlyphPtr - (uint8_t *)pOrder);
256
257 vrdpReportOrderGeneric(pDev, pClipRects, pOrder, pOrder->cbOrder, VRDE_ORDER_TEXT);
258 }
259
260 EngFreeMem(pOrder);
261
262 return fResult;
263}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette