~motumedia/xine-ui/ubuntu

« back to all changes in this revision

Viewing changes to src/xitk/xine-toolkit/image.c

  • Committer: Reinhard Tartler
  • Date: 2007-01-30 10:33:18 UTC
  • mfrom: (2541.1.34 xine-ui.0.99.4+cvs)
  • Revision ID: siretart@tauware.de-20070130103318-evmro8n4ydtj3cwb
merge debian changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 * along with this program; if not, write to the Free Software
18
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
19
19
 *
20
 
 * $Id: image.c,v 1.68 2006/05/22 17:53:26 mshopf Exp $
 
20
 * $Id: image.c,v 1.71 2006/09/03 01:26:58 fsck-p Exp $
21
21
 *
22
22
 */
23
23
#ifdef HAVE_CONFIG_H
590
590
  int            w;
591
591
  int            h;
592
592
  XPoint         points[4];
593
 
  int            i, offset = 0;
594
 
  short          x1, x2, x3;
595
 
  short          y1, y2, y3;
 
593
  int            i;
 
594
  int            x1, x2, x3;
 
595
  int            y1, y2, y3;
596
596
  
597
597
  ABORT_IF_NULL(im);
598
598
  ABORT_IF_NULL(p);
600
600
  w = p->width / 3;
601
601
  h = p->height;
602
602
  
 
603
  x1 = (w - 5);
 
604
  y1 = (h / 2); 
 
605
 
 
606
  x2 = (w - 10);
 
607
  y2 = ((h / 2) + 5);
 
608
 
 
609
  x3 = (w - 10);
 
610
  y3 = ((h / 2) - 5);
 
611
  
603
612
  XLOCK(im->x.disp);
604
613
  XSetForeground(im->x.disp, p->image->gc, xitk_get_pixel_color_black(im));
605
614
  XUNLOCK(im->x.disp);
606
 
  
 
615
 
607
616
  for(i = 0; i < 3; i++) {
608
 
 
609
 
    x1 = (w - 10) + offset;
610
 
    y1 = (h / 4);
611
 
    
612
 
    x2 = (w - 10) + offset;
613
 
    y2 = ((h / 4) * 3);
614
 
    
615
 
    x3 = (w - 4) + offset;
616
 
    y3 = (h / 2); 
617
617
    
618
618
    if(i == 2) {
619
619
      x1++; x2++; x3++;
628
628
    points[2].y = y3;
629
629
    points[3].x = x1;
630
630
    points[3].y = y1;
631
 
    
632
 
    offset += w;
633
631
 
634
632
    XLOCK(im->x.disp);
635
633
    XFillPolygon(im->x.disp, p->image->pixmap, p->image->gc, 
636
 
                 &points[0], 4, Complex, CoordModeOrigin);
 
634
                 &points[0], 4, Convex, CoordModeOrigin);
637
635
    XUNLOCK(im->x.disp);
 
636
 
 
637
    x1 += w;
 
638
    x2 += w;
 
639
    x3 += w;
638
640
  }
639
641
 
640
642
}
645
647
static void _draw_arrow(ImlibData *im, xitk_image_t *p, int direction) {
646
648
  int            w;
647
649
  int            h;
648
 
  XPoint         points[4];
649
 
  int            i, offset = 0;
650
 
  short          x1, x2, x3;
651
 
  short          y1, y2, y3;
 
650
  XSegment      *segments;
 
651
  int            nsegments;
 
652
  int            i, s;
 
653
  int            x1, x2, dx;
 
654
  int            y1, y2, dy;
652
655
 
653
656
  ABORT_IF_NULL(im);
654
657
  ABORT_IF_NULL(p);
656
659
  w = p->width / 3;
657
660
  h = p->height;
658
661
 
 
662
  /*
 
663
   * XFillPolygon doesn't yield equally shaped arbitrary sized small triangles
 
664
   * because of its filling algorithm (see also fill-rule in XCreateGC(3X11)
 
665
   * as for which pixels are drawn on the boundary).
 
666
   * So we handcraft them using XDrawSegments applying Bresenham's algorithm.
 
667
   */
 
668
 
 
669
  /* Coords of the enclosing rectangle for the triangle:   */
 
670
  /* Pay attention to integer precision loss and calculate */
 
671
  /* carefully to obtain symmetrical and centered shapes.  */
 
672
  x1 = ((w - 1) / 2) - (w / 4);
 
673
  x2 = ((w - 1) / 2) + (w / 4);
 
674
  y1 = ((h - 1) / 2) - (h / 4);
 
675
  y2 = ((h - 1) / 2) + (h / 4);
 
676
 
 
677
  dx = (x2 - x1 + 1);
 
678
  dy = (y2 - y1 + 1);
 
679
 
 
680
  if(direction == DIRECTION_UP || direction == DIRECTION_DOWN) {
 
681
    int y, iy, dd;
 
682
 
 
683
    nsegments = dy;
 
684
    segments = (XSegment *) xitk_xmalloc(sizeof(XSegment) * nsegments);
 
685
 
 
686
    if(direction == DIRECTION_DOWN) {
 
687
      y = y1; iy = 1;
 
688
    }
 
689
    else {
 
690
      y = y2; iy = -1;
 
691
    }
 
692
    dx = (dx + 1) / 2;
 
693
    dd = 0;
 
694
    for(s = 0; s < nsegments; s++) {
 
695
      segments[s].y1 = y; segments[s].x1 = x1;
 
696
      segments[s].y2 = y; segments[s].x2 = x2;
 
697
      y += iy;
 
698
      if(dy >= dx) {
 
699
        if((dd += dx) >= dy) {
 
700
          x1++; x2--;
 
701
          dd -= dy;
 
702
        }
 
703
      }
 
704
      else {
 
705
        do {
 
706
          x1++; x2--;
 
707
        } while((dd += dy) < dx);
 
708
        dd -= dx;
 
709
      }
 
710
    }
 
711
  }
 
712
  else if(direction == DIRECTION_LEFT || direction == DIRECTION_RIGHT) {
 
713
    int x, ix, dd;
 
714
 
 
715
    nsegments = dx;
 
716
    segments = (XSegment *) xitk_xmalloc(sizeof(XSegment) * nsegments);
 
717
 
 
718
    if(direction == DIRECTION_RIGHT) {
 
719
      x = x1; ix = 1;
 
720
    }
 
721
    else {
 
722
      x = x2; ix = -1;
 
723
    }
 
724
    dy = (dy + 1) / 2;
 
725
    dd = 0;
 
726
    for(s = 0; s < nsegments; s++) {
 
727
      segments[s].x1 = x; segments[s].y1 = y1;
 
728
      segments[s].x2 = x; segments[s].y2 = y2;
 
729
      x += ix;
 
730
      if(dx >= dy) {
 
731
        if((dd += dy) >= dx) {
 
732
          y1++; y2--;
 
733
          dd -= dx;
 
734
        }
 
735
      }
 
736
      else {
 
737
        do {
 
738
          y1++; y2--;
 
739
        } while((dd += dx) < dy);
 
740
        dd -= dy;
 
741
      }
 
742
    }
 
743
  }
 
744
  else {
 
745
    XITK_WARNING("direction '%d' is unhandled.\n", direction);
 
746
    return;
 
747
  }
 
748
 
659
749
  XLOCK(im->x.disp);
660
750
  XSetForeground(im->x.disp, p->image->gc, xitk_get_pixel_color_black(im));
661
751
  XUNLOCK(im->x.disp);
662
752
 
663
753
  for(i = 0; i < 3; i++) {
664
754
    
665
 
    if(direction == DIRECTION_UP) {
666
 
      x1 = (w / 2) + offset;
667
 
      y1 = (h / 4);
668
 
      
669
 
      x2 = ((w / 4) * 3) + offset;
670
 
      y2 = ((h / 4) * 3);
671
 
      
672
 
      x3 = (w / 4) + offset;
673
 
      y3 = ((h / 4) * 3); 
674
 
    }
675
 
    else if(direction == DIRECTION_DOWN) {
676
 
      x1 = (w / 2) + offset;
677
 
      y1 = ((h / 4) * 3);
678
 
 
679
 
      x2 = (w / 4) + offset;
680
 
      y2 = (h / 4);
681
 
      
682
 
      x3 = ((w / 4) * 3) + offset;
683
 
      y3 = (h / 4); 
684
 
    }
685
 
    else if(direction == DIRECTION_LEFT) {
686
 
      x1 = ((w / 4) * 3) + offset;
687
 
      y1 = (h / 4);
688
 
 
689
 
      x2 = ((w / 4) * 3) + offset;
690
 
      y2 = ((h / 4) * 3);
691
 
      
692
 
      x3 = (w / 4) + offset;
693
 
      y3 = (h / 2); 
694
 
    }
695
 
    else if(direction == DIRECTION_RIGHT) {
696
 
      x1 = (w / 4) + offset;
697
 
      y1 = (h / 4);
698
 
 
699
 
      x2 = ((w / 4) * 3) + offset;
700
 
      y2 = (h / 2);
701
 
      
702
 
      x3 = (w / 4) + offset;
703
 
      y3 = ((h / 4) * 3); 
704
 
    }
705
 
    else {
706
 
      XITK_WARNING("direction '%d' is unhandled.\n", direction);
707
 
      return;
708
 
    }
709
 
    
710
755
    if(i == 2) {
711
 
      x1++; x2++; x3++;
712
 
      y1++; y2++; y3++;
 
756
      for(s = 0; s < nsegments; s++) {
 
757
        segments[s].x1++; segments[s].y1++;
 
758
        segments[s].x2++; segments[s].y2++;
 
759
      }
713
760
    }
714
761
    
715
 
    points[0].x = x1;
716
 
    points[0].y = y1;
717
 
    points[1].x = x2;
718
 
    points[1].y = y2;
719
 
    points[2].x = x3;
720
 
    points[2].y = y3;
721
 
    points[3].x = x1;
722
 
    points[3].y = y1;
723
 
    
724
 
    offset += w;
725
 
 
726
762
    XLOCK(im->x.disp);
727
 
    XFillPolygon(im->x.disp, p->image->pixmap, p->image->gc, 
728
 
                 &points[0], 4, Complex, CoordModeOrigin);
 
763
    XDrawSegments(im->x.disp, p->image->pixmap, p->image->gc, 
 
764
                  &segments[0], nsegments);
729
765
    XUNLOCK(im->x.disp);
 
766
 
 
767
    for(s = 0; s < nsegments; s++) {
 
768
      segments[s].x1 += w;
 
769
      segments[s].x2 += w;
 
770
    }
730
771
  }
731
772
 
 
773
  free(segments);
732
774
}
733
775
 
734
776
/*
763
805
    XSetForeground(im->x.disp, p->gc, xitk_get_pixel_color_black(im));
764
806
  
765
807
  XDrawLine(im->x.disp, p->pixmap, p->gc, x, y, (x + excstart), y);
766
 
  XDrawLine(im->x.disp, p->pixmap, p->gc, (x + excstop), y, (x + width), y);
 
808
  XDrawLine(im->x.disp, p->pixmap, p->gc, (x + excstop), y, (x + width - 1), y);
767
809
  XDrawLine(im->x.disp, p->pixmap, p->gc, x, y, x, (y + height));
768
810
  XUNLOCK(im->x.disp);
769
811
 
774
816
    XSetForeground(im->x.disp, p->gc, xitk_get_pixel_color_white(im));
775
817
  
776
818
  XDrawLine(im->x.disp, p->pixmap, p->gc, (x + width), y, (x + width), (y + height));
777
 
  XDrawLine(im->x.disp, p->pixmap, p->gc, x, (y + height), (x + width), (y + height));
 
819
  XDrawLine(im->x.disp, p->pixmap, p->gc, (x + 1), (y + height), (x + width), (y + height));
778
820
  XUNLOCK(im->x.disp);
779
821
}
780
822
 
794
836
    XSetForeground(im->x.disp, p->gc, xitk_get_pixel_color_darkgray(im));
795
837
 
796
838
  XDrawLine(im->x.disp, p->pixmap, p->gc, x, y, (x + excstart), y);
797
 
  XDrawLine(im->x.disp, p->pixmap, p->gc, (x + excstop), y, (x + width), y);
 
839
  XDrawLine(im->x.disp, p->pixmap, p->gc, (x + excstop), y, (x + width - 1), y);
798
840
  XDrawLine(im->x.disp, p->pixmap, p->gc, x, y, x, (y + height));
799
841
  XUNLOCK(im->x.disp);
800
842
 
805
847
    XSetForeground(im->x.disp, p->gc, xitk_get_pixel_color_white(im));
806
848
  
807
849
  XDrawLine(im->x.disp, p->pixmap, p->gc, (x + width), y, (x + width), (y + height));
808
 
  XDrawLine(im->x.disp, p->pixmap, p->gc, x, (y + height), (x + width), (y + height));
 
850
  XDrawLine(im->x.disp, p->pixmap, p->gc, (x + 1), (y + height), (x + width), (y + height));
809
851
  XUNLOCK(im->x.disp);
810
852
}
811
853
 
825
867
  else if(relief == DRAW_INNER)
826
868
    XSetForeground(im->x.disp, p->gc, dcolor);
827
869
 
828
 
  XDrawLine(im->x.disp, p->pixmap, p->gc, x, y, (x + width), y);
 
870
  XDrawLine(im->x.disp, p->pixmap, p->gc, x, y, (x + width - 1), y);
829
871
  XDrawLine(im->x.disp, p->pixmap, p->gc, x, y, x, (y + height));
830
872
  XUNLOCK(im->x.disp);
831
873
 
836
878
    XSetForeground(im->x.disp, p->gc, lcolor);
837
879
  
838
880
  XDrawLine(im->x.disp, p->pixmap, p->gc, (x + width), y, (x + width), (y + height));
839
 
  XDrawLine(im->x.disp, p->pixmap, p->gc, x, (y + height), (x + width), (y + height));
 
881
  XDrawLine(im->x.disp, p->pixmap, p->gc, (x + 1), (y + height), (x + width), (y + height));
840
882
  XUNLOCK(im->x.disp);
841
883
}
842
884
 
1310
1352
  xitk_font_t   *fs = NULL;
1311
1353
  int            sty[2];
1312
1354
  int            yoff = 0, xstart = 0, xstop = 0, fheight = 0, fwidth = 0;
 
1355
  int            titlelen = 0;
 
1356
  char          *titlebuf = NULL;
1313
1357
  char           buf[BUFSIZ];
1314
1358
 
1315
1359
  ABORT_IF_NULL(im);
1316
1360
  ABORT_IF_NULL(p);
1317
1361
  
1318
1362
  if(title) {
 
1363
    int ascent, descent;
 
1364
 
 
1365
    int maxfwidth = (w - 12);
 
1366
 
 
1367
    titlelen = strlen(title);
 
1368
    titlebuf = title;
1319
1369
 
1320
1370
    fs = xitk_font_load_font(im->x.disp, (fontname ? fontname : DEFAULT_FONT_12));
1321
1371
    xitk_font_set_font(fs, p->gc);
1322
 
    fheight = xitk_font_get_string_height(fs, title);
1323
 
    fwidth = xitk_font_get_string_length(fs, title);
1324
 
 
1325
 
    if(fwidth >= (w - 12)) {
1326
 
      int nchar = 1;
1327
 
      
1328
 
      memset(&buf, 0, sizeof(buf));
1329
 
      /* Limit the title to width of frame */
 
1372
    xitk_font_text_extent(fs, title, titlelen, NULL, NULL, &fwidth, &ascent, &descent);
 
1373
    fheight = ascent + descent;
 
1374
 
 
1375
    /* Limit title to frame width */
 
1376
    if(fwidth > maxfwidth) {
 
1377
      char  dots[]  = "...";
 
1378
      int   dotslen = strlen(dots);
 
1379
      int   dotsfwidth;
 
1380
 
 
1381
      /* Cut title, append dots */
 
1382
      xitk_font_text_extent(fs, dots, dotslen, NULL, NULL, &dotsfwidth, NULL, NULL);
1330
1383
      do {
1331
 
        nchar++;
1332
 
        snprintf(buf, nchar, "%s", title);
1333
 
      } while(xitk_font_get_string_length(fs, buf) < (w - 12));
1334
 
      /* Cut title, add three dots a the end */
1335
 
      nchar -= 4;
1336
 
      snprintf(buf, nchar, "%s", title);
1337
 
      strcat(buf, "...");
 
1384
        titlelen--;
 
1385
        xitk_font_text_extent(fs, title, titlelen, NULL, NULL, &fwidth, NULL, NULL);
 
1386
      } while((fwidth + dotsfwidth) > maxfwidth);
 
1387
      { /* Cut possible incomplete multibyte character at the end */
 
1388
        int fwidth1;
 
1389
        while((titlelen > 0) &&
 
1390
              (xitk_font_text_extent(fs, title, (titlelen - 1), NULL, NULL, &fwidth1, NULL, NULL),
 
1391
               fwidth1 == fwidth))
 
1392
          titlelen--;
 
1393
      }
 
1394
      if(titlelen > (sizeof(buf) - dotslen - 1)) /* Should never happen, */
 
1395
        titlelen = (sizeof(buf) - dotslen - 1);  /* just to be sure ...  */
 
1396
      strncpy(buf, title, titlelen), buf[titlelen] = '\0';
 
1397
      strcat(buf, dots);
 
1398
      fwidth += dotsfwidth;
 
1399
      titlelen += dotslen;
 
1400
      titlebuf = buf;
1338
1401
    }
1339
 
    else
1340
 
      strcpy(buf, title);
1341
 
 
1342
 
    fwidth = xitk_font_get_string_length(fs, buf);
1343
1402
  }
1344
1403
 
1345
1404
  sty[0] = (style == DRAW_INNER) ? DRAW_INNER : DRAW_OUTTER;
1349
1408
  if(title) {
1350
1409
    yoff = (fheight>>1);
1351
1410
    xstart = 3;
1352
 
    xstop = fwidth + 12;
 
1411
    xstop = fwidth + 9;
1353
1412
  }
 
1413
 
1354
1414
  _draw_rectangular_box_light(im, p, x, (y - yoff), 
1355
1415
                              xstart, xstop,
1356
 
                              w, (h - yoff), sty[0]);
 
1416
                              w, (h - fheight + yoff), sty[0]);
1357
1417
  
1358
1418
  if(title)
1359
 
    xstart--;
 
1419
    xstart--, xstop--;
1360
1420
  
1361
1421
  _draw_rectangular_box_light(im, p, (x + 1), ((y - yoff) + 1), 
1362
1422
                              xstart, xstop,
1363
 
                              (w - 2), ((h - yoff) - 2), sty[1]);
 
1423
                              (w - 2), ((h - fheight + yoff) - 2), sty[1]);
1364
1424
  
1365
1425
  if(title) {
1366
1426
    XLOCK(im->x.disp);
1367
1427
    XSetForeground(im->x.disp, p->gc, xitk_get_pixel_color_black(im));
1368
 
    xitk_font_draw_string(fs, p->pixmap, p->gc, (x + 6), y, buf, strlen(buf));
 
1428
    xitk_font_draw_string(fs, p->pixmap, p->gc, (x + 6), y, titlebuf, titlelen);
1369
1429
    XUNLOCK(im->x.disp);
1370
1430
    
1371
1431
    xitk_font_unload_font(fs);