From 7f1228cb260fd155cc7d61cd21683f0d209b850a Mon Sep 17 00:00:00 2001 From: Toshio Sekiya Date: Fri, 22 Jan 2021 22:14:05 +0900 Subject: [PATCH] Add section 19. --- .gitignore | 2 + Rakefile | 8 +- Readme.md | 1 + gfm/sec19.md | 197 +++++++++++++++++++++++++++++++++++++++++ image/cairo.png | Bin 0 -> 16076 bytes image/cairo.xcf | Bin 0 -> 32167 bytes image/da1.png | Bin 0 -> 9554 bytes src/misc/cairo.c | 31 +++++++ src/misc/da1.c | 39 ++++++++ src/misc/rectangle.png | Bin 0 -> 341 bytes src/sec19.src.md | 125 ++++++++++++++++++++++++++ 11 files changed, 399 insertions(+), 4 deletions(-) create mode 100644 gfm/sec19.md create mode 100644 image/cairo.png create mode 100644 image/cairo.xcf create mode 100644 image/da1.png create mode 100644 src/misc/cairo.c create mode 100644 src/misc/da1.c create mode 100644 src/misc/rectangle.png create mode 100644 src/sec19.src.md diff --git a/.gitignore b/.gitignore index bdb1e74..44cf7dd 100755 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ src/img.rb src/imgsize.rb src/toi.rb src/misc/a.out +src/misc/cairo2.c +src/misc/cairo2.pdf src/tfv/a.out src/tfe/a.out src/tfe/hello.txt diff --git a/Rakefile b/Rakefile index a6f3a03..b9d8d14 100644 --- a/Rakefile +++ b/Rakefile @@ -201,9 +201,9 @@ end end end -task html: htmlfilenames+["html/index.html"] +task html: ["html/index.html"] -file "html/index.html" do +file "html/index.html" => htmlfilenames do 0.upto(srcfiles.size-1) do |i| h = File.open(srcfiles[i].path) { |file| file.readline } h = h.gsub(/^#* */,"").chomp @@ -249,9 +249,9 @@ task pdf: "latex" do sh "mv latex/main.pdf latex/gtk4_tutorial.pdf" end -task latex: texfilenames+["latex/main.tex"] +task latex: ["latex/main.tex"] -file "latex/main.tex" do +file "latex/main.tex" => texfilenames do 0.upto(srcfiles.size-1) do |i| main += " \\input{#{srcfiles[i].to_tex}}\n" end diff --git a/Readme.md b/Readme.md index 5f2d6d2..a8f019f 100644 --- a/Readme.md +++ b/Readme.md @@ -31,3 +31,4 @@ You can read it without download. 1. [Menu and action](gfm/sec16.md) 1. [Stateful action](gfm/sec17.md) 1. [Ui file for menu and action entries](gfm/sec18.md) +1. [GtkDrawingArea and Cairo](gfm/sec19.md) diff --git a/gfm/sec19.md b/gfm/sec19.md new file mode 100644 index 0000000..12b3b81 --- /dev/null +++ b/gfm/sec19.md @@ -0,0 +1,197 @@ +Up: [Readme.md](../Readme.md), Prev: [Section 18](sec18.md) + +# GtkDrawingArea and Cairo + +If you want to draw dynamically, like an image window of gimp graphics editor, GtkDrawingArea widget is the most suitable widget. +You can draw or redraw an image in this widget freely. +It is called custom drawing. + +GtkDrawingArea provides a cairo context so users can draw images by cairo functions. +In this section, I will explain: + +1. Cairo, but briefly. +2. GtkDrawingArea with very simple example. + +## Cairo + +Cairo is a two dimensional graphics library. +First, you need to know surface, source, mask, destination, cairo context and transformation. + +- surface represents an image. +It is like a canvas. +We can draw shapes and images with different colors on surfaces. +- source pattern, or simply source, is a kind of paint, which will be transfered to destination surface by cairo functions. +- mask is image mask used in the transference. +- destination is a target surface. +- cairo context manages the transference from source to destination through mask with its functions. +For example, `cairo_stroke` is a function to draw a path to the destination by the transference. +- transformation is applied before the transfer completes. +The transformation is called affine, which is a mathematicsterminology, and represented by matrix multiplication and vector addition. +Scaling, rotation, reflection, shearing and translation are examples of affine transformation. +In this section, we don't use it. +That means we only use identity transformation. +Therefore, the coordinate in source and mask is the same as the coordinate in destination. + +![Stroke a rectangle](../image/cairo.png) + +The instruction is as follows: + +1. Create a surface. +This will be a destnation. +2. Create a cairo context with the surface and set it to the destination. +3. Create a source pattern within the context. +4. Create paths, which are lines, rectangles, arcs, texts or more complicated shapes, to generate a mask. +5. Use drawing operator such as `cairo_stroke` to transfer the paint in the source to the destination. +6. Save the destination surface to a file if necessary. + +Here's a simple example code that draws a small square and save it as a png file. + + 1 #include + 2 + 3 int + 4 main (int argc, char **argv) + 5 { + 6 cairo_surface_t *surface; + 7 cairo_t *cr; + 8 int width = 100; + 9 int height = 100; + 10 + 11 /* Generate surface and cairo */ + 12 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); + 13 cr = cairo_create (surface); + 14 + 15 /* Drawing starts here. */ + 16 /* Paint the background white */ + 17 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); + 18 cairo_paint (cr); + 19 /* Draw a black rectangle */ + 20 cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); + 21 cairo_set_line_width (cr, 2.0); + 22 cairo_rectangle (cr, width/2.0 - 20.0, height/2.0 - 20.0, 40.0, 40.0); + 23 cairo_stroke (cr); + 24 + 25 /* Write the surface to a png file and clean up cairo and surface. */ + 26 cairo_surface_write_to_png (surface, "rectangle.png"); + 27 cairo_destroy (cr); + 28 cairo_surface_destroy (surface); + 29 + 30 return 0; + 31 } + +- 1: Include the header file of cairo. +- 12: `cairo_image_surface_create` creates an image surface. +`CAIRO_FORMAT_RGB24` is a constant which means that each pixel has red, green and blue data. +Each data has 8 bit quantity. +Modern displays have this type of color depth. +Width and hieight are pixels and given as integers. +- 13: Create cairo context. +The surface given as an argument will be set to the destination of the context. +- 17: `cairo_set_source_rgb` creates a source pattern, which is a solid white paint. +The second to fourth argument is red, green and blue color depth respectively. +Their type is float and the values are between zero and one. +(0,0,0) is black and (1,1,1) is white. +- 18: `cairo_paint` copies everywhere in the source to destination. +The destination is filled with white pixels by this command. +- 20: Set the source color to black. +- 21: `cairo_set_line_width` set the width of lines. +In this case, the line width is set to two pixels. +(It is because the transformation is identity. +If we set it different one, for example scaling with the factor three, the actual width in destnation is six (2x3=6) pixels.) +- 22: Draw a rectangle (square). +The top-left coordinate is (width/2.0-20.0, height/2.0-20.0) and the width and height have the same length 40.0. +- 23: `cairo_stroke` transfer the source to destnation through the rectangle in mask. +- 26: Output the image to a png file `rectangle.png`. +- 27: Destroy the context. At the same time the source is destroyed. +- 28: Destroy the destnation surface. + +To compile this, type the following. + + $ gcc `pkg-config --cflags cairo` cairo.c `pkg-config --libs cairo` + +![rectangle.png](../src/misc/rectangle.png) + +There are lots of documentations in [Cairo's website](https://www.cairographics.org/). +If you aren't familiar with cairo, it is strongly recommended to read the [tutorial](https://www.cairographics.org/tutorial/) in the website. + +## GtkDrawingArea + +The following is a very simple example. + + 1 #include + 2 + 3 static void + 4 draw_function (GtkDrawingArea *area, cairo_t *cr, int width, int height, gpointer user_data) { + 5 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* whilte */ + 6 cairo_paint (cr); + 7 cairo_set_line_width (cr, 2.0); + 8 cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ + 9 cairo_rectangle (cr, width/2.0 - 20.0, height/2.0 - 20.0, 40.0, 40.0); + 10 cairo_stroke (cr); + 11 } + 12 + 13 static void + 14 on_activate (GApplication *app, gpointer user_data) { + 15 GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app)); + 16 GtkWidget *area = gtk_drawing_area_new (); + 17 + 18 gtk_window_set_title (GTK_WINDOW (win), "da1"); + 19 /* Set initial size of width and height */ + 20 gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (area), 100); + 21 gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (area), 100); + 22 gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (area), draw_function, NULL, NULL); + 23 gtk_window_set_child (GTK_WINDOW (win), area); + 24 + 25 gtk_widget_show (win); + 26 } + 27 + 28 int + 29 main (int argc, char **argv) { + 30 GtkApplication *app; + 31 int stat; + 32 + 33 app = gtk_application_new ("com.github.ToshioCP.da1", G_APPLICATION_FLAGS_NONE); + 34 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + 35 stat =g_application_run (G_APPLICATION (app), argc, argv); + 36 g_object_unref (app); + 37 return stat; + 38 } + 39 + +The function `main` is almost same as before. +The two functions `on_activate` and `draw_function` is important in this example. + +- 16: Generate a GtkDrawingArea object. +- 20,21: Set the width and height of the contents of the GtkDrawingArea widget. +These width and height is the size of the destination surface of the cairo context provided by the widget. +- 22: Set a drawng function to the widget. +GtkDrawingArea widget uses the function to draw the contents of itself whenever its necessary. +For example, when a user drag a mouse pointer and resize a top level window, GtkDrawingArea also changes the size. +Then, the whole window needs to be redrawn. + +The drawing function has five parameters. + + void drawing_function (GtkDrawingArea *drawing_area, cairo_t *cr, int width, int height, + gpointer user_data); + +The first parameter is the GtkDrawingArea widget which calls the drawing function. +However, you can't change any properties, for example `content-width` or `content-height`, in this function. +The second parameter is a cairo context given by the widget. +The destnation surface of the context is connected to the contents of the widget. +What you draw to this surface will appear in the widget on the screen. +The third and fourth paranmeters are the size of the destination surface. + +- 3-11: The drawing function. +- 4-5: Set the source to be white and paint the destination white. +- 7: Set the line width to be 2. +- 8: Set the source to be black. +- 9: Add a rectangle to the mask. +- 10: Draw the rectangle with black color to the destination. + +Compile and run it, then a window with a black rectangle (square) appears. +Try resizing the window. +The square always appears at the center of the window because the drawing function is invoked every moment the window is resized. + +![Square in the window](../image/da1.png) + + +Up: [Readme.md](../Readme.md), Prev: [Section 18](sec18.md) diff --git a/image/cairo.png b/image/cairo.png new file mode 100644 index 0000000000000000000000000000000000000000..bb0a3bc7855e287f0e63ec0fb7261c0a79c24545 GIT binary patch literal 16076 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 literal 0 HcmV?d00001 diff --git a/image/cairo.xcf b/image/cairo.xcf new file mode 100644 index 0000000000000000000000000000000000000000..d82a8c8802b7a7d4c9057c1ca3f44f14cd7a4f34 GIT binary patch literal 32167 zcmeHQ31C#!)xNX5Nix|XKu9vl5ZNJ+u!SWo5(L4bw1NVH8X$qNB$|XR$UmXBilP-2 z7hDQtg0@(Sbwfdg3W_2MRTRMjvdO*(StgU2cmD6bci+sLh)^I3Q|`0R7@K3CmYSBv7&8uM%rGAWf1ZVlhBFxOst*^Oi6HLq#K4*1?t^P6XwKIN zN=!ih7~!H0%zymABaiQ!vuxj-=j=D|MAQh55pbND3*N;svjY-%5fpd==*^1}&eH;q zpEd^2AD?2G&o5Sa{IoGsPk$1{GXHE>dHl37Q%`T6uS?5EBP|~tuFn)#rW6IwMFTi3 zM<@zd`(#&^nYINaa-^phmLPmB4>x4`X=5ObT;Hnk_-OFx=s&;CGJn%Y)#Im)nR@ye z@Q*1`dHl37Q%}#^!ZL69LFMt&#!Nl^WFNmhej54mh3oUk%i;`N_;|Fkl(G3!rex<8 zDGA_JFS8&!t0;S%eR^)u1p9!2gNN{#D1|k5O4j)7l<@_*<23HSwJa=}IXT;2m_Ipp zTq|qKobhAxC+8Q~TPl!JFn&yyJyrRa)(X*M&JvwwSN`$n8HM*{jm^y)Z%<2wZ)Si` zcv7b3N2_EYGq+jym|j*rQSYc2zeC05|5UNhcPdVM zOT~cq0Qh(@@}?D1RFIWdn3G+=Ie6FNj|Gl*LxO9<>E0!HqpQO4a79qi0G6zy6Lhpy zN85FDsE!WP(cwBe5;W2?jECcGK1jrI{mldoU`;tqcz`$PXl*E&fG}j%Fczpbgre*j zMJbcBW~zBcUJL_TPRS~mH1$4va)wIu%0P|f*$Z=vvwMz8?$j-<^Qh!rT1jQJ=aIcK z+6&%fRAo+nUXeZdb`)hwVRk`ojuw`}RoJ_95G;yUt=Ri=XJk+2tspC}C^u_zZdRdv zrqU`VXXTBbil%B$o|u&~@jk9;Ojcob%DCKu?6F0;`FZxqMFj|~-B#_X?NZaabxBR{ z+NopLj%jIK(>izPg21%2j_Dmbcj}hfwM*AjxeDNWdC{DfRsk2bHEjuO^C7Cy{t zkJjdR^TA{3tYXwM6_vNf!{djk;gO3~WX!>SVq`W-WbVd{l9ySeP$rwDHq0PJGFdXW z!OP;O!Wmi2lFQ7@k|o$88G$C|fd?vNbC8LdB!iit#lYNVNwP?0GuL8L(x@<_wMh~e zhGZ3_G}<85m|2k7V&tirn9Cwb%z~Fm6-EM*3A7nv2B{kTi0d}8YOVkpgSeQHc{v*x zgcSFNa9t|DiPdnm$R&kHs(=CFUg+S-!bUED05fRGtqAcz2pN$rf?Y}~!65wt;4mV~ zRY4*dApu@qBuaj`%~oFuVBi*NW(j_Yxq^5;7|(~wj`S2$R7n>~i)S1BZY3K^PEl%# z1Q6+>F<5KxWHv2n{A)4`4KdsSCEAP$Mv!PEi6)zz$RwK=!;#rW31;X)StZ&M6XN5U-DvZ~K^AQXN^G_U3AO~} z*H)8gkLRIC0)=aHC&t-rDv7qqWxv@rc(N+O-Y&O4u33*m> z!ELbm?11tFZZXf9PdOS)Tq4hnFuzfVj-TfM+-hEVN(PiN@?Q<}RS9TBdE*_&^%@dt zY`j>wlsBPiya@ul1i0vF#;r_10XOBMs3cStuLj7QY&8j74t*SE*jx=n@v2FZ9aV_( zL>w9wa<4TRL#e?@Wnqj6ZN%v*TUuI%mQ&{BJ`6R^G9Q7q^VA|cg3)xGr&y`8tkmgT z#FjbBoX)bP=6FWvE$%yE?L4Bm6a`B2;maON{!BAWy?yP zrE5St%N8whIx$>2ooF9xoX*mPuRu5IjK4hKDn&BOoJh>ztX{$;oCq;G(Rv^uuUW<; zxFZC67QsA(a#`5s3}TgQmH-tol&;fTh5-nyk|N}FmX;`t5cSD$!%NLhH#m{HB2UpOP~fOEnUJjaEj|vssetVG%u;LrK9BDHNJlP%wrjdJFT~5Hp=DVi`25$$PF? zR&V}p*UkmeXcGwO^TC-TuP1{xjNe*yWJM3Q*i2QEnYrL=*TGdcqr%ExH?eOs=$`kx zHD|HAclWaPJ@k>0LD^gX?jP3s=r%KBld3XIV`we;vn#}K%kG8g4N!e&=T-uXC z9}Yq()^nsHb~3f&($%fdXMayU8C$a*RcST25muOGuIzR zSes|i5)-Q$LHD3|>BU40Sc=p)$Bp3p1NHU`&BuJ#^Dp~MkHF9fdB_sV;w_G)$;X<}Z88JXKOP*Y#p2!W3JqcM2^14@1QGe0eQ0^hX_T<8TCuKUeWZ{>8A50pJp%rw zpJNEGT7NWtWG^)*r;BK6MDs<&wMe($Xj1JzaqV|3>&%WdwPR4{)1#R3)Y(fNi}6l?ure;6{jI2Y zY7sgUx;F&`yTw;zTcPadl3J;!oO6JzkOv0I;OiC9y3UwNHb=l@D~ewRNxB&MLIF7 zgny&J9RiOCbgS6FDlkr9Yk}Pb4iY$0;6#DN0v{Flg1}`0R|(uGaEHJn0^KS$vrKdm%cl)9HRlW9t5$T*4foH)G4+0|z%< znN{kf)I_wD!eXRkmLw&y8>D#FT#99_r5KhXMYA+1oOP1wvxZVjR!?fH)K;j}kp)TV zsIfFvpAGtK&}V}_)LXO-`fSi=gFYMd*`Ut`eKzQ`L7xr!Y|v+eKGbcf4f<@*2U*2F zC-ga?&k22~3a-!SNEFr7te@V|(2~*qaPsV0 zI4q(qqg^57sa%=Y94+-b3rt-&EW9J5uZ-lWSUtT}I;;6&=fc53$ldwIgDX6K1T&Hx zk(D@jCYwN~z-W#aY%f+&j;qP>9;9XaoGED}%^$Um2vOrFZLsI|H?V zuG$*|ez|oyj{Xz*t&a9+Ek^7nFn%dd^S=swTVn)jydV?rRl}2c)56nCRuMfatdHLr zci}WPgLzY4`?fo)33*MX?=UmQ8tMGlka-PF+bqT3PO#)N3O#VHec z*W6*nNtG^F^7jUCOh(!#a9GmiM>D2^6?cWA#B@wF5B`UFCUDwQ@7ZdJyr<{I_%owa z$r$jw44yYF%o{grn?&-_!9js)h6|S0LzuVqLqDQ4y(9c3r)c3UbD?EjC@xN>{KTs- zA+R2Zv*dy0U^p%Y_Jf#v7KZjFieU5`#BQh^i|RaJfIHPnrs2Q`cyW5$ zf7JsyY>K$G;E4p5`+3Sk5Aizd`x8}7vmgu4Ao~B%FbowSx}zaBf(&n{!^4>SW)CsL zJ0^1Nn$x9$DZ1}#$kmC)kowR_)mu9Rr#yEoTD0ro;mkb&icNn)dv)D{^1CCLXr2}e zqkoHP>a;3^@ z9aM|I2az{+feYRF*i0*`Sz)m-ITA}0mF4zwl*eHd&etuFeI*{n9`sKh-xVtEl~JY# zXSB9P_j=JtF89K|F_yU7|G_(MM^vXGfb&-4a!sI{3)CCYI8P_}yOu~R^C$v-OhC~K zW_lI@r@KM9c_*m1ajE5{ooN1Y>(eN@cQsDb`u}mx?nq}Gh{N?DQqu<67>1762lcHe zL{H6D*kJ!Q$QObAB@_p5E&ouNsxaB#hVFi*2Y8ae>}?39PGGtRo-=$fgeuoKmQlr- zkiu99ZvnFrJaI@ZLuIKR*X9H`GSF}z3Fl3o8$4W%ljrP%vhr4lds&G?<|t2%BafNn zZ+H#-U5P>sQ6Y~)@OG3nEkTqM_;4(vGr-Y2(nOxEvGFJ19Sc+b1bnp-qj;FpPgPs9 zIfk)eNVPHr`I!QSonUMOn@1zCI!q)!4kcNNfbHQZS`1#)7Tk}6i>Lg7R*vWg5xaRB zh};8Qf(ofjgk1w6F+}4+U1xX^n+sJKG-OZDAk^OGP%tMSL-?m!?IG=l5bwf>E(h%e zb-0Cvw~5b_5YP<+hJ2!hpI4SPA!KJHkE;fCa)`u?R8{p<@A^{gt$#rylwEycm{Q|l zYFUZ2mZLq4_L!*pqj62GK}~-`E8g7!1)wlN_e2<;51yNjqXRTqT!Z)Nhog`qg#p_5 z2=7Km@y0(}ZNZ#Sku>G??I+xax0c==jp7k(a-$>Q`=MSiZuoLu+jh)TzEfRW9>E$@ zIQABk$3+D(51lA7ant3M5g0{0AU+F5$)+EKy-QJeZ7~GXAVl#gViN+)=pK}YfR};O zfs>5n#SyoKyq_!YANZS&wqw)~`iGWJF_>9R*K#5pA6JeBdT{JM7Oh>D@5Q}1n&42} zOp({KED5vAn}znid_8d!oN^8fOokH+7sGDQJK@x2ZvNDQu~*wNmkoq@bKx#_ncD@j zx~IijzsHw-v1V&guEzDjWeI=!tW|*Z*`y+W`(!}35^`+5x7Cc z)HoG8cvS2(THq9cvjsjb@MVF^1%4p#3xPWY9vA3Uv2(aUo4^!-Jp~RHI9kQ@!zy;2 zC{UbScE{AopB{DvSVp0Wy~WQ~utwGIY>oMh8bmYK4X+$>A6YrvfcqFr?)p=%?-w+| zg&LNd_#K0HEe*kC(S8bR;5_jVZlA2vHk~Q|_R+?eb{ZX$hzhW_YOoQ@orj)a2^RsTf3ev#p7$!MYKPurdY6aloY zR-Vp_D6uuP4L@u0j;FUUUD;vPH-y_o^d#)Pz+7*eXC!tT`>6|B{EIXj?>@A}!p_w1 z*l+MAYR{DJ6U5wGsOKl1kzq;$1=I611Mdvlig*3FyD$`_Vppp69W&?NM&7B1O4%A{73#s2l`u+CLY034LwckI=IkQYT<@6^36)E)k;Qg zxX(=0N1mrKOzSbCn#aD|n=v{SfpISb?GD~Vm84VQ%v;D~`MW;zKBmxk>*-)tsr7u;RwDQNjBTQR z7%4GWw0reX_3n9Avu~I{k$}g=c`)^eDV6I*!itn zSb+hT+{*(5s}(c(u;Ssv3YrFZJeB-k#GR-5MaMmZWZc!CFq^Qbv`awalS8 z_9A|LGdY33X5!UPx9&5u)BZM!U-+QWYO6c+L$x6ue}_i|F5ison7+O7Xmye1;fpkk z6KcDvK)X_8bxSd(w4VyJA0@`W=0XIjp@J6)*XLhc)r!z9q|}&lO(by5q^LWl#Raa4 z)OvHPk@|&CKm-a(Ti&3psOvO{IHX2_LrCql#O3g7m8s$7NaI{OwRC;h2MtU()Afyo zSo2=rSX}9i1^d|F4taYtUFnSla|IfpbqWoQ*Ebf|Hx^fVW5M|JuOFdnZ!DM`$Y8v_ zvAEQY1^+?4zRZo+Hx}177XMQl3qGot9`rkW5qo`OQHL7~<+%SO&hYcpb9^=(m@eoZ zz<8DR{kq)%f4Ke&0UmFGGsE%AfhL^pU4r+2<+EueUH-b*%OQOJqknGP>G$~xf#(%Z zU-8qhX@5}t)8-3&N#I{p83B28=h7bLxio=BdJ4Cv799P5dtWgm^(NLb@yaC`DK3?Ff z0=KC+LR=D!6y-3IU(DednI-T^flE}xDZldE^|6YhMEaw9tNwd?3j9*VEb%kEEOGgi zwM&GbP;rb~#cWx{T!E9Us(v%sPWs=w%Uf%{dQ z+E!qZz{dn`6{zu*tNv-Cy-bS{{-y#u3G63usK9Xoi&SKRd;gHxxK7TvLe61b$1?C~ zTirTE>r7~^Q>SR%1+8`J93fcMTGry|d@XCdy;+?*Mej`Ltz)O?-37gM?09)35&t>$ zm2m+V$|19u86N;#85fu`T7h8>;S%tITo_Bi{VmadjuJItl8`wYUE3-f_&+6(vZ9}cJd2N)CLjvm05YaZ{@Tuz0U0s(2*Vi=g6Dh2M^tN275&CLP zr>^IWYfxXE&Te%*TV4Tubvh5j-fK!9#saz=>xFAdXC1F;>UxcI+4a@&+N-YDa+h1* zm0BZSt?B6316OL*dbOsbFAKgNKHJ*%S_;3gb^V3z8~!`|`Z{WK8FmntV-rR@YA5jY6{S2SF>VUQRpkYc0;Jt^gg8uZS}v zg;G`;oI3Yh=!mcf>{8D+Tk!Psqk?w&q3pgx7U6U8@Q&0&>PLNBGI}zGs9K;0I3IqQ zV*?^X3r0@>O~60lw}$(IHhDi@?FD5KA@}1;ohtZ);C~!g06%`UOje!$4E$m6KL#vB z{7=9Lo&O~KQSi?L79k!#KBaoXKNbEX@Hc?}Q6Tpp0yYxu>BC$&r5!BF%3tfN*>>eiU$6YgpZ%!Rk{;^!K^l=yP`T!H0n}&@;cp86L%^Ac-wtf9^M4C} zEBOBiEJplRU>n>c--JJRN`HW776QKlwrj-Psi(hN@Y^T^Jcxh?fSZA-v8?Lm8hlu{ zX>Pw@$shM6;`rx`jfY{cKOR4^u3R-8-(axcBYZYwKL^6^PQG_BzCg#9<&WTRmK^`v zgqKA8XZRKFh;gNRCB(_bzeeE`XGm>`pn6OWULUD?*GEu&CfDB{p?cSa6S-rU-0Ua_ z2iVsFCp2Jkk1BkpRDysHfzKg-!@Qwt!26*jueabs(&-j*uX|=Y(VP(GUPU#ZJboNs zt^Ck1j^Vo{a?8V+?cQ5LSj~w3q3jvNRHVk^&z-!%zihcNlF_{&+) z;oV*MD&xT zxB_2wMet9*z6fc}eNrD-D z96^q=TmbN?=Ter&fy-Zq)pgc`em;d={9!*9m5~Ek%JyjCFtKv~O!yTi{JY>+9Q=Hc z=98f*1Q#m^S6twP%z1u(0l=rkODT^_TjE`{g*mPV=I`s><^Bt@FugB}l;#@y|xz;ZM z{uBGJ<%ov)zEd73$x)MKftTezu04+|`D98~wBc zf7K86`*xbJdnW9M|7t_Mjec6#@7o!}?p?4S{;Lhuox8S!*HGB++rh(b@z2n!0m*;fE5vE**Z9mtk0>2hH-_BX^oO74SdGIMOj{i%}bNug! zXnvj_YbzY*+zoJ!i(A_|!WIX#yo+5)@_g!Buy(QcOQ@W>)si{iir^Qo#KKAg(mwxO z`U_WOwd}zKsd_qCEBt)D^B1qs!j}I03eAi(t|n(dJ?b3(YDQapHu90`CzxNubbQEc6!({l!9mvH04mSlC*;M#z0GP<(|| zyifRr-NiMke^!vd`T~;#wh@>vFjL@d0`C$yUSOd>hroFPpA+a5xI*A+fg1#VEpWHM zqXMf`#Q&v8c^-%q7%#Aez>WfY3%o_(odU-S%ojLI;KKr+7Pv^@YXVmaTqkg|!0!bf z6nI7;sW>}SU?YJy2y8E~hrj^>Zx?uvz)31%7{Q_86?6D|tq#pyPxtbbyH>^=e{JQA Tzy61*@ya-U2`Jo!PI>6MfUffaMt9 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 literal 0 HcmV?d00001 diff --git a/src/misc/cairo.c b/src/misc/cairo.c new file mode 100644 index 0000000..bd64810 --- /dev/null +++ b/src/misc/cairo.c @@ -0,0 +1,31 @@ +#include + +int +main (int argc, char **argv) +{ + cairo_surface_t *surface; + cairo_t *cr; + int width = 100; + int height = 100; + + /* Generate surface and cairo */ + surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); + cr = cairo_create (surface); + + /* Drawing starts here. */ + /* Paint the background white */ + cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); + cairo_paint (cr); + /* Draw a black rectangle */ + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); + cairo_set_line_width (cr, 2.0); + cairo_rectangle (cr, width/2.0 - 20.0, height/2.0 - 20.0, 40.0, 40.0); + cairo_stroke (cr); + + /* Write the surface to a png file and clean up cairo and surface. */ + cairo_surface_write_to_png (surface, "rectangle.png"); + cairo_destroy (cr); + cairo_surface_destroy (surface); + + return 0; +} diff --git a/src/misc/da1.c b/src/misc/da1.c new file mode 100644 index 0000000..5808e80 --- /dev/null +++ b/src/misc/da1.c @@ -0,0 +1,39 @@ +#include + +static void +draw_function (GtkDrawingArea *area, cairo_t *cr, int width, int height, gpointer user_data) { + cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* whilte */ + cairo_paint (cr); + cairo_set_line_width (cr, 2.0); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ + cairo_rectangle (cr, width/2.0 - 20.0, height/2.0 - 20.0, 40.0, 40.0); + cairo_stroke (cr); +} + +static void +on_activate (GApplication *app, gpointer user_data) { + GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app)); + GtkWidget *area = gtk_drawing_area_new (); + + gtk_window_set_title (GTK_WINDOW (win), "da1"); + /* Set initial size of width and height */ + gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (area), 100); + gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (area), 100); + gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (area), draw_function, NULL, NULL); + gtk_window_set_child (GTK_WINDOW (win), area); + + gtk_widget_show (win); +} + +int +main (int argc, char **argv) { + GtkApplication *app; + int stat; + + app = gtk_application_new ("com.github.ToshioCP.da1", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + stat =g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return stat; +} + diff --git a/src/misc/rectangle.png b/src/misc/rectangle.png new file mode 100644 index 0000000000000000000000000000000000000000..21f3a313cdaa6b77604006c86d0f340b967c218b GIT binary patch literal 341 zcmeAS@N?(olHy`uVBq!ia0vp^DIm