NCBI C Toolkit Cross Reference

C/desktop/gphdraw.c


  1 /*
  2 * ===========================================================================
  3 *
  4 *                            PUBLIC DOMAIN NOTICE
  5 *               National Center for Biotechnology Information
  6 *
  7 *  This software/database is a "United States Government Work" under the
  8 *  terms of the United States Copyright Act.  It was written as part of
  9 *  the author's official duties as a United States Government employee and
 10 *  thus cannot be copyrighted.  This software/database is freely available
 11 *  to the public for use. The National Library of Medicine and the U.S.
 12 *  Government have not placed any restriction on its use or reproduction.
 13 *
 14 *  Although all reasonable efforts have been taken to ensure the accuracy
 15 *  and reliability of the software and data, the NLM and the U.S.
 16 *  Government do not and cannot warrant the performance or results that
 17 *  may be obtained by using this software or data. The NLM and the U.S.
 18 *  Government disclaim all warranties, express or implied, including
 19 *  warranties of performance, merchantability or fitness for any particular
 20 *  purpose.
 21 *
 22 *  Please cite the author in any work or product based on this material.
 23 *
 24 * ===========================================================================
 25 *
 26 * File Name: gphdraw.c
 27 *
 28 * Author(s): Jonathan Kans, John Kuzio
 29 *
 30 * Version Creation Date: 98-01-01
 31 *
 32 * $Revision: 6.10 $
 33 *
 34 * File Description: sentinel graphs
 35 *
 36 * Modifications:
 37 * --------------------------------------------------------------------------
 38 * Date       Name        Description of modification
 39 * --------------------------------------------------------------------------
 40 * $Log: gphdraw.c,v $
 41 * Revision 6.10  2000/07/14 19:47:38  kans
 42 * allow Phred Quality along with Phrap Quality
 43 *
 44 * Revision 6.9  1999/10/04 17:46:23  kans
 45 * include vibrant.h
 46 *
 47 * Revision 6.8  1999/03/12 14:23:34  kuzio
 48 * cast
 49 *
 50 * Revision 6.7  1998/10/13 17:13:56  kuzio
 51 * colored superimposable graphs
 52 *
 53 * Revision 6.6  1998/09/16 19:00:35  kuzio
 54 * cvs logs
 55 *
 56 * ==========================================================================
 57 */
 58 
 59 #include <vibrant.h>
 60 #include <sequtil.h>
 61 #include <drawingp.h>
 62 #include <gphdraw.h>
 63 
 64 static void PlotTheWorkingArray (Int4Ptr xp, Int4 len, Int4 scaleX,
 65                                  Int4 gmin, RecT r, Uint1 uR, Uint1 uG,
 66                                  Uint1 uB, AttPData PNTR curattrib)
 67 {
 68   PoinT          pt;
 69   Int4           i;
 70   Int4           j;
 71   Int4           max;
 72   Int4           min;
 73   Int4           val;
 74   Uint1          curR, curG, curB;
 75 
 76   if (curattrib != NULL)
 77   {
 78     curR = curattrib->color[0];
 79     curG = curattrib->color[1];
 80     curB = curattrib->color[2];
 81   }
 82   else
 83   {
 84     curR = 0;
 85     curG = 0;
 86     curB = 0;
 87   }
 88 
 89   SelectColor (uR, uG, uB);
 90   pt.x = r.left;
 91   i = 0;
 92   val = (Int4) *xp;
 93   pt.y = (Int2) (r.bottom - (Int2) (val - gmin));
 94   if (pt.y < r.top) {
 95     pt.y = r.top;
 96   }
 97   MoveTo (pt.x, pt.y);
 98   for (; i < len - scaleX; i += scaleX) {
 99     val = (Int4) *xp;
100     min = (Int4) val;
101     max = (Int4) val;
102     for (j = 1; j < scaleX; j++) {
103       xp++;
104       val = (Int4) *xp;
105       min = MIN (min, (Int4) val);
106       max = MAX (max, (Int4) val);
107     }
108     xp++;
109     pt.y = (Int2) (r.bottom - (Int2) (min - gmin));
110     if (pt.y < r.top) {
111       pt.y = r.top;
112     }
113     LineTo (pt.x, pt.y);
114     pt.y = (Int2) (r.bottom - (Int2) (max - gmin));
115     if (pt.y < r.top) {
116       pt.y = r.top;
117     }
118     LineTo (pt.x, pt.y);
119     (pt.x)++;
120   }
121   SelectColor (curR, curG, curB);
122   return;
123 }
124 
125 static Int4Ptr MakeWorkingSeqGraphInt4Array (Pointer data, Uint1 type,
126                                              Int4 pos, Int4 len,
127                                              Boolean usescaleflags,
128                                              FloatHi a, FloatHi b)
129 {
130   Int4          i;
131   Int4Ptr       xpoints, xp;
132   FloatHi       fval;
133   Int4          ival;
134   Byte          bval;
135   ByteStorePtr  bs;
136   BytePtr       bp;
137 
138   xpoints = (Int4Ptr) MemNew ((size_t) (sizeof (Int4) * (len + 10)));
139 
140   if (xpoints == NULL)
141     return xpoints;
142 
143   xp = xpoints;
144   switch (type) {
145    default:
146    case 1:
147     for (i = 0; i < len; i++, pos++, xp++) {
148       if (usescaleflags) {
149         fval = a * (FloatHi) (((FloatHiPtr) data)[pos]) + b;
150       } else {
151         fval = (FloatHi) (((FloatHiPtr) data)[pos]);
152       }
153       *xp = (Int4) fval;
154     }
155     break;
156    case 2:
157     for (i = 0; i < len; i++, pos++, xp++) {
158       if (usescaleflags) {
159         ival = (Int4) (a * (FloatHi) (((Int4Ptr) data)[pos]) + b);
160       } else {
161         ival = (Int4) (((Int4Ptr) data)[pos]);
162       }
163       *xp = (Int4) ival;
164     }
165     break;
166    case 3:
167     bp = MemNew (sizeof (Byte) * (len + 10));
168     bs = (ByteStorePtr) data;
169     BSSeek (bs, pos, SEEK_SET);
170     len = BSRead (bs, (Pointer) bp, len * sizeof (Byte));
171     for (i = 0; i < len; i++, pos++, xp++) {
172       if (usescaleflags) {
173         bval = (Byte) (a * (FloatHi) (bp [i]) + b);
174       } else {
175         bval = (Byte) (bp [i]);
176       }
177       *xp = (Int4) bval;
178     }
179     MemFree (bp);
180     break;
181   }
182   return xpoints;
183 }
184 
185 static void GraphSentProc (BigScalar calldata, PrimDrawContext pdc)
186 {
187   BioseqPtr      bsp;
188   Int4           curScale;
189   DrawInfoPtr    dInfoPtr;
190   GraphSentPtr   gsp;
191   Int4           left;
192   Int4           len, pos;
193   RecT           r;
194   Int4           scaleX;
195   Int4           scaleY;
196   SeqGraphPtr    sgp;
197   BoxInfo        tmpBox;
198   Int4Ptr        xpoints;
199   Int4           tmpscaleX;
200 
201   gsp = (GraphSentPtr) calldata;
202   if (gsp == NULL) return;
203   sgp = gsp->sgp;
204   if (sgp == NULL || sgp->values == NULL) return;
205 
206   dInfoPtr = (DrawInfoPtr) pdc;
207   tmpBox = gsp->box;
208   if ( (tmpBox.left   > dInfoPtr->scale.worldWindow.right ) ||
209        (tmpBox.right  < dInfoPtr->scale.worldWindow.left  ) ||
210        (tmpBox.top    < dInfoPtr->scale.worldWindow.bottom) ||
211        (tmpBox.bottom > dInfoPtr->scale.worldWindow.top   ) )
212     return;
213 
214   if ( dInfoPtr->checked == FALSE ) {
215     if ( tmpBox.left < dInfoPtr->scale.worldWindow16.left )
216       tmpBox.left = dInfoPtr->scale.worldWindow16.left;
217     if ( tmpBox.right > dInfoPtr->scale.worldWindow16.right )
218       tmpBox.right = dInfoPtr->scale.worldWindow16.right;
219     if ( tmpBox.top > dInfoPtr->scale.worldWindow16.top )
220       tmpBox.top = dInfoPtr->scale.worldWindow16.top;
221     if ( tmpBox.bottom < dInfoPtr->scale.worldWindow16.bottom )
222       tmpBox.bottom = dInfoPtr->scale.worldWindow16.bottom;
223   }
224   scaleX = dInfoPtr->scale.scaleX;
225   scaleY = dInfoPtr->scale.scaleY;
226 
227   curScale = dInfoPtr->scale.scaleX;
228   r.left   = (Int2)((dInfoPtr->scale.offsetX + tmpBox.left )  / curScale);
229   r.right  = (Int2)((dInfoPtr->scale.offsetX + tmpBox.right)  / curScale);
230   curScale = dInfoPtr->scale.scaleY;
231   r.top    = (Int2)((dInfoPtr->scale.offsetY - tmpBox.top   ) / curScale);
232   r.bottom = (Int2)((dInfoPtr->scale.offsetY - tmpBox.bottom) / curScale);
233 
234   bsp = BioseqFind (SeqLocId (sgp->loc));
235   left = GetOffsetInBioseq (sgp->loc, bsp, SEQLOC_LEFT_END);
236 
237   if (gsp->flagIsGUI)
238   {
239     len = tmpBox.right - tmpBox.left;
240     pos = tmpBox.left - left;
241   }
242   else
243   {
244 /* for non-GUI, plot all the sgp values */
245     len = sgp->numval;
246     pos = 0;
247   }
248 
249   xpoints = MakeWorkingSeqGraphInt4Array (sgp->values, sgp->flags[2],
250                                           pos, len,
251                                           (Boolean) (sgp->flags[1] != 0),
252                                           gsp->a, gsp->b);
253   if (!gsp->flagIsGUI)
254   {
255     tmpscaleX = sgp->numval / (Int4) (tmpBox.right - tmpBox.left);
256     if (tmpscaleX > scaleX)
257       scaleX = tmpscaleX;
258   }
259 
260   PlotTheWorkingArray (xpoints, len, scaleX, gsp->min, r,
261                        gsp->red, gsp->green, gsp->blue,
262                        &(dInfoPtr->curattrib));
263 
264   MemFree (xpoints);
265 }
266 
267 static void CleanGSP (BigScalar calldata)
268 {
269   GraphSentPtr  gsp;
270 
271   gsp = (GraphSentPtr) calldata;
272   MemFree (gsp);
273 }
274 
275 extern GraphSentPtr AddGraphSentinelToPicture (SeqGraphPtr sgp, BioseqPtr bsp,
276                                                SegmenT pict, Int4 scaleX,
277                                                Int4 top, Int2 start,
278                                                Uint1Ptr uRGB)
279 {
280   Int4          axis;
281   GraphSentPtr  gsp;
282   Int4          i;
283   Boolean       is_phrap;
284   Int4          max;
285   Int4          min;
286   SegmenT       seg;
287   Char          str [32];
288   Int4          leftoff, rightoff;
289 
290   if (sgp == NULL || bsp == NULL || pict == NULL)
291     return NULL;
292   gsp = MemNew (sizeof (GraphSentData));
293   if (gsp == NULL)
294     return NULL;
295   gsp->flagIsGUI = VibrantIsGUI ();
296   if (uRGB != NULL)
297   {
298     gsp->red   = uRGB[0];
299     gsp->green = uRGB[1];
300     gsp->blue  = uRGB[2];
301   }
302   else
303   {
304     gsp->red   = 0;
305     gsp->green = 0;
306     gsp->blue  = 0;
307   }
308 
309   leftoff = GetOffsetInBioseq (sgp->loc, bsp, SEQLOC_LEFT_END);
310   rightoff = GetOffsetInBioseq (sgp->loc, bsp, SEQLOC_RIGHT_END);
311   if (!gsp->flagIsGUI)
312   {
313     leftoff /= scaleX;
314     rightoff /= scaleX;
315   }
316   gsp->box.left = leftoff + start;
317   gsp->box.right = rightoff - 1 + start;
318 
319   gsp->sgp = sgp;
320   gsp->a = sgp->a;
321   gsp->b = sgp->b;
322   is_phrap = (Boolean) (StringICmp (sgp->title, "Phrap Quality") == 0 ||
323                         StringICmp (sgp->title, "Phred Quality") == 0);
324   switch (sgp->flags [2]) {
325     case 1 :
326       min = (Int4) sgp->min.realvalue;
327       max = (Int4) sgp->max.realvalue;
328       axis = (Int4) sgp->axis.realvalue;
329       if (sgp->flags [1] != 0) {
330         min = (Int4) (sgp->a * ((FloatHi) min) + sgp->b);
331         max = (Int4) (sgp->a * ((FloatHi) max) + sgp->b);
332       }
333       break;
334     case 2 :
335       min = (Int4) sgp->min.intvalue;
336       max = (Int4) sgp->max.intvalue;
337       axis = (Int4) sgp->axis.intvalue;
338       if (sgp->flags [1] != 0) {
339         min = (Int4) (sgp->a * ((FloatHi) min) + sgp->b);
340         max = (Int4) (sgp->a * ((FloatHi) max) + sgp->b);
341       }
342       break;
343     case 3 :
344       min = (Int4) sgp->min.intvalue;
345       max = (Int4) sgp->max.intvalue;
346       if (is_phrap) {
347         min = MIN (0, min);
348         max = MAX (100, max);
349       }
350       axis = (Int4) sgp->axis.intvalue;
351       if (sgp->flags [1] != 0) {
352         min = (Int4) (sgp->a * ((FloatHi) min) + sgp->b);
353         max = (Int4) (sgp->a * ((FloatHi) max) + sgp->b);
354       }
355       break;
356     default :
357       min = (Int4) 0;
358       max = (Int4) 100;
359       axis = (Int4) 0;
360       break;
361   }
362   gsp->seg = seg = CreateSegment (pict, 0, 0);
363   gsp->bottom = top - (max - min) - 20;
364   AddSegRect (seg, FALSE, 0);
365 
366   if (sgp->title != NULL)  /* StringHasNoText -- vibforms */
367   {
368     if (StrLen (sgp->title) > 0)
369     {
370       AddLabel (seg, (gsp->box.left + gsp->box.right) / 2, top,
371                 sgp->title, SMALL_TEXT, 0, MIDDLE_CENTER, 0);
372     }
373   }
374 
375   top -= 10;
376   gsp->box.top = top;
377   gsp->box.bottom = gsp->bottom;
378   gsp->min = min;
379   gsp->max = max;
380   gsp->axis = axis;
381   gsp->bottom += 10;
382 
383   if (is_phrap)
384   {
385     for (i = 0; i <=100; i += 20) {
386       sprintf (str, "%ld", (long) i);
387       AddLabel (seg, gsp->box.left, gsp->bottom + i, str,
388                 SMALL_TEXT, 5, MIDDLE_LEFT, 0);
389     }
390   }
391   else
392   {
393     sprintf (str, "%ld", (long) max);
394     AddLabel (seg, gsp->box.left, top-10, str,
395               SMALL_TEXT, 5, MIDDLE_LEFT, 0);
396     sprintf (str, "%ld", (long) min);
397     AddLabel (seg, gsp->box.left, gsp->bottom-10, str,
398               SMALL_TEXT, 5, MIDDLE_LEFT, 0);
399     if (min < 0 && max > 0)
400     {
401       sprintf (str, "%ld", 0L);
402       AddLabel (seg, gsp->box.left, gsp->bottom-min-10, str,
403                 SMALL_TEXT, 5, MIDDLE_LEFT, 0);
404     }
405   }
406 
407   gsp->snt = AddSntRectangle (seg, gsp->box.left, gsp->box.top,
408                               gsp->box.right, gsp->box.bottom,
409                               GraphSentProc, (BigScalar) gsp, CleanGSP, 0);
410   return gsp;
411 }
412 
413 extern SegmenT DrawSeqGraphSegment (SeqGraphPtr sgp, BioseqPtr bsp,
414                                     Int4 xlen, Int4 top, Int2 start,
415                                     Int4 leftend, Int4 rightend,
416                                     SegmenT pict)
417 {
418   GraphSentPtr gsp;
419   Int4         scaleX;
420   Char         str[32];
421 
422   if (sgp == NULL || bsp == NULL)
423     return NULL;
424 
425   if (pict == NULL)
426     pict = CreatePicture ();
427   scaleX = sgp->numval / xlen;
428   if ((sgp->numval % xlen) != 0)
429     scaleX++;
430 
431   if ((gsp = AddGraphSentinelToPicture (sgp, bsp, pict, scaleX, top, start,
432                                         NULL))
433       != NULL)
434   {
435     if (gsp->seg != NULL)
436     {
437       sprintf (str, "%ld", (long) leftend);
438       AddLabel (gsp->seg, gsp->box.left, gsp->bottom-20,
439                 str, SMALL_TEXT, 0, MIDDLE_CENTER, 0);
440       sprintf (str, "%ld", (long) rightend);
441       AddLabel (gsp->seg, gsp->box.left+(sgp->numval/scaleX), gsp->bottom-20,
442                 str, SMALL_TEXT, 0, MIDDLE_CENTER, 0);
443     }
444   }
445   return pict;
446 }
447 
448 extern void DrawGraphToPanel (SeqGraphPtr sgp, Int4 Xscale,
449                               Int4 Yscale, Int4 Ylength, RecT PNTR rp,
450                               Int4 leftend, Int4 rightend)
451 {
452   Int4           len, max, min;
453   Int4Ptr        xpoints, xp;
454   Char           numberbuffer[32];
455 
456   switch (sgp->flags[2])
457   {
458    case 1:
459     min = (Int4) sgp->min.realvalue;
460     max = (Int4) sgp->max.realvalue;
461     if (sgp->flags[1] != 0)
462     {
463       min = (Int4) (sgp->a * ((FloatHi) min) + sgp->b);
464       max = (Int4) (sgp->a * ((FloatHi) max) + sgp->b);
465     }
466     break;
467    case 2:
468    case 3:
469     min = (Int4) sgp->min.intvalue;
470     max = (Int4) sgp->max.intvalue;
471     if (sgp->flags[1] != 0)
472     {
473       min = (Int4) (sgp->a * ((FloatHi) min) + sgp->b);
474       max = (Int4) (sgp->a * ((FloatHi) max) + sgp->b);
475     }
476     break;
477    default:
478     min = (Int4) 0;
479     max = (Int4) Ylength;
480     break;
481   }
482   max /= Yscale;
483   min /= Yscale;
484   len = sgp->numval;
485 
486   if (sgp->title != NULL)  /* StringHasNoText -- vibforms */
487   {
488     if (StrLen (sgp->title) > 0)
489     {
490       PaintStringEx (sgp->title, rp->left, (Int2) (rp->bottom-Ylength-30));
491     }
492   }
493 
494   sprintf (numberbuffer, "%ld", (long) max);
495   PaintStringEx (numberbuffer, (Int2) (rp->left+((len/Xscale)+10)),
496                  (Int2) (rp->bottom-Ylength));
497   sprintf (numberbuffer, "%ld", (long) min);
498   PaintStringEx (numberbuffer, (Int2) (rp->left+((len/Xscale)+10)),
499                  rp->bottom);
500   sprintf (numberbuffer, "%ld", (long) leftend);
501   PaintStringEx (numberbuffer, rp->left,
502                  (Int2) (rp->bottom+20));
503   sprintf (numberbuffer, "%ld", (long) rightend);
504   PaintStringEx (numberbuffer, (Int2) (rp->left+((len/Xscale)-20)),
505                  (Int2) (rp->bottom+20));
506   if (min < 0 && max > 0)
507   {
508     sprintf (numberbuffer, "%ld", 0L);
509     PaintStringEx (numberbuffer, (Int2) (rp->left+((len/Xscale)+10)),
510                    (Int2) (rp->bottom+min));
511   }
512 
513   xp = xpoints = MakeWorkingSeqGraphInt4Array (sgp->values, sgp->flags[2],
514                                                0, len, FALSE, sgp->a, sgp->b);
515   PlotTheWorkingArray (xpoints, len, Xscale, (Int4) sgp->min.realvalue, *rp,
516                        0, 0, 0, NULL);
517   MemFree (xpoints);
518   return;
519 }
520 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.