File: xxPixmapGraph.cc

package info (click to toggle)
xtide 2.6.4-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 2,996 kB
  • ctags: 2,617
  • sloc: cpp: 26,266; ansic: 8,105; makefile: 152; yacc: 113; sh: 54; lex: 54
file content (115 lines) | stat: -rw-r--r-- 4,360 bytes parent folder | download | duplicates (3)
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
/*  xxPixmapGraph  Graph implemented as Pixmap.
    Last modified 1999-08-14

    Copyright (C) 1998  David Flater.

    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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "xtide.hh"

xxPixmapGraph::xxPixmapGraph (unsigned xsize, unsigned ysize,
xxContext *in_context): Graph (xsize, ysize) {
  assert (xsize >= mingwidth && ysize >= mingheight);
  context = in_context;
  pixmap = context->makePixmap (xsize, ysize);
}

xxPixmapGraph::~xxPixmapGraph() {
  XFreePixmap (context->display, pixmap);
}

unsigned xxPixmapGraph::fontWidth() {
  return 7;
}

unsigned xxPixmapGraph::fontHeight() {
  // This used to be 11, then was increased to make room for Latin1
  // characters.
  return 12;
}

void xxPixmapGraph::setPixel (int x, int y, Colors::colorchoice c) {
  if (x < 0 || x >= xsize() || y < 0 || y >= ysize())
    return;
  XSetForeground (context->display, context->spare_gc,
    context->pixels[c]);
  XDrawPoint (context->display, pixmap, context->spare_gc, x, y);
}

void xxPixmapGraph::setPixel (int x, int y, Colors::colorchoice c,
double saturation) {
  if (x < 0 || x >= xsize() || y < 0 || y >= ysize())
    return;
  if (context->display_sucks) {
    if (saturation >= 0.5)
      setPixel (x, y, c);
  } else {
    unsigned short r1, g1, b1, r2, g2, b2;

    // We arrive at this sorry crossroads as a result of these
    // unhealthy facts about Xlib:
    //    1.  Apart from doing XGetImage, there is no way to "read"
    //        the value of a pixel in a Pixmap.
    //    2.  The drawing functions XDrawPoint, XDrawLine, and XDrawString
    //        only work on "drawables."  Windows and Pixmaps are drawables;
    //        XImages are not.  So it's not possible to avoid the kludge
    //        by using XImages instead of Pixmaps everywhere.
    // It would be nice to just inherit everything from RGBGraph and then
    // convert the PPM to a Pixmap at the end, but this suddenly gets
    // complicated when your display only supports 256 colors.  It's also
    // intolerably slow.  The only remaining alternative would be to
    // duplicate the effort in RGBGraph to create an XImage at the PutPixel
    // level, sans even XDrawLine to speed things up.  This would probably
    // be even slower than the current implementation (IMHO).

    XImage *img = XGetImage (context->display, pixmap, x, y, 1, 1,
      AllPlanes, ZPixmap);
    Pixel pixel = XGetPixel (img, 0, 0);
    XDestroyImage (img);
    // Assuming that image has same colormap as display. (?)  This
    // could also be done using the color masks in the XImage.
    context->extractColor (pixel, r1, g1, b1);

    context->extractColor (context->pixels[c], r2, g2, b2);
    XSetForeground (context->display, context->spare_gc,
      context->getColor (linterp (r1, r2, saturation),
                         linterp (g1, g2, saturation),
                         linterp (b1, b2, saturation)));
    XDrawPoint (context->display, pixmap, context->spare_gc, x, y);
  }
}

void xxPixmapGraph::drawVerticalLine (int x, int y1, int y2,
                                 Colors::colorchoice c) {
  XSetForeground (context->display, context->spare_gc,
    context->pixels[c]);
  XDrawLine (context->display, pixmap, context->spare_gc, x, y1, x, y2);
}

void
xxPixmapGraph::drawHorizontalLine (int xlo, int xhi, int y,
			      Colors::colorchoice c) {
  XSetForeground (context->display, context->spare_gc,
    context->pixels[c]);
  if (xlo <= xhi) // ?
    XDrawLine (context->display, pixmap, context->spare_gc, xlo, y, xhi, y);
}

void
xxPixmapGraph::drawString (int x, int y, const Dstr &s) {
  XDrawString (context->display, pixmap, context->text_gc, x, y+fontHeight()-2,
  s.aschar(), s.length());
}