-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrx248um.html
2400 lines (2036 loc) · 111 KB
/
grx248um.html
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<html lang="en">
<head>
<title>GRX 2.4.8 User's Manual</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="GRX 2.4.8 User's Manual">
<meta name="generator" content="makeinfo 4.7">
<link title="Top" rel="top" href="#Top">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
<meta http-equiv="Content-Style-Type" content="text/css">
<style type="text/css"><!--
pre.display { font-family:inherit }
pre.format { font-family:inherit }
pre.smalldisplay { font-family:inherit; font-size:smaller }
pre.smallformat { font-family:inherit; font-size:smaller }
pre.smallexample { font-size:smaller }
pre.smalllisp { font-size:smaller }
span.sc { font-variant:small-caps }
span.roman { font-family: serif; font-weight: normal; }
--></style>
</head>
<body text="#000000" bgcolor="#CCCCCC" link="#0000EE" vlink="#551A8B" alink="#FF0000">
<center>
<h1><font color="#FF0000">G</font><font color="#00CC00">R</font><font color="#0000FF">X</font>
<small>2.4.8</small></h1>
<h1>a 2D graphics library for DOS, Linux, X11 and Win32</h1>
<h2>User's Manual</h2>
<p>Based on the original doc written by: Csaba Biegl on August 10, 1992
<p>Updated by: Mariano Alvarez Fernández on August 17, 2000
<p>Last update: August 14, 2007
</center>
<div class="node">
<p><hr>
<a name="Top"></a>Next: <a rel="next" accesskey="n" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<!-- node-name, next,previous, up -->
<h2 class="unnumbered">Abstract</h2>
<p><strong>GRX</strong> is a 2D graphics library originaly written by
Csaba Biegl for DJ Delorie's DOS port of the GCC compiler. Now it support
a big range of platforms, the main four are: DOS (DJGPPv2), Linux console,
X11 and Win32 (Mingw). On DOS it supports VGA, EGA and VESA compliant cards.
On Linux console it uses svgalib or the framebuffer. On X11 it must work on
any X11R5 (or later). From the 2.4 version, GRX comes with a Win32 driver.
The framebuffer Linux console driver was new in 2.4.2. From 2.4.7 there is a
support for x86_64 bits Linux machines and a support for an SDL driver
on MingW and X11. On MingW and X11 it runs on a window with the original
driver, and either full screen or on a window with the SDL driver.
<ul class="menu">
<li><a accesskey="1" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
</ul>
<!-- -->
<div class="node">
<p><hr>
<a name="A-User-Manual-For-GRX2"></a>
Next: <a rel="next" accesskey="n" href="#Hello-world">Hello world</a>,
Previous: <a rel="previous" accesskey="p" href="#Top">Top</a>,
Up: <a rel="up" accesskey="u" href="#Top">Top</a>
</div>
<h2 class="unnumbered">GRX2 User's Manual</h2>
<ul class="menu">
<li><a accesskey="1" href="#Top">Top</a>
<li><a accesskey="2" href="#Hello-world">Hello world</a>
<li><a accesskey="3" href="#Data-types-and-function-declarations">Data types and function declarations</a>
<li><a accesskey="4" href="#Setting-the-graphics-driver">Setting the graphics driver</a>
<li><a accesskey="5" href="#Setting-video-modes">Setting video modes</a>
<li><a accesskey="6" href="#Graphics-contexts">Graphics contexts</a>
<li><a accesskey="7" href="#Context-use">Context use</a>
<li><a accesskey="8" href="#Color-management">Color management</a>
<li><a accesskey="9" href="#Portable-use-of-a-few-colors">Portable use of a few colors</a>
<li><a href="#Graphics-primitives">Graphics primitives</a>
<li><a href="#Non_002dclipping-graphics-primitives">Non-clipping graphics primitives</a>
<li><a href="#Customized-line-drawing">Customized line drawing</a>
<li><a href="#Pattern-filled-graphics-primitives">Pattern filled graphics primitives</a>
<li><a href="#Patterned-line-drawing">Patterned line drawing</a>
<li><a href="#Image-manipulation">Image manipulation</a>
<li><a href="#Text-drawing">Text drawing</a>
<li><a href="#Drawing-in-user-coordinates">Drawing in user coordinates</a>
<li><a href="#Graphics-cursors">Graphics cursors</a>
<li><a href="#Keyboard-input">Keyboard input</a>
<li><a href="#Mouse-event-handling">Mouse event handling</a>
<li><a href="#Writing_002freading-PNM-graphics-files">Writing/reading PNM graphics files</a>
<li><a href="#Writing_002freading-PNG-graphics-files">Writing/reading PNG graphics files</a>
<li><a href="#Writing_002freading-JPEG-graphics-files">Writing/reading JPEG graphics files</a>
<li><a href="#Miscellaneous-functions">Miscellaneous functions</a>
<li><a href="#BGI-interface">BGI interface</a>
<li><a href="#Pascal-interface">Pascal interface</a>
<li><a href="#References">References</a>
</ul>
<!-- -->
<div class="node">
<p><hr>
<a name="Hello-world"></a>Next: <a rel="next" accesskey="n" href="#Data-types-and-function-declarations">Data types and function declarations</a>,
Previous: <a rel="previous" accesskey="p" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>,
Up: <a rel="up" accesskey="u" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<h3 class="unnumberedsec">Hello world</h3>
<p>The next program draws a double frame around the screen and writes "Hello, GRX
world" centered. Then it waits after a key is pressed.
<pre class="example"> #include <string.h>
#include <grx20.h>
#include <grxkeys.h>
int main()
{
char *message = "Hello, GRX world";
int x, y;
GrTextOption grt;
GrSetMode( GR_default_graphics );
grt.txo_font = &GrDefaultFont;
grt.txo_fgcolor.v = GrWhite();
grt.txo_bgcolor.v = GrBlack();
grt.txo_direct = GR_TEXT_RIGHT;
grt.txo_xalign = GR_ALIGN_CENTER;
grt.txo_yalign = GR_ALIGN_CENTER;
grt.txo_chrtype = GR_BYTE_TEXT;
GrBox( 0,0,GrMaxX(),GrMaxY(),GrWhite() );
GrBox( 4,4,GrMaxX()-4,GrMaxY()-4,GrWhite() );
x = GrMaxX()/2;
y = GrMaxY()/2;
GrDrawString( message,strlen( message ),x,y,&grt );
GrKeyRead();
return 0;
}
</pre>
<p>How to compile the hello world (assuming the GRX library was
previously installed)
<pre class="example"> DJGPP: gcc -o hellogrx.exe hellogrx.c -lgrx20
Mingw: gcc -o hellogrx.exe hellogrx.c -lgrx20 -mwindows
X11 : gcc -o hellogrx hellogrx.c -D__XWIN__ -I/usr/X11R6/include
-lgrx20X -L/usr/X11R6/lib -lX11
Linux: gcc -o hellogrx hellogrx.c -lgrx20 -lvga
For the SDL driver:
Mingw: gcc -o hellogrx.exe hellogrx.c -lgrx20S -lSDL
X11 : gcc -o hellogrx hellogrx.c -D__XWIN__ -I/usr/X11R6/include
-lgrx20S -lSDL -lpthread -L/usr/X11R6/lib -lX11
For x86_64 systems add -m32 or -m64 for 32/64 bits executables
and replace /lib by /lib64 as needed
</pre>
<!-- -->
<div class="node">
<p><hr>
<a name="Data-types-and-function-declarations"></a>Next: <a rel="next" accesskey="n" href="#Setting-the-graphics-driver">Setting the graphics driver</a>,
Previous: <a rel="previous" accesskey="p" href="#Hello-world">Hello world</a>,
Up: <a rel="up" accesskey="u" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<h3 class="unnumberedsec">Data types and function declarations</h3>
<p>All public data structures and graphics primitives meant for usage by the
application program are declared/prototyped in the header files (in the
'include' sub-directory):
<pre class="example"> * grdriver.h graphics driver format specifications
* grfontdv.h format of a font when loaded into memory
* grx20.h drawing-related structures and functions
* grxkeys.h platform independent key definitions
User programs normally only include <strong>include/grx20.h</strong> and <strong>include/grxkeys.h</strong>
</pre>
<!-- -->
<div class="node">
<p><hr>
<a name="Setting-the-graphics-driver"></a>Next: <a rel="next" accesskey="n" href="#Setting-video-modes">Setting video modes</a>,
Previous: <a rel="previous" accesskey="p" href="#Data-types-and-function-declarations">Data types and function declarations</a>,
Up: <a rel="up" accesskey="u" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<h3 class="unnumberedsec">Setting the graphics driver</h3>
<p>The graphics driver is normally set by the final user by the environment
variable GRX20DRV, but a program can set it using:
<pre class="example"> int GrSetDriver(char *drvspec);
</pre>
<p>The drvspec string has the same format as the environment variable:
<pre class="example"> <driver> gw <width> gh <height> nc <colors>
</pre>
<p>Available drivers are for:
<pre class="example"> * DOS => herc, stdvga, stdega, et4000, cl5426, mach64, ati28800, s3, VESA, memory
* Linux => svgalib, linuxfb, memory
* X11 => xwin, memory
* Win32 => win32, memory
* SDL (Win32 and X11) => sdl::fs, sdl::ww, memory
</pre>
<p>The xwin and win32 drivers are windowed.
The SDL driver on the same systems can be either fullscreen (::fs) or windowed (::ww).
<p>The optionals gw, gh and nc parameters set the desired default graphics mode.
Normal values for 'nc' are 2, 16, 256, 64K and 16M. The current driver name can
be obtained from:
<pre class="example"> GrCurrentVideoDriver()->name
</pre>
<!-- -->
<div class="node">
<p><hr>
<a name="Setting-video-modes"></a>Next: <a rel="next" accesskey="n" href="#Graphics-contexts">Graphics contexts</a>,
Previous: <a rel="previous" accesskey="p" href="#Setting-the-graphics-driver">Setting the graphics driver</a>,
Up: <a rel="up" accesskey="u" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<h3 class="unnumberedsec">Setting video modes</h3>
<p>Before a program can do any graphics drawing it has to configure the graphics
driver for the desired graphics mode. It is done with the GrSetMode function as
follows:
<pre class="example"> int GrSetMode(int which,...);
</pre>
<p>On succes it returns non-zero (TRUE). The which parameter can be one of the
following constants, declared in grx20.h:
<pre class="example"> typedef enum _GR_graphicsModes {
GR_80_25_text,
GR_default_text,
GR_width_height_text,
GR_biggest_text,
GR_320_200_graphics,
GR_default_graphics,
GR_width_height_graphics,
GR_biggest_noninterlaced_graphics,
GR_biggest_graphics,
GR_width_height_color_graphics,
GR_width_height_color_text,
GR_custom_graphics,
GR_width_height_bpp_graphics,
GR_width_height_bpp_text,
GR_custom_bpp_graphics,
GR_NC_80_25_text,
GR_NC_default_text,
GR_NC_width_height_text,
GR_NC_biggest_text,
GR_NC_320_200_graphics,
GR_NC_default_graphics,
GR_NC_width_height_graphics,
GR_NC_biggest_noninterlaced_graphics,
GR_NC_biggest_graphics,
GR_NC_width_height_color_graphics,
GR_NC_width_height_color_text,
GR_NC_custom_graphics,
GR_NC_width_height_bpp_graphics,
GR_NC_width_height_bpp_text,
GR_NC_custom_bpp_graphics,
} GrGraphicsMode;
</pre>
<p>The GR_width_height_text and GR_width_height_graphics modes require the two
size arguments: int width and int height.
<p>The GR_width_height_color_graphics and GR_width_height_color_text modes
require three arguments: int width, int height and GrColor colors.
<p>The GR_width_height_bpp_graphics and GR_width_height_bpp_text modes require
three arguments: int width, int height and int bpp (bits per plane instead
number of colors).
<p>The GR_custom_graphics and GR_custom_bpp_graphics modes require five
arguments: int width, int height, GrColor colors or int bpp, int vx and int vy.
Using this modes you can set a virtual screen of vx by vy size.
<p>A call with any other mode does not require any arguments.
<p>The GR_NC_... modes are equivalent to the GR_.. ones, but they don't clear the
video memory.
<p>Graphics drivers can provide info of the supported graphics modes, use the
next code skeleton to colect the data:
<pre class="example"> {
GrFrameMode fm;
const GrVideoMode *mp;
for(fm =GR_firstGraphicsFrameMode; fm <= GR_lastGraphicsFrameMode; fm++) {
mp = GrFirstVideoMode(fm);
while( mp != NULL ) {
..
.. use the mp info
..
mp = GrNextVideoMode(mp))
}
}
}
</pre>
<p>Don't worry if you don't understand it, normal user programs don't need to
know about FrameModes. The GrVideoMode structure has the following fields:
<pre class="example"> typedef struct _GR_videoMode GrVideoMode;
struct _GR_videoMode {
char present; /* is it really available? */
char bpp; /* log2 of # of colors */
short width,height; /* video mode geometry */
short mode; /* BIOS mode number (if any) */
int lineoffset; /* scan line length */
int privdata; /* driver can use it for anything */
struct _GR_videoModeExt *extinfo; /* extra info (maybe shared) */
};
</pre>
<p>The width, height and bpp members are the useful information if you are
interested in set modes other than the GR_default_graphics.
<p>A user-defined function can be invoked every time the video mode is changed
(i.e. GrSetMode is called). This function should not take any parameters and
don't return any value. It can be installed (for all subsequent GrSetMode calls)
with the:
<pre class="example"> void GrSetModeHook(void (*hookfunc)(void));
</pre>
<p>function. The current graphics mode (one of the valid mode argument values for
GrSetMode) can be obtained with the:
<pre class="example"> GrGraphicsMode GrCurrentMode(void);
</pre>
<p>function, while the type of the installed graphics adapter can be determined
with the:
<pre class="example"> GrVideoAdapter GrAdapterType(void);
</pre>
<p>function. GrAdapterType returns the type of the adapter as one of the following
symbolic constants (defined in grx20.h):
<pre class="example"> typedef enum _GR_videoAdapters {
GR_UNKNOWN = (-1), /* not known (before driver set) */
GR_VGA, /* VGA adapter */
GR_EGA, /* EGA adapter */
GR_HERC, /* Hercules mono adapter */
GR_8514A, /* 8514A or compatible */
GR_S3, /* S3 graphics accelerator */
GR_XWIN, /* X11 driver */
GR_WIN32, /* WIN32 driver */
GR_LNXFB, /* Linux framebuffer */
GR_SDL, /* SDL driver */
GR_MEM /* memory only driver */
} GrVideoAdapter;
</pre>
<p>Note that the VESA driver return GR_VGA here.
<!-- -->
<div class="node">
<p><hr>
<a name="Graphics-contexts"></a>Next: <a rel="next" accesskey="n" href="#Context-use">Context use</a>,
Previous: <a rel="previous" accesskey="p" href="#Setting-video-modes">Setting video modes</a>,
Up: <a rel="up" accesskey="u" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<h3 class="unnumberedsec">Graphics contexts</h3>
<p>The library supports a set of drawing regions called contexts (the GrContext
structure). These can be in video memory or in system memory. Contexts in system
memory always have the same memory organization as the video memory. When
GrSetMode is called, a default context is created which maps to the whole
graphics screen. Contexts are described by the GrContext data structure:
<pre class="example"> typedef struct _GR_context GrContext;
struct _GR_context {
struct _GR_frame gc_frame; /* frame buffer info */
struct _GR_context *gc_root; /* context which owns frame */
int gc_xmax; /* max X coord (width - 1) */
int gc_ymax; /* max Y coord (height - 1) */
int gc_xoffset; /* X offset from root's base */
int gc_yoffset; /* Y offset from root's base */
int gc_xcliplo; /* low X clipping limit */
int gc_ycliplo; /* low Y clipping limit */
int gc_xcliphi; /* high X clipping limit */
int gc_ycliphi; /* high Y clipping limit */
int gc_usrxbase; /* user window min X coordinate */
int gc_usrybase; /* user window min Y coordinate */
int gc_usrwidth; /* user window width */
int gc_usrheight; /* user window height */
# define gc_baseaddr gc_frame.gf_baseaddr
# define gc_selector gc_frame.gf_selector
# define gc_onscreen gc_frame.gf_onscreen
# define gc_memflags gc_frame.gf_memflags
# define gc_lineoffset gc_frame.gf_lineoffset
# define gc_driver gc_frame.gf_driver
};
</pre>
<p>The following four functions return information about the layout of and memory
occupied by a graphics context of size width by height in the current graphics
mode (as set up by GrSetMode):
<pre class="example"> int GrLineOffset(int width);
int GrNumPlanes(void);
long GrPlaneSize(int w,int h);
long GrContextSize(int w,int h);
</pre>
<p>GrLineOffset always returns the offset between successive pixel rows of the
context in bytes. GrNumPlanes returns the number of bitmap planes in the current
graphics mode. GrContextSize calculates the total amount of memory needed by a
context, while GrPlaneSize calculates the size of a bitplane in the context. The
function:
<pre class="example"> GrContext *GrCreateContext(int w,int h,char far *memory[4],GrContext *where);
</pre>
<p>can be used to create a new context in system memory. The NULL pointer is also
accepted as the value of the memory and where arguments, in this case the
library allocates the necessary amount of memory internally. It is a general
convention in the library that functions returning pointers to any GRX
specific data structure have a last argument (most of the time named where in
the prototypes) which can be used to pass the address of the data structure
which should be filled with the result. If this where pointer has the value of
NULL, then the library allocates space for the data structure internally.
<p>The memory argument is really a 4 pointer array, each pointer must point to
space to handle GrPlaneSize(w,h) bytes, really only GrNumPlanes() pointers must
be malloced, the rest can be NULL. Nevertheless the normal use (see below) is
<pre class="example"> gc = GrCreateContext(w,h,NULL,NULL);
</pre>
<p>so yo don't need to care about.
<p>The function:
<pre class="example">
GrContext *GrCreateSubContext(int x1,int y1,int x2,int y2,
const GrContext *parent,GrContext *where);
</pre>
<p>creates a new sub-context which maps to a part of an existing context. The
coordinate arguments (x1 through y2) are interpreted relative to the parent
context's limits. Pixel addressing is zero-based even in sub-contexts, i.e. the
address of the top left pixel is (0,0) even in a sub-context which has been
mapped onto the interior of its parent context.
<p>Sub-contexts can be resized, but not their parents (i.e. anything returned by
GrCreateContext or set up by GrSetMode cannot be resized – because this could
lead to irrecoverable "loss" of drawing memory. The following function can be
used for this purpose:
<pre class="example"> void GrResizeSubContext(GrContext *context,int x1,int y1,int x2,int y2);
</pre>
<p>The current context structure is stored in a static location in the library.
(For efficiency reasons – it is used quite frequently, and this way no pointer
dereferencing is necessary.) The context stores all relevant information about
the video organization, coordinate limits, etc... The current context can be set
with the:
<pre class="example"> void GrSetContext(const GrContext *context);
</pre>
<p>function. This function will reset the current context to the full graphics
screen if it is passed the NULL pointer as argument. The value of the current
context can be saved into a GrContext structure pointed to by where using:
<pre class="example"> GrContext *GrSaveContext(GrContext *where);
</pre>
<p>(Again, if where is NULL, the library allocates the space.) The next two
functions:
<pre class="example"> const GrContext *GrCurrentContext(void);
const GrContext *GrScreenContext(void);
</pre>
<p>return the current context and the screen context respectively. Contexts can be
destroyed with:
<pre class="example"> void GrDestroyContext(GrContext *context);
</pre>
<p>This function will free the memory occupied by the context only if it was
allocated originally by the library. The next three functions set up and query
the clipping limits associated with the current context:
<pre class="example"> void GrSetClipBox(int x1,int y1,int x2,int y2);
void GrGetClipBox(int *x1p,int *y1p,int *x2p,int *y2p);
void GrResetClipBox(void);
</pre>
<p>GrResetClipBox sets the clipping limits to the limits of context. These are
the limits set up initially when a context is created. There are three similar
functions to sets/gets the clipping limits of any context:
<pre class="example"> void GrSetClipBoxC(GrContext *c,int x1,int y1,int x2,int y2);
void GrGetClipBoxC(const GrContext *c,int *x1p,int *y1p,int *x2p,int *y2p);
void GrResetClipBoxC(GrContext *c);
</pre>
<p>The limits of the current context can be obtained using the following
functions:
<pre class="example"> int GrMaxX(void);
int GrMaxY(void);
int GrSizeX(void);
int GrSizeY(void);
</pre>
<p>The Max functions return the biggest valid coordinate, while the Size
functions return a value one higher. The limits of the graphics screen
(regardless of the current context) can be obtained with:
<pre class="example"> int GrScreenX(void);
int GrScreenY(void);
</pre>
<p>If you had set a virtual screen (using a custom graphics mode), the limits of
the virtual screen can be fetched with:
<pre class="example"> int GrVirtualX(void);
int GrVirtualY(void);
</pre>
<p>The routine:
<pre class="example"> int GrScreenIsVirtual(void);
</pre>
<p>returns non zero if a virtual screen is set. The rectangle showed in the real
screen can be set with:
<pre class="example"> int GrSetViewport(int xpos,int ypos);
</pre>
<p>and the current viewport position can be obtained by:
<pre class="example"> int GrViewportX(void);
int GrViewportY(void);
</pre>
<!-- -->
<div class="node">
<p><hr>
<a name="Context-use"></a>Next: <a rel="next" accesskey="n" href="#Color-management">Color management</a>,
Previous: <a rel="previous" accesskey="p" href="#Graphics-contexts">Graphics contexts</a>,
Up: <a rel="up" accesskey="u" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<h3 class="unnumberedsec">Context use</h3>
<p>Here is a example of normal context use:
<pre class="example"> GrContext *grc;
if( (grc = GrCreateContext( w,h,NULL,NULL )) == NULL ){
...process the error
}
else {
GrSetContext( grc );
...do some drawing
...and probably bitblt to the screen context
GrSetContext( NULL ); /* the screen context! */
GrDestroyContext( grc );
}
</pre>
<p>But if you have a GrContext variable (not a pointer) you want to use (probably
because is static to some routines) you can do:
<pre class="example"> static GrContext grc; /* not a pointer!! */
if( GrCreateContext( w,h,NULL,&grc )) == NULL ) {
...process the error
}
else {
GrSetContext( &grc );
...do some drawing
...and probably bitblt to the screen context
GrSetContext( NULL ); /* the screen context! */
GrDestroyContext( &grc );
}
</pre>
<p>Note that GrDestoryContext knows if grc was automatically malloced or not!!
<p>Only if you don't want GrCreateContext use malloc at all, you must allocate
the memory buffers and pass it to GrCreateContext.
<p>Using GrCreateSubContext is the same, except it doesn't need the buffer,
because it uses the parent buffer.
<p>See the <strong>test/winclip.c</strong> and <strong>test/wintest.c</strong> examples.
<!-- -->
<div class="node">
<p><hr>
<a name="Color-management"></a>Next: <a rel="next" accesskey="n" href="#Portable-use-of-a-few-colors">Portable use of a few colors</a>,
Previous: <a rel="previous" accesskey="p" href="#Context-use">Context use</a>,
Up: <a rel="up" accesskey="u" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<h3 class="unnumberedsec">Color management</h3>
<p>GRX defines the type GrColor for color variables. GrColor it's a 32 bits
integer. The 8 left bits are reserved for the write mode (see below). The 24
bits right are the color value.
<p>The library supports two models for color management. In the 'indirect' (or
color table) model, color values are indices to a color table. The color table
slots will be allocated with the highest resolution supported by the hardware
(EGA: 2 bits, VGA: 6 bits) with respect to the component color intensities. In
the 'direct' (or RGB) model, color values map directly into component color
intensities with non-overlapping bitfields of the color index representing the
component colors.
<p>Color table model is supported until 256 color modes. The RGB model is
supported in 256 color and up color modes.
<p>In RGB model the color index map to component color intensities depend on the
video mode set, so it can't be assumed the component color bitfields (but if you
are curious check the GrColorInfo global structure in grx20.h).
<p>After the first GrSetMode call two colors are always defined: black and white.
The color values of these two colors are returned by the functions:
<pre class="example"> GrColor GrBlack(void);
GrColor GrWhite(void);
</pre>
<p>GrBlack() is guaranteed to be 0.
<p>The library supports five write modes (a write mode descibes the operation
between the actual bit color and the one to be set): write, XOR, logical OR,
logical AND and IMAGE. These can be selected with OR-ing the color value with
one of the following constants declared in grx20.h :
<pre class="example"> #define GrWRITE 0UL /* write color */
#define GrXOR 0x01000000UL /* to "XOR" any color to the screen */
#define GrOR 0x02000000UL /* to "OR" to the screen */
#define GrAND 0x03000000UL /* to "AND" to the screen */
#define GrIMAGE 0x04000000UL /* blit: write, except given color */
</pre>
<p>The GrIMAGE write mode only works with the bitblt function.
By convention, the no-op color is obtained by combining color value 0 (black)
with the XOR operation. This no-op color has been defined in grx20.h as:
<pre class="example"> #define GrNOCOLOR (GrXOR | 0) /* GrNOCOLOR is used for "no" color */
</pre>
<p>The write mode part and the color value part of a GrColor variable can be
obtained OR-ing it with one of the following constants declared in grx20.h:
<pre class="example"> #define GrCVALUEMASK 0x00ffffffUL /* color value mask */
#define GrCMODEMASK 0xff000000UL /* color operation mask */
</pre>
<p>The number of colors in the current graphics mode is returned by the:
<pre class="example"> GrColor GrNumColors(void);
</pre>
<p>function, while the number of unused, available color can be obtained by
calling:
<pre class="example"> GrColor GrNumFreeColors(void);
</pre>
<p>Colors can be allocated with the:
<pre class="example"> GrColor GrAllocColor(int r,int g,int b);
GrColor GrAllocColor2(long hcolor);
</pre>
<p>functions (component intensities can range from 0 to 255,
hcolor must be in 0xRRGGBB format), or with the:
<pre class="example"> GrColor GrAllocCell(void);
</pre>
<p>function. In the second case the component intensities of the returned color can
be set with:
<pre class="example"> void GrSetColor(GrColor color,int r,int g,int b);
</pre>
<p>In the color table model both Alloc functions return GrNOCOLOR if there are no
more free colors available. In the RGB model GrNumFreeColors returns 0 and
GrAllocCell always returns GrNOCOLOR, as colors returned by GrAllocCell are
meant to be changed – what is not supposed to be done in RGB mode. Also note
that GrAllocColor operates much more efficiently in RGB mode, and that it never
returns GrNOCOLOR in this case.
<p>Color table entries can be freed (when not in RGB mode) by calling:
<pre class="example"> void GrFreeColor(GrColor color);
</pre>
<p>The component intensities of any color can be queried using one of this function:
<pre class="example"> void GrQueryColor(GrColor c,int *r,int *g,int *b);
void GrQueryColor2(GrColor c,long *hcolor);
</pre>
<p>Initially the color system is in color table (indirect) model if there are 256
or less colors. 256 color modes can be put into the RGB model by calling:
<pre class="example"> void GrSetRGBcolorMode(void);
</pre>
<p>The color system can be reset (i.e. put back into color table model if
possible, all colors freed except for black and white) by calling:
<pre class="example"> void GrResetColors(void);
</pre>
<p>The function:
<pre class="example"> void GrRefreshColors(void);
</pre>
<p>reloads the currently allocated color values into the video hardware. This
function is not needed in typical applications, unless the display adapter is
programmed directly by the application.
<p>This functions:
<pre class="example"> GrColor GrAllocColorID(int r,int g,int b);
GrColor GrAllocColor2ID(long hcolor);
void GrQueryColorID(GrColor c,int *r,int *g,int *b);
void GrQueryColor2ID(GrColor c,long *hcolor);
</pre>
<p>are inlined versions (except if you compile GRX with GRX_SKIP_INLINES defined)
to be used in the RGB model (in the color table model they call the normal
routines).
<p>See the <strong>test/rgbtest.c</strong> and <strong>test/colorops.c</strong> examples.
<!-- -->
<div class="node">
<p><hr>
<a name="Portable-use-of-a-few-colors"></a>Next: <a rel="next" accesskey="n" href="#Graphics-primitives">Graphics primitives</a>,
Previous: <a rel="previous" accesskey="p" href="#Color-management">Color management</a>,
Up: <a rel="up" accesskey="u" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<h3 class="unnumberedsec">Portable use of a few colors</h3>
<p>People that only want to use a few colors find the GRX color handling a bit
confusing, but it gives the power to manage a lot of color deeps and two color
models. Here are some guidelines to easily use the famous 16 ega colors in GRX
programs. We need this GRX function:
<pre class="example"> GrColor *GrAllocEgaColors(void);
</pre>
<p>it returns a 16 GrColor array with the 16 ega colors alloced (really it's a
trivial function, read the source src/setup/colorega.c). We can use a
construction like that:
<p>First, in your C code make a global pointer, and init it after set the
graphics mode:
<pre class="example"> GrColor *egacolors;
....
int your_setup_function( ... )
{
...
GrSetMode( ... )
...
egacolors = GrAllocEgaColors();
...
}
</pre>
<p>Next, add this to your main include file:
<pre class="example"> extern GrColor *egacolors;
#define BLACK egacolors[0]
#define BLUE egacolors[1]
#define GREEN egacolors[2]
#define CYAN egacolors[3]
#define RED egacolors[4]
#define MAGENTA egacolors[5]
#define BROWN egacolors[6]
#define LIGHTGRAY egacolors[7]
#define DARKGRAY egacolors[8]
#define LIGHTBLUE egacolors[9]
#define LIGHTGREEN egacolors[10]
#define LIGHTCYAN egacolors[11]
#define LIGHTRED egacolors[12]
#define LIGHTMAGENTA egacolors[13]
#define YELLOW egacolors[14]
#define WHITE egacolors[15]
</pre>
<p>Now you can use the defined colors in your code. Note that if you are in color
table model in a 16 color mode, you have exhausted the color table. Note too
that this don't work to initialize static variables with a color, because
egacolors is not initialized.
<!-- -->
<div class="node">
<p><hr>
<a name="Graphics-primitives"></a>Next: <a rel="next" accesskey="n" href="#Non_002dclipping-graphics-primitives">Non-clipping graphics primitives</a>,
Previous: <a rel="previous" accesskey="p" href="#Portable-use-of-a-few-colors">Portable use of a few colors</a>,
Up: <a rel="up" accesskey="u" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<h3 class="unnumberedsec">Graphics primitives</h3>
<p>The screen, the current context or the current clip box can be cleared (i.e.
set to a desired background color) by using one of the following three
functions:
<pre class="example"> void GrClearScreen(GrColor bg);
void GrClearcontext(GrColor bg);
void GrClearClipBox(GrColor bg);
</pre>
<p>Thanks to the special GrColor definition, you can do more than simple clear
with this functions, by example with:
<pre class="example"> GrClearScreen( GrWhite()|GrXOR );
</pre>
<p>the graphics screen is negativized, do it again and the screen is restored.
<p>The following line drawing graphics primitives are supported by the library:
<pre class="example"> void GrPlot(int x,int y,GrColor c);
void GrLine(int x1,int y1,int x2,int y2,GrColor c);
void GrHLine(int x1,int x2,int y,GrColor c);
void GrVLine(int x,int y1,int y2,GrColor c);
void GrBox(int x1,int y1,int x2,int y2,GrColor c);
void GrCircle(int xc,int yc,int r,GrColor c);
void GrEllipse(int xc,int yc,int xa,int ya,GrColor c);
void GrCircleArc(int xc,int yc,int r,int start,int end,int style,GrColor c);
void GrEllipseArc(int xc,int yc,int xa,int ya,
int start,int end,int style,GrColor c);
void GrPolyLine(int numpts,int points[][2],GrColor c);
void GrPolygon(int numpts,int points[][2],GrColor c);
</pre>
<p>All primitives operate on the current graphics context. The last argument of
these functions is always the color to use for the drawing. The HLine and VLine
primitives are for drawing horizontal and vertical lines. They have been
included in the library because they are more efficient than the general line
drawing provided by GrLine. The ellipse primitives can only draw ellipses with
their major axis parallel with either the X or Y coordinate axis. They take the
half X and Y axis length in the xa and ya arguments. The arc (circle and
ellipse) drawing functions take the start and end angles in tenths of degrees
(i.e. meaningful range: 0 ... 3600). The angles are interpreted
counter-clockwise starting from the positive X axis. The style argument can be
one of this defines from grx20.h:
<pre class="example"> #define GR_ARC_STYLE_OPEN 0
#define GR_ARC_STYLE_CLOSE1 1
#define GR_ARC_STYLE_CLOSE2 2
</pre>
<p>GR_ARC_STYLE_OPEN draws only the arc, GR_ARC_STYLE_CLOSE1 closes the arc with
a line between his start and end point, GR_ARC_STYLE_CLOSE1 draws the typical
cake slice. This routine:
<pre class="example"> void GrLastArcCoords(int *xs,int *ys,int *xe,int *ye,int *xc,int *yc);
</pre>
<p>can be used to retrieve the start, end, and center points used by the last arc
drawing functions.
<p>See the <strong>test/circtest.c</strong> and <strong>test/arctest.c</strong> examples.
<p>The polyline and polygon primitives take the address of an n by 2 coordinate
array. The X values should be stored in the elements with 0 second index, and
the Y values in the elements with a second index value of 1. Coordinate arrays
passed to the polygon primitive can either contain or omit the closing edge of
the polygon – the primitive will append it to the list if it is missing.
<p>See the <strong>test/polytest.c</strong> example.
<p>Because calculating the arc points it's a very time consuming operation, there
are two functions to pre-calculate the points, that can be used next with
polyline and polygon primitives:
<pre class="example"> int GrGenerateEllipse(int xc,int yc,int xa,int ya,
int points[GR_MAX_ELLIPSE_POINTS][2]);
int GrGenerateEllipseArc(int xc,int yc,int xa,int ya,int start,int end,
int points[GR_MAX_ELLIPSE_POINTS][2]);
</pre>
<p>The following filled primitives are available:
<pre class="example"> void GrFilledBox(int x1,int y1,int x2,int y2,GrColor c);
void GrFramedBox(int x1,int y1,int x2,int y2,int wdt,const GrFBoxColors *c);
void GrFilledCircle(int xc,int yc,int r,GrColor c);
void GrFilledEllipse(int xc,int yc,int xa,int ya,GrColor c);
void GrFilledCircleArc(int xc,int yc,int r,
int start,int end,int style,GrColor c);
void GrFilledEllipseArc(int xc,int yc,int xa,int ya,
int start,int end,int style,GrColor c);
void GrFilledPolygon(int numpts,int points[][2],GrColor c);
void GrFilledConvexPolygon(int numpts,int points[][2],GrColor c);
</pre>
<p>Similarly to the line drawing, all of the above primitives operate on the
current graphics context. The GrFramedBox primitive can be used to draw
motif-like shaded boxes and "ordinary" framed boxes as well. The x1 through y2
coordinates specify the interior of the box, the border is outside this area,
wdt pixels wide. The primitive uses five different colors for the interior and
four borders of the box which are specified in the GrFBoxColors structure:
<pre class="example"> typedef struct {
GrColor fbx_intcolor;
GrColor fbx_topcolor;
GrColor fbx_rightcolor;
GrColor fbx_bottomcolor;
GrColor fbx_leftcolor;
} GrFBoxColors;
</pre>
<p>The GrFilledConvexPolygon primitive can be used to fill convex polygons. It
can also be used to fill some concave polygons whose boundaries do not intersect
any horizontal scan line more than twice. All other concave polygons have to be
filled with the (somewhat less efficient) GrFilledPolygon primitive. This
primitive can also be used to fill several disjoint nonoverlapping polygons in
a single operation.
<p>The function:
<pre class="example"> void GrFloodFill(int x, int y, GrColor border, GrColor c);
</pre>
<p>flood-fills the area bounded by the color border using x, y like the starting
point.
<p>The current color value of any pixel in the current context can be obtained
with:
<pre class="example"> GrColor GrPixel(int x,int y);
</pre>
<p>and:
<pre class="example"> GrColor GrPixelC(GrContext *c,int x,int y);
</pre>
<p>do the same for any context.
<p>Rectangular areas can be transferred within a context or between contexts by
calling:
<pre class="example"> void GrBitBlt(GrContext *dest,int x,int y,GrContext *source,
int x1,int y1,int x2,int y2,GrColor op);
</pre>
<p>x, y is the position in the destination context, and x1, y1, x2, y2 the area
from the source context to be transfered. The op argument should be one of
supported color write modes (GrWRITE, GrXOR, GrOR, GrAND, GrIMAGE), it will
control how the pixels from the source context are combined with the pixels in
the destination context (the GrIMAGE op must be ored with the color value to be
handled as transparent). If either the source or the destination context
argument is the NULL pointer then the current context is used for that argument.
<p>See the <strong>test/blittest.c</strong> example.
<p>A efficient form to get/put pixels from/to a context can be achieved using the
next functions:
<pre class="example"> const GrColor *GrGetScanline(int x1,int x2,int yy);
const GrColor *GrGetScanlineC(GrContext *ctx,int x1,int x2,int yy);
void GrPutScanline(int x1,int x2,int yy,const GrColor *c, GrColor op);
</pre>
<p>The Get functions return a pointer to a static GrColor pixel array (or NULL if
they fail) with the color values of a row (yy) segment (x1 to x2). GrGetScanline
uses the current context. GrGestScanlineC uses the context ctx (that can be NULL
to refer to the current context). Note that the output is only valid until the
next GRX call.
<p>GrPutScanline puts the GrColor pixel array c on the yy row segmet defined by
x1 to x2 in the current context using the op operation. op can be any of
GrWRITE, GrXOR, GrOR, GrAND or GrIMAGE. Data in c must fit GrCVALUEMASK
otherwise the results are implementation dependend. So you can't supply
operation code with the pixel data!.
<!-- -->
<div class="node">
<p><hr>
<a name="Non_002dclipping-graphics-primitives"></a>Next: <a rel="next" accesskey="n" href="#Customized-line-drawing">Customized line drawing</a>,
Previous: <a rel="previous" accesskey="p" href="#Graphics-primitives">Graphics primitives</a>,
Up: <a rel="up" accesskey="u" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<h3 class="unnumberedsec">Non-clipping graphics primitives</h3>
<p>There is a non-clipping version of some of the elementary primitives. These
are somewhat more efficient than the regular versions. These are to be used only
in situations when it is absolutely certain that no drawing will be performed
beyond the boundaries of the current context. Otherwise the program will almost
certainly crash! The reason for including these functions is that they are
somewhat more efficient than the regular, clipping versions. ALSO NOTE: These
function do not check for conflicts with the mouse cursor. (See the explanation
about the mouse cursor handling later in this document.) The list of the
supported non-clipping primitives:
<pre class="example"> void GrPlotNC(int x,int y,GrColor c);
void GrLineNC(int x1,int y1,int x2,int y2,GrColor c);
void GrHLineNC(int x1,int x2,int y,GrColor c);
void GrVLineNC(int x,int y1,int y2,GrColor c);
void GrBoxNC(int x1,int y1,int x2,int y2,GrColor c);
void GrFilledBoxNC(int x1,int y1,int x2,int y2,GrColor c);
void GrFramedBoxNC(int x1,int y1,int x2,int y2,int wdt,const GrFBoxColors *c);
void grbitbltNC(GrContext *dst,int x,int y,GrContext *src,
int x1,int y1,int x2,int y2,GrColor op);
GrColor GrPixelNC(int x,int y);
GrColor GrPixelCNC(GrContext *c,int x,int y);
</pre>
<!-- -->
<div class="node">
<p><hr>
<a name="Customized-line-drawing"></a>Next: <a rel="next" accesskey="n" href="#Pattern-filled-graphics-primitives">Pattern filled graphics primitives</a>,
Previous: <a rel="previous" accesskey="p" href="#Non_002dclipping-graphics-primitives">Non-clipping graphics primitives</a>,
Up: <a rel="up" accesskey="u" href="#A-User-Manual-For-GRX2">A User Manual For GRX2</a>
<br>
</div>
<h3 class="unnumberedsec">Customized line drawing</h3>