~ubuntu-branches/ubuntu/vivid/freerdp/vivid

« back to all changes in this revision

Viewing changes to libfreerdp/gdi/graphics.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-11-11 12:20:50 UTC
  • mfrom: (1.2.5)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20141111122050-7z628f4ab38qxad5
Tags: upstream-1.1.0~git20140921.1.440916e+dfsg1
ImportĀ upstreamĀ versionĀ 1.1.0~git20140921.1.440916e+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * FreeRDP: A Remote Desktop Protocol Implementation
 
3
 * Graphical Objects
 
4
 *
 
5
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
 
6
 *
 
7
 * Licensed under the Apache License, Version 2.0 (the "License");
 
8
 * you may not use this file except in compliance with the License.
 
9
 * You may obtain a copy of the License at
 
10
 *
 
11
 *     http://www.apache.org/licenses/LICENSE-2.0
 
12
 *
 
13
 * Unless required by applicable law or agreed to in writing, software
 
14
 * distributed under the License is distributed on an "AS IS" BASIS,
 
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
16
 * See the License for the specific language governing permissions and
 
17
 * limitations under the License.
 
18
 */
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include "config.h"
 
22
#endif
 
23
 
 
24
#include <winpr/crt.h>
 
25
 
 
26
#include <freerdp/gdi/dc.h>
 
27
#include <freerdp/gdi/brush.h>
 
28
#include <freerdp/gdi/shape.h>
 
29
#include <freerdp/gdi/region.h>
 
30
#include <freerdp/gdi/bitmap.h>
 
31
#include <freerdp/codec/jpeg.h>
 
32
#include <freerdp/codec/rfx.h>
 
33
#include <freerdp/codec/nsc.h>
 
34
#include <freerdp/gdi/drawing.h>
 
35
#include <freerdp/gdi/clipping.h>
 
36
#include <freerdp/codec/color.h>
 
37
#include <freerdp/codec/bitmap.h>
 
38
#include <freerdp/codec/bitmap.h>
 
39
#include <freerdp/cache/glyph.h>
 
40
 
 
41
#include "graphics.h"
 
42
 
 
43
/* Bitmap Class */
 
44
 
 
45
HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, int width, int height, int bpp, BYTE* data)
 
46
{
 
47
        BYTE* bmpData;
 
48
        HGDI_BITMAP bitmap;
 
49
 
 
50
        bmpData = freerdp_image_convert(data, NULL, width, height, gdi->srcBpp, bpp, gdi->clrconv);
 
51
        bitmap = gdi_CreateBitmap(width, height, gdi->dstBpp, bmpData);
 
52
 
 
53
        return bitmap;
 
54
}
 
55
 
 
56
void gdi_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
 
57
{
 
58
        gdiBitmap* gdi_bitmap;
 
59
        rdpGdi* gdi = context->gdi;
 
60
 
 
61
        gdi_bitmap = (gdiBitmap*) bitmap;
 
62
        gdi_bitmap->hdc = gdi_CreateCompatibleDC(gdi->hdc);
 
63
 
 
64
        if (bitmap->data == NULL)
 
65
                gdi_bitmap->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, bitmap->width, bitmap->height);
 
66
        else
 
67
                gdi_bitmap->bitmap = gdi_create_bitmap(gdi, bitmap->width, bitmap->height, gdi->dstBpp, bitmap->data);
 
68
 
 
69
        gdi_SelectObject(gdi_bitmap->hdc, (HGDIOBJECT) gdi_bitmap->bitmap);
 
70
        gdi_bitmap->org_bitmap = NULL;
 
71
}
 
72
 
 
73
void gdi_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
 
74
{
 
75
        gdiBitmap* gdi_bitmap = (gdiBitmap*) bitmap;
 
76
 
 
77
        if (gdi_bitmap != NULL)
 
78
        {
 
79
                gdi_SelectObject(gdi_bitmap->hdc, (HGDIOBJECT) gdi_bitmap->org_bitmap);
 
80
                gdi_DeleteObject((HGDIOBJECT) gdi_bitmap->bitmap);
 
81
                gdi_DeleteDC(gdi_bitmap->hdc);
 
82
        }
 
83
}
 
84
 
 
85
void gdi_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
 
86
{
 
87
        int width, height;
 
88
        gdiBitmap* gdi_bitmap = (gdiBitmap*) bitmap;
 
89
 
 
90
        width = bitmap->right - bitmap->left + 1;
 
91
        height = bitmap->bottom - bitmap->top + 1;
 
92
 
 
93
        gdi_BitBlt(context->gdi->primary->hdc, bitmap->left, bitmap->top,
 
94
                        width, height, gdi_bitmap->hdc, 0, 0, GDI_SRCCOPY);
 
95
}
 
96
 
 
97
void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
 
98
                BYTE* data, int width, int height, int bpp, int length,
 
99
                BOOL compressed, int codec_id)
 
100
{
 
101
        UINT16 size;
 
102
        RFX_MESSAGE* msg;
 
103
        BYTE* src;
 
104
        BYTE* dst;
 
105
        int yindex;
 
106
        int xindex;
 
107
        rdpGdi* gdi;
 
108
        BOOL status;
 
109
 
 
110
        size = width * height * ((bpp + 7) / 8);
 
111
 
 
112
        if (bitmap->data == NULL)
 
113
                bitmap->data = (BYTE*) malloc(size);
 
114
        else
 
115
                bitmap->data = (BYTE*) realloc(bitmap->data, size);
 
116
 
 
117
        switch (codec_id)
 
118
        {
 
119
                case RDP_CODEC_ID_NSCODEC:
 
120
                        gdi = context->gdi;
 
121
                        nsc_process_message(gdi->nsc_context, bpp, width, height, data, length);
 
122
                        freerdp_image_flip(((NSC_CONTEXT*)gdi->nsc_context)->bmpdata, bitmap->data, width, height, bpp);
 
123
                        break;
 
124
                case RDP_CODEC_ID_REMOTEFX:
 
125
                        gdi = context->gdi;
 
126
                        rfx_context_set_pixel_format(gdi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
 
127
                        msg = rfx_process_message(gdi->rfx_context, data, length);
 
128
                        if (msg == NULL)
 
129
                        {
 
130
                                fprintf(stderr, "gdi_Bitmap_Decompress: rfx Decompression Failed\n");
 
131
                        }
 
132
                        else
 
133
                        {
 
134
                                for (yindex = 0; yindex < height; yindex++)
 
135
                                {
 
136
                                        src = msg->tiles[0]->data + yindex * 64 * 4;
 
137
                                        dst = bitmap->data + yindex * width * 3;
 
138
                                        for (xindex = 0; xindex < width; xindex++)
 
139
                                        {
 
140
                                                *(dst++) = *(src++);
 
141
                                                *(dst++) = *(src++);
 
142
                                                *(dst++) = *(src++);
 
143
                                                src++;
 
144
                                        }
 
145
                                }
 
146
                                rfx_message_free(gdi->rfx_context, msg);
 
147
                        }
 
148
                        break;
 
149
                case RDP_CODEC_ID_JPEG:
 
150
#ifdef WITH_JPEG
 
151
                        if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
 
152
                        {
 
153
                                fprintf(stderr, "gdi_Bitmap_Decompress: jpeg Decompression Failed\n");
 
154
                        }
 
155
#endif
 
156
                        break;
 
157
                default:
 
158
                        if (compressed)
 
159
                        {
 
160
                                status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);
 
161
 
 
162
                                if (status == FALSE)
 
163
                                {
 
164
                                        fprintf(stderr, "gdi_Bitmap_Decompress: Bitmap Decompression Failed\n");
 
165
                                }
 
166
                        }
 
167
                        else
 
168
                        {
 
169
                                freerdp_image_flip(data, bitmap->data, width, height, bpp);
 
170
                        }
 
171
                        break;
 
172
        }
 
173
 
 
174
        bitmap->width = width;
 
175
        bitmap->height = height;
 
176
        bitmap->compressed = FALSE;
 
177
        bitmap->length = size;
 
178
        bitmap->bpp = bpp;
 
179
}
 
180
 
 
181
void gdi_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)
 
182
{
 
183
        rdpGdi* gdi = context->gdi;
 
184
 
 
185
        if (primary)
 
186
                gdi->drawing = gdi->primary;
 
187
        else
 
188
                gdi->drawing = (gdiBitmap*) bitmap;
 
189
}
 
190
 
 
191
/* Glyph Class */
 
192
 
 
193
void gdi_Glyph_New(rdpContext* context, rdpGlyph* glyph)
 
194
{
 
195
        BYTE* data;
 
196
        gdiGlyph* gdi_glyph;
 
197
 
 
198
        gdi_glyph = (gdiGlyph*) glyph;
 
199
 
 
200
        gdi_glyph->hdc = gdi_GetDC();
 
201
        gdi_glyph->hdc->bytesPerPixel = 1;
 
202
        gdi_glyph->hdc->bitsPerPixel = 1;
 
203
 
 
204
        data = freerdp_glyph_convert(glyph->cx, glyph->cy, glyph->aj);
 
205
        gdi_glyph->bitmap = gdi_CreateBitmap(glyph->cx, glyph->cy, 1, data);
 
206
        gdi_glyph->bitmap->bytesPerPixel = 1;
 
207
        gdi_glyph->bitmap->bitsPerPixel = 1;
 
208
 
 
209
        gdi_SelectObject(gdi_glyph->hdc, (HGDIOBJECT) gdi_glyph->bitmap);
 
210
        gdi_glyph->org_bitmap = NULL;
 
211
}
 
212
 
 
213
void gdi_Glyph_Free(rdpContext* context, rdpGlyph* glyph)
 
214
{
 
215
        gdiGlyph* gdi_glyph;
 
216
 
 
217
        gdi_glyph = (gdiGlyph*) glyph;
 
218
 
 
219
        if (gdi_glyph != 0)
 
220
        {
 
221
                gdi_SelectObject(gdi_glyph->hdc, (HGDIOBJECT) gdi_glyph->org_bitmap);
 
222
                gdi_DeleteObject((HGDIOBJECT) gdi_glyph->bitmap);
 
223
                gdi_DeleteDC(gdi_glyph->hdc);
 
224
        }
 
225
}
 
226
 
 
227
void gdi_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y)
 
228
{
 
229
        gdiGlyph* gdi_glyph;
 
230
        rdpGdi* gdi = context->gdi;
 
231
 
 
232
        gdi_glyph = (gdiGlyph*) glyph;
 
233
 
 
234
        gdi_BitBlt(gdi->drawing->hdc, x, y, gdi_glyph->bitmap->width,
 
235
                        gdi_glyph->bitmap->height, gdi_glyph->hdc, 0, 0, GDI_DSPDxax);
 
236
}
 
237
 
 
238
void gdi_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor)
 
239
{
 
240
        GDI_RECT rect;
 
241
        HGDI_BRUSH brush;
 
242
        rdpGdi* gdi = context->gdi;
 
243
 
 
244
        bgcolor = freerdp_color_convert_var_bgr(bgcolor, gdi->srcBpp, 32, gdi->clrconv);
 
245
        fgcolor = freerdp_color_convert_var_bgr(fgcolor, gdi->srcBpp, 32, gdi->clrconv);
 
246
 
 
247
        gdi_CRgnToRect(x, y, width, height, &rect);
 
248
 
 
249
        brush = gdi_CreateSolidBrush(fgcolor);
 
250
        gdi_FillRect(gdi->drawing->hdc, &rect, brush);
 
251
        gdi_DeleteObject((HGDIOBJECT) brush);
 
252
 
 
253
        gdi->textColor = gdi_SetTextColor(gdi->drawing->hdc, bgcolor);
 
254
}
 
255
 
 
256
void gdi_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor)
 
257
{
 
258
        rdpGdi* gdi = context->gdi;
 
259
 
 
260
        bgcolor = freerdp_color_convert_var_bgr(bgcolor, gdi->srcBpp, 32, gdi->clrconv);
 
261
        gdi->textColor = gdi_SetTextColor(gdi->drawing->hdc, bgcolor);
 
262
}
 
263
 
 
264
/* Graphics Module */
 
265
 
 
266
void gdi_register_graphics(rdpGraphics* graphics)
 
267
{
 
268
        rdpBitmap* bitmap;
 
269
        rdpGlyph* glyph;
 
270
 
 
271
        bitmap = (rdpBitmap*) malloc(sizeof(rdpBitmap));
 
272
        ZeroMemory(bitmap, sizeof(rdpBitmap));
 
273
        bitmap->size = sizeof(gdiBitmap);
 
274
 
 
275
        bitmap->New = gdi_Bitmap_New;
 
276
        bitmap->Free = gdi_Bitmap_Free;
 
277
        bitmap->Paint = gdi_Bitmap_Paint;
 
278
        bitmap->Decompress = gdi_Bitmap_Decompress;
 
279
        bitmap->SetSurface = gdi_Bitmap_SetSurface;
 
280
 
 
281
        graphics_register_bitmap(graphics, bitmap);
 
282
        free(bitmap);
 
283
 
 
284
        glyph = (rdpGlyph*) malloc(sizeof(rdpGlyph));
 
285
        ZeroMemory(glyph, sizeof(rdpGlyph));
 
286
        glyph->size = sizeof(gdiGlyph);
 
287
 
 
288
        glyph->New = gdi_Glyph_New;
 
289
        glyph->Free = gdi_Glyph_Free;
 
290
        glyph->Draw = gdi_Glyph_Draw;
 
291
        glyph->BeginDraw = gdi_Glyph_BeginDraw;
 
292
        glyph->EndDraw = gdi_Glyph_EndDraw;
 
293
 
 
294
        graphics_register_glyph(graphics, glyph);
 
295
        free(glyph);
 
296
}