+typedef enum { STABLE, SLOW, MODERATE, FAST, CRAZY } velocity_t;
+
+/* Plot info with smoothing, velocity indication
+ * and one-, two- and three-minute minimums and maximums */
+struct plot_info {
+ int nr;
+ int maxtime;
+ int meandepth, maxdepth;
+ int maxpressure;
+ int mintemp, maxtemp;
+ struct plot_data {
+ unsigned int same_cylinder:1;
+ unsigned int cylinderindex;
+ int sec;
+ /* pressure[0] is sensor pressure
+ * pressure[1] is interpolated pressure */
+ int pressure[2];
+ int temperature;
+ /* Depth info */
+ int depth;
+ int smoothed;
+ velocity_t velocity;
+ struct plot_data *min[3];
+ struct plot_data *max[3];
+ int avg[3];
+ } entry[];
+};
+
+#define SENSOR_PR 0
+#define INTERPOLATED_PR 1
+#define SENSOR_PRESSURE(_entry) (_entry)->pressure[SENSOR_PR]
+#define INTERPOLATED_PRESSURE(_entry) (_entry)->pressure[INTERPOLATED_PR]
+#define GET_PRESSURE(_entry) (SENSOR_PRESSURE(_entry) ? : INTERPOLATED_PRESSURE(_entry))
+
+#define SAC_COLORS_START_IDX SAC_1
+#define SAC_COLORS 9
+#define VELOCITY_COLORS_START_IDX VELO_STABLE
+#define VELOCITY_COLORS 5
+
+typedef enum {
+ /* SAC colors. Order is important, the SAC_COLORS_START_IDX define above. */
+ SAC_1, SAC_2, SAC_3, SAC_4, SAC_5, SAC_6, SAC_7, SAC_8, SAC_9,
+
+ /* Velocity colors. Order is still important, ref VELOCITY_COLORS_START_IDX. */
+ VELO_STABLE, VELO_SLOW, VELO_MODERATE, VELO_FAST, VELO_CRAZY,
+
+ /* Other colors */
+ TEXT_BACKGROUND, ALERT_BG, ALERT_FG, EVENTS, SAMPLE_DEEP, SAMPLE_SHALLOW,
+ SMOOTHED, MINUTE, TIME_GRID, TIME_TEXT, DEPTH_GRID, MEAN_DEPTH, DEPTH_TOP,
+ DEPTH_BOTTOM, TEMP_TEXT, TEMP_PLOT, SAC_DEFAULT, BOUNDING_BOX, PRESSURE_TEXT, BACKGROUND
+} color_indice_t;
+
+typedef struct {
+ /* media[0] is screen, and media[1] is printer */
+ struct rgba {
+ double r,g,b,a;
+ } media[2];
+} color_t;
+
+/* [color indice] = {{screen color, printer color}} */
+static const color_t profile_color[] = {
+ [SAC_1] = {{FUNGREEN1, BLACK1_LOW_TRANS}},
+ [SAC_2] = {{APPLE1, BLACK1_LOW_TRANS}},
+ [SAC_3] = {{ATLANTIS1, BLACK1_LOW_TRANS}},
+ [SAC_4] = {{ATLANTIS2, BLACK1_LOW_TRANS}},
+ [SAC_5] = {{EARLSGREEN1, BLACK1_LOW_TRANS}},
+ [SAC_6] = {{HOKEYPOKEY1, BLACK1_LOW_TRANS}},
+ [SAC_7] = {{TUSCANY1, BLACK1_LOW_TRANS}},
+ [SAC_8] = {{CINNABAR1, BLACK1_LOW_TRANS}},
+ [SAC_9] = {{REDORANGE1, BLACK1_LOW_TRANS}},
+
+ [VELO_STABLE] = {{CAMARONE1, BLACK1_LOW_TRANS}},
+ [VELO_SLOW] = {{LIMENADE1, BLACK1_LOW_TRANS}},
+ [VELO_MODERATE] = {{RIOGRANDE1, BLACK1_LOW_TRANS}},
+ [VELO_FAST] = {{PIRATEGOLD1, BLACK1_LOW_TRANS}},
+ [VELO_CRAZY] = {{RED1, BLACK1_LOW_TRANS}},
+
+ [TEXT_BACKGROUND] = {{CONCRETE1_LOWER_TRANS, WHITE1}},
+ [ALERT_BG] = {{BROOM1_LOWER_TRANS, BLACK1_LOW_TRANS}},
+ [ALERT_FG] = {{BLACK1_LOW_TRANS, BLACK1_LOW_TRANS}},
+ [EVENTS] = {{REDORANGE1, BLACK1_LOW_TRANS}},
+ [SAMPLE_DEEP] = {{PERSIANRED1, BLACK1_LOW_TRANS}},
+ [SAMPLE_SHALLOW] = {{PERSIANRED1, BLACK1_LOW_TRANS}},
+ [SMOOTHED] = {{REDORANGE1_HIGH_TRANS, BLACK1_LOW_TRANS}},
+ [MINUTE] = {{MEDIUMREDVIOLET1_HIGHER_TRANS, BLACK1_LOW_TRANS}},
+ [TIME_GRID] = {{WHITE1, TUNDORA1_MED_TRANS}},
+ [TIME_TEXT] = {{FORESTGREEN1, BLACK1_LOW_TRANS}},
+ [DEPTH_GRID] = {{WHITE1, TUNDORA1_MED_TRANS}},
+ [MEAN_DEPTH] = {{REDORANGE1_MED_TRANS, BLACK1_LOW_TRANS}},
+ [DEPTH_BOTTOM] = {{GOVERNORBAY1_MED_TRANS, TUNDORA1_MED_TRANS}},
+ [DEPTH_TOP] = {{MERCURY1_MED_TRANS, WHITE1_MED_TRANS}},
+ [TEMP_TEXT] = {{GOVERNORBAY2, BLACK1_LOW_TRANS}},
+ [TEMP_PLOT] = {{ROYALBLUE2_LOW_TRANS, BLACK1_LOW_TRANS}},
+ [SAC_DEFAULT] = {{WHITE1, BLACK1_LOW_TRANS}},
+ [BOUNDING_BOX] = {{WHITE1, BLACK1_LOW_TRANS}},
+ [PRESSURE_TEXT] = {{KILLARNEY1, BLACK1_LOW_TRANS}},
+ [BACKGROUND] = {{SPRINGWOOD1, BLACK1_LOW_TRANS}},
+};
+
+#define plot_info_size(nr) (sizeof(struct plot_info) + (nr)*sizeof(struct plot_data))
+
+/* Scale to 0,0 -> maxx,maxy */
+#define SCALEX(gc,x) (((x)-gc->leftx)/(gc->rightx-gc->leftx)*gc->maxx)
+#define SCALEY(gc,y) (((y)-gc->topy)/(gc->bottomy-gc->topy)*gc->maxy)
+#define SCALE(gc,x,y) SCALEX(gc,x),SCALEY(gc,y)
+
+static void move_to(struct graphics_context *gc, double x, double y)
+{
+ cairo_move_to(gc->cr, SCALE(gc, x, y));
+}
+
+static void line_to(struct graphics_context *gc, double x, double y)
+{
+ cairo_line_to(gc->cr, SCALE(gc, x, y));
+}
+
+static void set_source_rgba(struct graphics_context *gc, color_indice_t c)
+{
+ const color_t *col = &profile_color[c];
+ struct rgba rgb = col->media[gc->printer];
+ double r = rgb.r;
+ double g = rgb.g;
+ double b = rgb.b;
+ double a = rgb.a;
+
+ cairo_set_source_rgba(gc->cr, r, g, b, a);
+}
+
+void init_profile_background(struct graphics_context *gc)
+{
+ set_source_rgba(gc, BACKGROUND);
+}
+
+void pattern_add_color_stop_rgba(struct graphics_context *gc, cairo_pattern_t *pat, double o, color_indice_t c)
+{
+ const color_t *col = &profile_color[c];
+ struct rgba rgb = col->media[gc->printer];
+ cairo_pattern_add_color_stop_rgba(pat, o, rgb.r, rgb.g, rgb.b, rgb.a);
+}
+