~ubuntu-branches/ubuntu/trusty/gnustep-back/trusty

« back to all changes in this revision

Viewing changes to Source/winlib/WIN32GState.m

  • Committer: Bazaar Package Importer
  • Author(s): Yavor Doganov
  • Date: 2010-09-08 18:35:17 UTC
  • mfrom: (1.2.7 upstream) (4.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20100908183517-kw4doaizdh29qdd9
* debian/control.m4 (gnustep-back-common) <Depends>: Add ttf-freefont
  (Closes: #596059).
* debian/control: Regenerate.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
// Define this so we pick up AlphaBlend, when loading windows.h
33
33
#ifdef USE_ALPHABLEND
34
 
#define WINVER 0x0500
 
34
#if     !defined(WINVER)
 
35
#define WINVER 0x0500
 
36
#elif (WINVER < 0x0500)
 
37
#undef  WINVER
 
38
#define WINVER 0x0500
 
39
#endif
35
40
#endif
36
41
 
37
42
#include <AppKit/NSAffineTransform.h>
111
116
  return GSWindowRectToMS(s, r);
112
117
}
113
118
 
 
119
void* get_bits(HDC dc,
 
120
               int w,
 
121
               int h,
 
122
               HBITMAP *bitmap)
 
123
{
 
124
  void          *bits = NULL;
 
125
  BITMAPINFO     info;
 
126
  HDC            cDC;
 
127
 
 
128
  info.bmiHeader.biSize = sizeof(BITMAPINFO);
 
129
  info.bmiHeader.biWidth = w;
 
130
  info.bmiHeader.biHeight = h;
 
131
  info.bmiHeader.biPlanes = 1;
 
132
  info.bmiHeader.biBitCount = 32;
 
133
  info.bmiHeader.biCompression = BI_RGB;
 
134
  info.bmiHeader.biSizeImage = 0;
 
135
  info.bmiHeader.biXPelsPerMeter = 0;
 
136
  info.bmiHeader.biYPelsPerMeter = 0;
 
137
  info.bmiHeader.biClrUsed = 0;
 
138
  info.bmiHeader.biClrImportant = 0;
 
139
 
 
140
  if(!(cDC = CreateCompatibleDC(dc)))
 
141
    {
 
142
      NSLog(@"Could not create compatible DC");
 
143
      return NULL;
 
144
    }
 
145
  
 
146
  if(!(*bitmap = CreateDIBSection(dc, (LPBITMAPINFO)&info, 
 
147
                                  DIB_RGB_COLORS, &bits, 
 
148
                                  NULL, 0)))
 
149
    {
 
150
      NSLog(@"Could not create bit map from DC");
 
151
      return NULL;
 
152
    }
 
153
  
 
154
  SelectObject(cDC, *bitmap);
 
155
  
 
156
  return bits;
 
157
}
 
158
 
 
159
BOOL alpha_blend_source_over(HDC destDC, 
 
160
                             HDC srcDC, 
 
161
                             RECT rectFrom, 
 
162
                             int x, int y, int w, int h, 
 
163
                             float delta)
 
164
{
 
165
  BOOL success = YES;
 
166
 
 
167
#ifdef USE_ALPHABLEND
 
168
  // Use (0..1) fraction to set a (0..255) alpha constant value
 
169
  BYTE SourceConstantAlpha = (BYTE)(delta * 255);
 
170
  BLENDFUNCTION blendFunc
 
171
    = {AC_SRC_OVER, 0, SourceConstantAlpha, AC_SRC_ALPHA};
 
172
 
 
173
  /* There is actually a very real chance this could fail, even on 
 
174
     computers that supposedly support it. It's not known why it
 
175
     fails though... */
 
176
  success = AlphaBlend(destDC,
 
177
                       x, y, w, h,
 
178
                       srcDC,
 
179
                       rectFrom.left, rectFrom.top,
 
180
                       w, h, blendFunc);
 
181
  // #else
 
182
  // HBITMAP    sbitmap;
 
183
  // HBITMAP    dbitmap; 
 
184
  // unsigned char *sbits = (unsigned char *)get_bits(srcDC,w,h,&sbitmap);
 
185
  // unsigned char *dbits = (unsigned char *)get_bits(destDC,w,h,&dbitmap);
 
186
 
 
187
#endif
 
188
 
 
189
  return success;
 
190
}
 
191
 
114
192
@interface WIN32GState (WinOps)
115
193
- (void) setStyle: (HDC)hDC;
116
194
- (void) restoreStyle: (HDC)hDC;
205
283
 
206
284
    [source->ctm boundingRectFor: sourceRect result: &newRect];
207
285
    rectFrom = GSWindowRectToMS(source, newRect);
 
286
    y += (sourceRect.size.height - newRect.size.height); // adjust location for scaled source
208
287
  }
209
288
  h = rectFrom.bottom - rectFrom.top;
210
289
  w = rectFrom.right - rectFrom.left;
233
312
    {
234
313
    case NSCompositeSourceOver:
235
314
      {
236
 
#ifdef USE_ALPHABLEND
237
 
        // Use (0..1) fraction to set a (0..255) alpha constant value
238
 
        BYTE SourceConstantAlpha = (BYTE)(delta * 255);
239
 
        BLENDFUNCTION blendFunc
240
 
            = {AC_SRC_OVER, 0, SourceConstantAlpha, AC_SRC_ALPHA};
241
 
        success = AlphaBlend(hDC,
242
 
                             x, y, w, h,
243
 
                             sourceDC,
244
 
                             rectFrom.left, rectFrom.top,
245
 
                             w, h, blendFunc);
246
 
        /* There is actually a very real chance this could fail, even on 
247
 
           computers that supposedly support it. It's not known why it
248
 
           fails though... */
249
 
        if (success)
250
 
            break;
251
 
#endif
 
315
        success = alpha_blend_source_over(hDC, 
 
316
                                          sourceDC, 
 
317
                                          rectFrom, 
 
318
                                          x, y, w, h, 
 
319
                                          delta);
 
320
        if (success)
 
321
          break;
252
322
      }
253
323
    case NSCompositeCopy:
254
324
      {
282
352
  [source releaseHDC: sourceDC];
283
353
}
284
354
 
285
 
- (void) compositeGState: (GSGState *)source 
286
 
                fromRect: (NSRect)aRect
287
 
                 toPoint: (NSPoint)aPoint
288
 
                      op: (NSCompositingOperation)op
289
 
{
290
 
  [self compositeGState: (WIN32GState *) source
291
 
               fromRect: aRect
292
 
                toPoint: aPoint
293
 
                     op: op
294
 
               fraction: 1.0];
295
 
}
296
 
 
297
 
- (void) dissolveGState: (GSGState *)source
298
 
               fromRect: (NSRect)aRect
299
 
                toPoint: (NSPoint)aPoint 
300
 
                  delta: (float)delta
301
 
{
302
 
  [self compositeGState: (WIN32GState *) source
303
 
               fromRect: aRect
304
 
                toPoint: aPoint
305
 
                     op: NSCompositeSourceOver
306
 
               fraction: delta];
307
 
}
308
 
 
309
355
- (void) compositerect: (NSRect)aRect
310
356
                    op: (NSCompositingOperation)op
311
357
{
312
358
  float gray;
 
359
  BOOL success = NO;
313
360
 
314
361
  // FIXME: This is taken from the xlib backend
315
362
  [self DPScurrentgray: &gray];
747
794
      switch (drawType)
748
795
        {
749
796
        case path_stroke:
750
 
          StrokePath(hDC);
 
797
          if (strokeColor.field[AINDEX] != 0.0)
 
798
            {
 
799
              StrokePath(hDC);
 
800
            }
751
801
          break;
752
802
        case path_eofill:
753
 
          SetPolyFillMode(hDC, ALTERNATE);
754
 
          FillPath(hDC);
 
803
          if (fillColor.field[AINDEX] != 0.0)
 
804
            {
 
805
              SetPolyFillMode(hDC, ALTERNATE);
 
806
              FillPath(hDC);
 
807
            }
755
808
          break;
756
809
        case path_fill:
757
 
          SetPolyFillMode(hDC, WINDING);
758
 
          FillPath(hDC);
 
810
          if (fillColor.field[AINDEX] != 0.0)
 
811
            {
 
812
              SetPolyFillMode(hDC, WINDING);
 
813
              FillPath(hDC);
 
814
            }
759
815
          break;
760
816
        case path_eoclip:
761
817
          {
764
820
            SetPolyFillMode(hDC, ALTERNATE);
765
821
            region = PathToRegion(hDC);
766
822
            if (clipRegion)
767
 
            {
768
 
              CombineRgn(clipRegion, clipRegion, region, RGN_AND);
769
 
              DeleteObject(region);
770
 
            }
 
823
              {
 
824
                CombineRgn(clipRegion, clipRegion, region, RGN_AND);
 
825
                DeleteObject(region);
 
826
              }
771
827
            else
772
828
              {
773
829
                clipRegion = region;
781
837
            SetPolyFillMode(hDC, WINDING);
782
838
            region = PathToRegion(hDC);
783
839
            if (clipRegion)
784
 
            {
785
 
              CombineRgn(clipRegion, clipRegion, region, RGN_AND);
786
 
              DeleteObject(region);
787
 
            }
 
840
              {
 
841
                CombineRgn(clipRegion, clipRegion, region, RGN_AND);
 
842
                DeleteObject(region);
 
843
              }
788
844
            else
789
845
              {
790
846
                clipRegion = region;
819
875
 
820
876
- (void)DPSeofill 
821
877
{
 
878
  if (pattern != nil)
 
879
    {
 
880
      [self eofillPath: path withPattern: pattern];
 
881
      return;
 
882
    }
822
883
  [self _paintPath: path_eofill];
823
884
}
824
885
 
825
886
- (void)DPSfill 
826
887
{
 
888
  if (pattern != nil)
 
889
    {
 
890
      [self fillPath: path withPattern: pattern];
 
891
      return;
 
892
    }
 
893
 
827
894
  [self _paintPath: path_fill];
828
895
}
829
896
 
1127
1194
}
1128
1195
 
1129
1196
@end
 
1197
 
 
1198
 
 
1199
@implementation WIN32GState (PatternColor)
 
1200
 
 
1201
- (void *) saveClip
 
1202
{
 
1203
  if (clipRegion)
 
1204
    {
 
1205
      HRGN newClipRegion;
 
1206
 
 
1207
      newClipRegion = CreateRectRgn(0, 0, 1, 1);
 
1208
      CombineRgn(newClipRegion, clipRegion, NULL, RGN_COPY);
 
1209
 
 
1210
      return newClipRegion;
 
1211
    }
 
1212
  return clipRegion;
 
1213
}
 
1214
 
 
1215
- (void) restoreClip: (void *)savedClip
 
1216
{
 
1217
  if (clipRegion)
 
1218
    {
 
1219
      DeleteObject(clipRegion);
 
1220
    }
 
1221
  clipRegion = savedClip;
 
1222
}
 
1223
 
 
1224
@end
 
1225
 
 
1226
@implementation WIN32GState (ReadRect)
 
1227
 
 
1228
- (NSDictionary *) GSReadRect: (NSRect)r
 
1229
{
 
1230
  NSMutableDictionary *dict;
 
1231
  NSAffineTransform *matrix;
 
1232
  double x, y;
 
1233
  NSMutableData *data;
 
1234
  unsigned char *cdata;
 
1235
  unsigned char *bits;
 
1236
  int i = 0;
 
1237
  HDC hDC;
 
1238
  HDC hdcMemDC = NULL;
 
1239
  HBITMAP hbitmap = NULL;
 
1240
  BITMAP bmpCopied;
 
1241
  HGDIOBJ old;
 
1242
  RECT rcClient;
 
1243
  DWORD dwBmpSize;
 
1244
  HANDLE hDIB;
 
1245
  LPBITMAPV4HEADER lpbi;
 
1246
 
 
1247
  if (window == NULL)
 
1248
    {
 
1249
      NSLog(@"No window in GSReadRect");
 
1250
      return nil;
 
1251
    }
 
1252
 
 
1253
  r = [ctm rectInMatrixSpace: r];
 
1254
  x = NSWidth(r);
 
1255
  y = NSHeight(r);
 
1256
 
 
1257
  dict = [NSMutableDictionary dictionary];
 
1258
  [dict setObject: NSDeviceRGBColorSpace forKey: @"ColorSpace"];
 
1259
 
 
1260
  [dict setObject: [NSNumber numberWithUnsignedInt: 8]
 
1261
           forKey: @"BitsPerSample"];
 
1262
  [dict setObject: [NSNumber numberWithUnsignedInt: 32]
 
1263
           forKey: @"Depth"];
 
1264
  [dict setObject: [NSNumber numberWithUnsignedInt: 4] 
 
1265
           forKey: @"SamplesPerPixel"];
 
1266
  [dict setObject: [NSNumber numberWithUnsignedInt: 1]
 
1267
           forKey: @"HasAlpha"];
 
1268
 
 
1269
  matrix = [self GSCurrentCTM];
 
1270
  [matrix translateXBy: -r.origin.x - offset.x 
 
1271
                   yBy: r.origin.y + NSHeight(r) - offset.y];
 
1272
  [dict setObject: matrix forKey: @"Matrix"];
 
1273
 
 
1274
  hDC = GetDC((HWND)window);
 
1275
  if (!hDC)
 
1276
    {
 
1277
      NSLog(@"No DC for window %d in GSReadRect. Error %d", 
 
1278
        (int)window, GetLastError());
 
1279
      return nil;
 
1280
    }
 
1281
 
 
1282
  // Create a compatible DC which is used in a BitBlt from the window DC
 
1283
  hdcMemDC = CreateCompatibleDC(hDC); 
 
1284
  if (!hdcMemDC)
 
1285
    {
 
1286
      NSLog(@"No Compatible DC for window %d in GSReadRect. Error %d", 
 
1287
        (int)window, GetLastError());
 
1288
      ReleaseDC((HWND)window, hDC);
 
1289
      return nil;
 
1290
    }
 
1291
 
 
1292
  ReleaseDC((HWND)window, hDC);
 
1293
  hDC = [self getHDC];
 
1294
 
 
1295
  // Get the client area for size calculation
 
1296
  rcClient = GSWindowRectToMS(self, r);
 
1297
 
 
1298
  // Create a compatible bitmap from the Window DC
 
1299
  hbitmap = CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left, 
 
1300
  rcClient.bottom - rcClient.top);
 
1301
  if (!hbitmap)
 
1302
    {
 
1303
      NSLog(@"No Compatible bitmap for window %d in GSReadRect. Error %d", 
 
1304
        (int)window, GetLastError());
 
1305
      ReleaseDC((HWND)window, hdcMemDC);
 
1306
      [self releaseHDC: hDC];
 
1307
      return nil;
 
1308
    }
 
1309
 
 
1310
  // Select the compatible bitmap into the compatible memory DC.
 
1311
  old = SelectObject(hdcMemDC, hbitmap);
 
1312
  if (!old)
 
1313
    {
 
1314
      NSLog(@"SelectObject failed for window %d in GSReadRect. Error %d", 
 
1315
        (int)window, GetLastError());
 
1316
      DeleteObject(hbitmap);
 
1317
      ReleaseDC((HWND)window, hdcMemDC);
 
1318
      [self releaseHDC: hDC];
 
1319
      return nil;
 
1320
    }
 
1321
 
 
1322
  // Bit block transfer into our compatible memory DC.
 
1323
  if (!BitBlt(hdcMemDC, 0, 0, 
 
1324
    rcClient.right - rcClient.left, 
 
1325
    rcClient.bottom - rcClient.top, 
 
1326
    hDC, 
 
1327
    0, 0,
 
1328
    SRCCOPY))
 
1329
    {
 
1330
      NSLog(@"BitBlt failed for window %d in GSReadRect. Error %d", 
 
1331
        (int)window, GetLastError());
 
1332
      DeleteObject(hbitmap);
 
1333
      ReleaseDC((HWND)window, hdcMemDC);
 
1334
      [self releaseHDC: hDC];
 
1335
      return nil;
 
1336
    }
 
1337
 
 
1338
  // Get the BITMAP from the HBITMAP
 
1339
  GetObject(hbitmap, sizeof(BITMAP), &bmpCopied);
 
1340
 
 
1341
  dwBmpSize = bmpCopied.bmWidth * 4 * bmpCopied.bmHeight;
 
1342
 
 
1343
  hDIB = GlobalAlloc(GHND, dwBmpSize + sizeof(BITMAPV4HEADER)); 
 
1344
  lpbi = (LPBITMAPV4HEADER)GlobalLock(hDIB);    
 
1345
  lpbi->bV4Size = sizeof(BITMAPV4HEADER);
 
1346
  lpbi->bV4V4Compression = BI_BITFIELDS;
 
1347
  lpbi->bV4BlueMask = 0x000000FF;
 
1348
  lpbi->bV4GreenMask = 0x0000FF00;
 
1349
  lpbi->bV4RedMask = 0x00FF0000;
 
1350
  lpbi->bV4AlphaMask = 0xFF000000;
 
1351
  lpbi->bV4Width = bmpCopied.bmWidth;    
 
1352
  lpbi->bV4Height = bmpCopied.bmHeight;  
 
1353
  lpbi->bV4Planes = 1;    
 
1354
  lpbi->bV4BitCount = 32;    
 
1355
  lpbi->bV4SizeImage = 0;  
 
1356
  lpbi->bV4XPelsPerMeter = 0;    
 
1357
  lpbi->bV4YPelsPerMeter = 0;    
 
1358
  lpbi->bV4ClrUsed = 0;    
 
1359
  lpbi->bV4ClrImportant = 0;
 
1360
  bits = (unsigned char *)lpbi + sizeof(BITMAPV4HEADER);
 
1361
 
 
1362
  // Gets the "bits" from the bitmap and copies them into a buffer 
 
1363
  // which is pointed to by lpbi
 
1364
  if (GetDIBits(hdcMemDC, hbitmap, 0, (UINT)bmpCopied.bmHeight, bits,
 
1365
    (BITMAPINFOHEADER *)lpbi, DIB_RGB_COLORS) == 0)
 
1366
    {
 
1367
      NSLog(@"GetDIBits failed for window %d in GSReadRect. Error %d", 
 
1368
        (int)window, GetLastError());
 
1369
      GlobalUnlock(hDIB);    
 
1370
      GlobalFree(hDIB);
 
1371
      DeleteObject(hbitmap);
 
1372
      ReleaseDC((HWND)window, hdcMemDC);
 
1373
      [self releaseHDC: hDC];
 
1374
      return nil;
 
1375
    }
 
1376
 
 
1377
  data = [NSMutableData dataWithLength: dwBmpSize];
 
1378
  if (data == nil)
 
1379
    {
 
1380
      GlobalUnlock(hDIB);    
 
1381
      GlobalFree(hDIB);
 
1382
      DeleteObject(hbitmap);
 
1383
      ReleaseDC((HWND)window, hdcMemDC);
 
1384
      [self releaseHDC: hDC];
 
1385
      return nil;
 
1386
    }
 
1387
 
 
1388
  // Copy to data
 
1389
  cdata = [data mutableBytes];
 
1390
  while (i < dwBmpSize)
 
1391
    {
 
1392
      cdata[i+0] = bits[i+2];
 
1393
      cdata[i+1] = bits[i+1];
 
1394
      cdata[i+2] = bits[i+0];
 
1395
      cdata[i+3] = bits[i+3];
 
1396
      i += 4;
 
1397
    }
 
1398
 
 
1399
 
 
1400
  //Unlock and Free the DIB from the heap
 
1401
  GlobalUnlock(hDIB);    
 
1402
  GlobalFree(hDIB);
 
1403
 
 
1404
  //Clean up
 
1405
  DeleteObject(hbitmap);
 
1406
  ReleaseDC((HWND)window, hdcMemDC);
 
1407
  [self releaseHDC: hDC];
 
1408
 
 
1409
  [dict setObject: [NSValue valueWithSize: NSMakeSize(bmpCopied.bmWidth,
 
1410
  bmpCopied.bmHeight)]
 
1411
  forKey: @"Size"];
 
1412
  [dict setObject: data forKey: @"Data"];
 
1413
 
 
1414
  return dict;
 
1415
}
 
1416
 
 
1417
@end