Upload
trinhliem
View
216
Download
1
Embed Size (px)
Citation preview
Sisältö
• GDI ja Device Context• Piirtofunktioiden käyttö• Koordinaatisto• Tekstin piirtäminen, fontit• Rajaus (clipping)• Skaalautuminen (scaling)• Ikkunan päivittämisen problematiikka
Graphical Device Interface (GDI)• Laiteriippumaton rajapinta grafiikan piirtämiseen• Sisältää joukon piirto-objekteja, joilla sovellus voi esittää
tietoa graafisessa muodossa– Piirto-objektit ovat pohjimmiltaan tavallisia tietorakenteita (Struct)
• Piirtokoodi toteutettu kahden dll-kirjaston välisenävuorovaikutuksena– GDI.dll
• laiteriippumattomat piirtofunktiot– VGA.dll
• piirtofunktioiden toteutuskoodi käytössä olevalle laitteelle (tässätapauksessa vga-näyttö)
Graphical Device Interface (GDI)
GDI-Objekteja
• Sivellin (Brush)– GDI-objekti, jolla voi maalata laajoja alueita
• Kynä (Pen)– GDI-objekti viivojen piirtämiseen
• Fontti (Font)– GDI-objekti piirrettävän tekstin tyylin ja ulkoasun
määrittämiseen• Bittikartta (Bitmap)• Väri (Color)
Device context (piirtopinta)
• GDI:n ylläpitämä windowsin sisäinen tietorakenne, joka sisältää piirtopintaan liittyviä atribuutteja, kuten väri ja fontti tekstin piirrossa
• Piirtopintoja– Näyttö (Display)– Tulostin (Printer)– Muisti (Memory, Bitmap)
Device context (piirtopinta)
• Matalan tason toteutus
Pyydetään käyttöjärjestelmältäpiirtopinnan kahva
Suoritetaan piirtotoiminnot GDI-funktioilla
Vapautetaan piirtopinta, jonka
jälkeen kahva ei ole enää käyttökelpoinen
Asetetaan piirtopintaan
tarvittavat asetukset (esim kynä)
Esimerkki (winapi)HDC hdc; PAINTSTRUCT ps; // Pyydetään kahva piirtopintaanhdc = BeginPaint(hWnd, &ps); // Asetetaan objekti piirtopintaanHBRUSH old = SelectObject(hdc,
GetStockObject(GRAY_BRUSH));// Piirretään suorakulmio GDI-rajapinnan funktiollaRectangle(hdc,0,0,100,100);// Asetetaan vanha sivellin takaisinSelectObject(hdc,old);// Vapautetaan piirtopintaEndPaint(hWnd,&ps);
Device context (piirtopinta)
• .NET toteutus• GDI+
Luodaan Graphics-olio
Kutsutaan piirtofunktiota ja annetaan tarvittavat muuttujat parametrina
Esimerkki .NET
// Luodaan sivellinBrush br = Brushes.Blue;// Piirretään suorakulmio ruudullee.Graphics.FillRectangle(br,0,0,100,100);// Vapautetaan siveltimen varaamat resurssitbr.Dispose();
WM_PAINT
• Sovellus saa WM_PAINT sanoman kun järjestelmä lähettää ikkunan päivityspyynnön
• Omassa sovelluksessa ei kutsuta piirtofunktiota suoraan, vaan aiheutetaan WM_PAINT sanoma, jos ikkuna pitääpäivittää– InvalidateWindow + UpdateWindow
Esimerkkipublic Form1(){
this.MouseMove += new MouseEventHandler(Form1_MouseMove);this.Paint += new PaintEventHandler(Form1Paint);
}
void Form1_MouseDown(object sender, MouseEventArgs e){
x = e.X;y = e.Y;this.Invalidate();this.Update();
}
void Form1Paint(object sender, PaintEventArgs e){
e.Graphics.DrawRectangle(Pens.Blue, x, y, 100, 100);}
System.Drawing.Graphics (.NET)
• GDI rajapinnan piirtometodit kapseloiva luokka• Saadaan paint-eventin parametrina
void PaintEventHandler(PaintEventArgs e){
Graphics g = e.Graphics;}
• Voidaan myös pyytää Control-luokaltaGraphics g = Control.CreateGraphics();
System.Drawing.Graphics• Yksinkertaiset muodot
– DrawLine– Fill / DrawRectangle– Fill / DrawEllipse– Fill / DrawPath
• Monimutkaisemmat kuviot– Draw / FillPie– DrawPath( GraphicsPath path)
• Tekstin piirto– DrawText– DrawImage
Kynät ja siveltimet
• System.Drawing.Pen– Pen(Bursh b)– Pen(Color c)– Pens.Blue
• System.Drawing.Bursh– SolidBrush(Color c)– Brushes.Blue
• System.Drawing.Color– Color.FromArgb(int alpha, int red, int green, int blue)– Color.Blue
Paint - piirtotapahtumapublic class Form1{
public Form1{
this.Paint += newPaintEventHandler(Form1_Paint);}
void Form1_Paint(object sender, PaintEventArgs e){
Brush b = new SolidBrush(Color.Blue);e.Graphics.DrawLine(Pens.Red, 10, 10, 100, 100);e.Graphics.FillRectangle(b, 120, 20, 50, 50);b.Dispose();
}}
Tuplapuskurointi
• Vähentää ikkunan välkkymistä• Lisää muistinkulutusta• Ei oletuksena päällä formissa
– Form1.DoubleBuffered = false;
Fontti
• System.Drawing.Font
FontFamily fontFamily = newFontFamily("Arial");
Font font = new Font( fontFamily, 16, FontStyle.Regular, GraphicsUnit.Pixel);
FontDialog
• Valmis dialogi, jolla käyttäjä voi valita käytettävän fontin
• Näyttää kaikki järjestelmään asennetut fontit
• System.Windows.Forms.FontDialog
FontDialogprivate void button1_Click(object sender,
System.EventArgs e) {
fdlg.ShowColor = true; fdlg.Font = textBox1.Font; fdlg.Color = textBox1.ForeColor;
if(fdlg.ShowDialog() != DialogResult.Cancel )
{ textBox1.Font = fdlg.Font ; textBox1.ForeColor = fdlg.Color;
} }
Järjestelmäfontti (system font)
• Oletusfontti, jota käytetään mikäli fonttia ei erikseen valita – Esim ikkunoiden otsikoissa
• Fontin koko riippuu esimerkiksi näytön resoluutiosta
• Ei yleensä muutu suorituksen aikana, joten riittää että fontin koon selvittää sovelluksen käynnistysvaiheessa.
Tekstin piirtäminenvoid Form1_Paint(object sender,
PaintEventArgs e){
Brush b = new SolidBrush(Color.Blue);
FontFamily fontFamily = newFontFamily("Arial");
Font font = new Font(fontFamily, 16, FontStyle.Regular, GraphicsUnit.Pixel);
Point p = new Point(10,10);e.Grapihcs.DrawString("Hello world", font, b, p);
}
Wrapped Textstring text1 = "Draw text in a rectangle by passing a RectF to the DrawString
method.";Font font1 = new Font("Arial", 12, FontStyle.Bold, GraphicsUnit.Point); RectangleF rectF1 = new RectangleF(30, 10, 100, 122);e.Graphics.DrawString(text1, font1, Brushes.Blue, rectF1);e.Graphics.DrawRectangle(Pens.Black, Rectangle.Round(rectF1));
Värit (Color)
• Esittää ARGB värejä– A Läpinäkyvyys (0-255)– R Punainen (0-255)– G Vihreä (0-255)– B Sininen (0-255)
• System.Drawing.Color.FromArgb(a,r,g,b)• Sisältää useita valmiiksi määriteltyjä värejä
– Esim Color.DarkBlue
ColorDialog
ColorDialog dlg = newColorDialog();
dlg.Color = Color.Red;
if(dlg.ShowDialog() == DialogResult.OK)
{//…
}
System.Drawing2DGraphics g = e.Graphics;
LinearGradientBrush b = newLinearGradientBrush(new Point(0, 0), new Point(100, 100), Color.Red, Color.Blue);
g.FillRectangle(b, 10, 10, 100, 100);
Koordinaatisto
• Fyysiset koordinaatit– fyysinen yksikkö yksi kuvapiste,
pikseli– pikseli = pienin laitteen erottama
kuvan mitta
• Loogiset koordinaatit– loogiset yksiköt esitetty
mittayksikköinä
Graphics.PageUnit
• Kertoo mitä yksikköä piirrossa käytetään• GraphicsUnit
– Display– Document (1/300 inch)– Inch– Millimeter– Pixel– Point (1/72 inch)
Graphics.TranslateTransform
• Muuttaa origon paikkaa koordinaatistossa
Graphics g = e.Graphics;Rectangle r = new Rectangle(10, 10, 50, 50);g.FillRectangle(Brushes.Red, r);g.TranslateTransform(50, 50);g.FillRectangle(Brushes.Blue, r);
Graphics.PageScale• Asettaa skaalauskertoimen
– world unit → page unit
Graphics g = e.Graphics;Rectangle r = new Rectangle(10, 10, 50, 50);g.FillRectangle(Brushes.Red, r);g.PageScale = 2;g.FillRectangle(Brushes.Blue, r);
Clipping
• Keino rajata alue, jolle piirto halutaan tapahtuvan
• Alueen ulkopuolelle jäävä osa jätetään piirtämättä
Graphics g = e.Graphics;Rectangle r = new Rectangle(10, 10,100, 100);g.SetClip(new Rectangle(10, 10, 50, 50));g.FillEllipse(Brushes.Red, r);
Ikkunan päivittämisen problematiikka
• Milloin päivitetään?• Mitä päivitetään?• Miten päivitetään?
Milloin päivitetään?
• Kun ohjelma itse haluaa päivitystä– Ei kutsuta itse ikkunan päivitysfunktiota, vaan
aiheutetaan WM_PAINT sanoma– Invalidate + Update– Refresh
• Kun käyttöjärjestelmä lähettää päivityspyynnön– ikkunan koko muuttuu– ikkuna peittyy toisen ikkunan alle– ikkunaa vieritetään
Mitä päivitetään?
• Ikkunan päivittäminen on raskasta– Kannattaa päivittää vain se alue, joka todella
vaatii päivittämistä (Clipping)– Hitaus korostuu erityisesti usein päivitettäessä
• Esim. Pitääkö ikkuna päivittää aina kun hiirtäliikutetaan ikkunan päällä?
• Invalidate– Asettaa ikkunan alueen epäkelvoksi
Miten päivitetään?• Pidä varsinainen piirtometodi mahdollisimman tehokkaana
– Älä suorita piirtometodissa turhaa laskentaa tms.• Tuplapuskurointi (Double buffering)
– Hyödyllinen monimutkaisten piirto-operaatioiden yhteydessä– Ikkunan sisältö piirretään ensin muistiin ja vasta tämän jälkeen
kerralla näytölle• Ikkunan taustan pyyhkiminen
– WM_ERASEBKGND• GDI-objektin vaihtaminen (kynä, sivellin, fontti jne)
– Ota talteen piirtopinnalla oleva vanha objekti– Aseta vanha objekti takaisin piirron jälkeen
Ikkunan koon muuttaminen
• Ikkuna lukitaan koon muutoksen yhteydessä• Jos ikkunaa halutaan päivittää kesken koon
muutoksen, täytyy lukitus purkaa– LockWindowUpdate
• WM_SIZING– Lähetetään useita kertoja ikkunan kokoa muutettaessa
• WM_SIZE– Lähetetään aina kun ikkunan koko on muuttunut
Lähteitä• Using fonts and text
– http://msdn2.microsoft.com/en-us/library/a3a2bads.aspx• System.Drawing namespace
– http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDrawing.asp
• GDI– http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/winprog/winprog/graphics_device_interface.asp• Device Context
– http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_0g6r.asp
Lähteitä
• Getting started with Graphics programming– http://msdn2.microsoft.com/en-
us/library/da0f23z7.aspx
• Charles Petzold – Programming windows– Petzold, C. Programming Windows, 5th edition,
Microsoft Press 1999.
• Using managed graphics classes– http://msdn2.microsoft.com/en-
us/library/yhez825d.aspx