Browse Source

Performance des Text zeichnens verbessert und zeichnen von eingefärbtem Text hinzugefügt. Außerdem wurden kleinere Bugs im TextReader und im Linien Diagramm behoben

kolja 6 years ago
parent
commit
352b5b0c7d
7 changed files with 229 additions and 16 deletions
  1. 15 0
      Bild.cpp
  2. 3 0
      Bild.h
  3. 7 7
      Diagramm.cpp
  4. 1 1
      Random.cpp
  5. 168 7
      Schrift.cpp
  6. 33 0
      Schrift.h
  7. 2 1
      Text.cpp

+ 15 - 0
Bild.cpp

@@ -255,6 +255,21 @@ void Bild::drawLinieHTexturAlpha( Vec2< double > p, double len, Vec2< double > t
 
 // nicht constant
 
+// Prüft ob ein Rechteck vollständig oder teilweise in der Zeichen Fläche liegt.
+//  return 0, falls das Rechteck nicht in der Zeichenfläche liegt, 1 sonst
+bool Bild::isAreaDrawable( int x, int y, int b, int h )
+{
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dSizeA[ doa ].x;
+    int dgy = dSizeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + b < dpx || y + h < dpy || x > dgx || y > dgy )
+        return 0;
+    return 1;
+}
+
 // Wird dieser Flag gesetzt, so wird beim Alpha Blending wenn die vorheriege Farbe 0 ist nur die neue mit ihrem Alpha Wert kopiert.
 // Das ist sinnvoll für die Verwendung im 3DBildschirm, wo das Gezeichnette Bild später mittels Alpha Blending angezeigt wird
 void Bild::setAlpha3D( bool erlaubt )

+ 3 - 0
Bild.h

@@ -58,6 +58,9 @@ namespace Framework
         __declspec( dllexport ) Bild( bool options = 0 );
         // Destruktor 
         __declspec( dllexport ) ~Bild();
+        // Prüft ob ein Rechteck vollständig oder teilweise in der Zeichen Fläche liegt.
+        //  return 0, falls das Rechteck nicht in der Zeichenfläche liegt, 1 sonst
+        __declspec( dllexport ) bool isAreaDrawable( int x, int y, int width, int height );
         // Wird dieser Flag gesetzt, so wird beim Alpha Blending wenn die vorheriege Farbe 0 ist nur die neue mit ihrem Alpha Wert kopiert.
         // Das ist sinnvoll für die Verwendung im 3DBildschirm, wo das Gezeichnette Bild später mittels Alpha Blending angezeigt wird.
         // Der Flag wird im 3DBildschirm automatisch gesetzt

+ 7 - 7
Diagramm.cpp

@@ -1571,7 +1571,7 @@ void LDiag::render( Bild &zRObj )
         if( daten->hIntervallWerte && hatDatenStyle( DiagDaten::Style::AutoIntervallBreite ) )
         {
             double maxW = 0;
-            for( int i = 0; i < vIAnz; ++i )
+            for( int i = 0; i < hIAnz; ++i )
             {
                 if( daten->hIntervallWerte->hat( i ) && daten->hIntervallWerte->get( i ) > maxW )
                     maxW = daten->hIntervallWerte->get( i );
@@ -1592,9 +1592,9 @@ void LDiag::render( Bild &zRObj )
         if( vIRBbr > 0 )
         {
             if( vIntervallRB->getBreite() != vIRBbr || vIntervallRB->getHeight() != schriftGr + 2 )
-                vIntervallRB->neuBild( vIRBbr, schriftGr + 2, 0 );
+                vIntervallRB->neuBild( vIRBbr, schriftGr + 2, 0xFF000000 );
             else
-                vIntervallRB->fillRegion( 0, 0, vIRBbr, schriftGr + 2, 0 );
+                vIntervallRB->fillRegion( 0, 0, vIRBbr, schriftGr + 2, 0xFF000000 );
             schrift->lock();
             schrift->setSchriftSize( schriftGr );
             if( daten->vIntervallWerte )
@@ -1654,7 +1654,7 @@ void LDiag::render( Bild &zRObj )
             {
                 int vinbr = schrift->getTextBreite( daten->vIntervallName );
                 int vinx = vIntervallRB->getBreite() / 2 - vinbr / 2;
-                vIntervallRB->fillRegion( vinx - 5, 1, vinbr + 10, schriftGr, 0 );
+                vIntervallRB->fillRegion( vinx - 5, 1, vinbr + 10, schriftGr, 0xFF000000 );
                 schrift->setDrawPosition( vinx, 1 );
                 schrift->renderText( daten->vIntervallName, *vIntervallRB, daten->vIntervallFarbe );
             }
@@ -1674,9 +1674,9 @@ void LDiag::render( Bild &zRObj )
         if( hIRBbr > 0 )
         {
             if( hIntervallRB->getBreite() != hIRBbr || hIntervallRB->getHeight() != schriftGr + 2 )
-                hIntervallRB->neuBild( hIRBbr, schriftGr + 2, 0 );
+                hIntervallRB->neuBild( hIRBbr, schriftGr + 2, 0xFF000000 );
             else
-                hIntervallRB->fillRegion( 0, 0, hIRBbr, schriftGr + 2, 0 );
+                hIntervallRB->fillRegion( 0, 0, hIRBbr, schriftGr + 2, 0xFF000000 );
             schrift->lock();
             schrift->setSchriftSize( schriftGr );
             if( daten->hIntervallWerte )
@@ -1735,7 +1735,7 @@ void LDiag::render( Bild &zRObj )
             {
                 int hinbr = schrift->getTextBreite( daten->hIntervallName );
                 int hinx = hIntervallRB->getBreite() / 2 - hinbr / 2;
-                hIntervallRB->fillRegion( hinx - 5, 1, hinbr + 10, schriftGr, 0 );
+                hIntervallRB->fillRegion( hinx - 5, 1, hinbr + 10, schriftGr, 0xFF000000 );
                 schrift->setDrawPosition( hinx, 1 );
                 schrift->renderText( daten->hIntervallName, *hIntervallRB, daten->hIntervallFarbe );
             }

+ 1 - 1
Random.cpp

@@ -65,7 +65,7 @@ void RandomGenerator::srand( int seed )
     {
         long int hi = word / 127773;
         long int lo = word % 127773;
-        word = 16807 * lo - 2836 * hi;
+        word = (int)(16807 * lo - 2836 * hi);
         if( word < 0 )
             word += 2147483647;
         *++dst = word;

+ 168 - 7
Schrift.cpp

@@ -469,6 +469,50 @@ void Alphabet::textFormatieren( Text *zText, int maxBreite, int schriftSize ) //
     setDrawSchriftSize( sg );
 }
 
+void Alphabet::render( Text *zTxt, Bild &rendezRObj, std::function< int( int, int, int ) > f ) const // Zeichnet txt nach rendezRObj
+{
+    int zRObjBr = rendezRObj.getBreite();
+    int zRObjHi = rendezRObj.getHeight();
+    int xp = pos.x;
+    int yp = pos.y;
+    int zh = getZeilenHeight();
+    if( yp + ( zh + zeilenAbstand ) * zTxt->anzahlVon( '\n' ) + zh < 0 || xp >= zRObjBr || yp >= zRObjHi )
+        return;
+    char *text = zTxt->getText();
+    int len = zTxt->getLength();
+    for( int i = 0; i < len; ++i )
+    {
+        unsigned char c = text[ i ];
+        if( c == ' ' )
+        {
+            xp += drawSchriftSize / 2;
+            continue;
+        }
+        if( c == '\t' )
+        {
+            xp += drawSchriftSize;
+            continue;
+        }
+        if( c == '\n' )
+        {
+            yp += zh + zeilenAbstand;
+            xp = pos.x;
+            continue;
+        }
+        if( zeichen[ c ] )
+        {
+            if( xp >= zRObjBr )
+                continue;
+            if( rendezRObj.isAreaDrawable( xp, yp, zeichen[ c ]->getBreite(), zeichen[ c ]->getHeight() ) )
+            {
+                zeichen[ c ]->setPosition( xp, yp );
+                zeichen[ c ]->render( rendezRObj, f( xp, yp, i ) );
+            }
+            xp += zeichen[ c ]->getBreite();
+        }
+    }
+}
+
 void Alphabet::render( Text *zTxt, Bild &rendezRObj, int f ) const // Zeichnet txt nach rendezRObj
 {
     int zRObjBr = rendezRObj.getBreite();
@@ -515,13 +559,79 @@ void Alphabet::render( Text *zTxt, Bild &rendezRObj, int f ) const // Zeichnet t
         {
             if( xp >= zRObjBr )
                 continue;
-            zeichen[ c ]->setPosition( xp, yp );
-            zeichen[ c ]->render( rendezRObj, f );
+            if( rendezRObj.isAreaDrawable( xp, yp, zeichen[ c ]->getBreite(), zeichen[ c ]->getHeight() ) )
+            {
+                zeichen[ c ]->setPosition( xp, yp );
+                zeichen[ c ]->render( rendezRObj, f );
+            }
             xp += zeichen[ c ]->getBreite();
         }
     }
 }
 
+void Alphabet::render( Text *zTxt, Bild &rendezRObj, int cpos, int cf, int fbeg, int ff, std::function< int( int, int, int ) > f ) const
+{
+    int zRObjBr = rendezRObj.getBreite();
+    int zRObjHi = rendezRObj.getHeight();
+    int xp = pos.x;
+    int yp = pos.y;
+    int zh = getZeilenHeight();
+    if( yp + ( zh + zeilenAbstand ) * zTxt->anzahlVon( '\n' ) + zh < 0 || xp >= zRObjBr || yp >= zRObjHi )
+        return;
+    char *text = zTxt->getText();
+    int len = zTxt->getLength();
+    bool faerb = 0;
+    for( int i = 0; i < len; ++i )
+    {
+        unsigned char c = text[ i ];
+        if( i == fbeg )
+            faerb = !faerb;
+        if( i == cpos )
+        {
+            rendezRObj.drawLinieVAlpha( xp, yp, zh, cf );
+            faerb = !faerb;
+        }
+        if( c == ' ' )
+        {
+            if( faerb )
+                rendezRObj.alphaRegion( xp, yp, drawSchriftSize / 2, zh, ff );
+            xp += drawSchriftSize / 2;
+            continue;
+        }
+        if( c == '\t' )
+        {
+            if( faerb )
+                rendezRObj.alphaRegion( xp, yp, drawSchriftSize, zh, ff );
+            xp += drawSchriftSize;
+            continue;
+        }
+        if( c == '\n' )
+        {
+            yp += zh + zeilenAbstand;
+            xp = pos.x;
+            continue;
+        }
+        if( zeichen[ c ] )
+        {
+            if( xp >= zRObjBr )
+                continue;
+            if( rendezRObj.isAreaDrawable( xp, yp, zeichen[ c ]->getBreite(), zeichen[ c ]->getHeight() ) )
+            {
+                if( faerb )
+                {
+                    int br = zeichen[ c ]->getBreite();
+                    rendezRObj.alphaRegion( xp, yp, br, zh, ff );
+                }
+                zeichen[ c ]->setPosition( xp, yp );
+                zeichen[ c ]->render( rendezRObj, f( xp, yp, i ) );
+            }
+            xp += zeichen[ c ]->getBreite();
+        }
+    }
+    if( len == cpos )
+        rendezRObj.drawLinieVAlpha( xp, yp, zh, cf );
+}
+
 void Alphabet::render( Text *zTxt, Bild &rendezRObj, int cpos, int cf, int fbeg, int ff, int f ) const
 {
     int zRObjBr = rendezRObj.getBreite();
@@ -580,13 +690,16 @@ void Alphabet::render( Text *zTxt, Bild &rendezRObj, int cpos, int cf, int fbeg,
         {
             if( xp >= zRObjBr )
                 continue;
-            if( faerb )
+            if( rendezRObj.isAreaDrawable( xp, yp, zeichen[ c ]->getBreite(), zeichen[ c ]->getHeight() ) )
             {
-                int br = zeichen[ c ]->getBreite();
-                rendezRObj.alphaRegion( xp, yp, br, zh, ff );
+                if( faerb )
+                {
+                    int br = zeichen[ c ]->getBreite();
+                    rendezRObj.alphaRegion( xp, yp, br, zh, ff );
+                }
+                zeichen[ c ]->setPosition( xp, yp );
+                zeichen[ c ]->render( rendezRObj, f );
             }
-            zeichen[ c ]->setPosition( xp, yp );
-            zeichen[ c ]->render( rendezRObj, f );
             xp += zeichen[ c ]->getBreite();
         }
     }
@@ -835,6 +948,30 @@ void Schrift::textFormatieren( Text *zText, int maxBreite, int schriftSize ) //
     unlock();
 }
 
+void Schrift::renderText( Text *zTxt, Bild &zRObj, std::function< int( int, int, int ) > f ) // zeichnet txt nach zRObj
+{
+    lock();
+    Alphabet *drawAlphabet = alphabet->zAlphabet( (unsigned char)schriftSize );
+    if( !drawAlphabet )
+    {
+        for( int i = 0; i < 256; ++i )
+        {
+            drawAlphabet = alphabet->zAlphabet( (unsigned char)( schriftSize - i ) );
+            if( drawAlphabet )
+                break;
+            drawAlphabet = alphabet->zAlphabet( (unsigned char)( schriftSize + i ) );
+            if( drawAlphabet )
+                break;
+        }
+    }
+    if( drawAlphabet )
+    {
+        drawAlphabet->setDrawPosition( drawPos.x, drawPos.y );
+        drawAlphabet->render( zTxt, zRObj, f );
+    }
+    unlock();
+}
+
 void Schrift::renderText( Text *zTxt, Bild &zRObj, int f ) // zeichnet txt nach zRObj
 {
     lock();
@@ -859,6 +996,30 @@ void Schrift::renderText( Text *zTxt, Bild &zRObj, int f ) // zeichnet txt nach
     unlock();
 }
 
+void Schrift::renderText( Text *zTxt, Bild &zRObj, int cpos, int cf, int fbeg, int ff, std::function< int( int, int, int ) > f )
+{
+    lock();
+    Alphabet *drawAlphabet = alphabet->zAlphabet( (unsigned char)schriftSize );
+    if( !drawAlphabet )
+    {
+        for( int i = 0; i < 256; ++i )
+        {
+            drawAlphabet = alphabet->zAlphabet( (unsigned char)( schriftSize - i ) );
+            if( drawAlphabet )
+                break;
+            drawAlphabet = alphabet->zAlphabet( (unsigned char)( schriftSize + i ) );
+            if( drawAlphabet )
+                break;
+        }
+    }
+    if( drawAlphabet )
+    {
+        drawAlphabet->setDrawPosition( drawPos.x, drawPos.y );
+        drawAlphabet->render( zTxt, zRObj, cpos, cf, fbeg, ff, f );
+    }
+    unlock();
+}
+
 void Schrift::renderText( Text *zTxt, Bild &zRObj, int cpos, int cf, int fbeg, int ff, int f )
 {
     lock();

+ 33 - 0
Schrift.h

@@ -3,6 +3,7 @@
 
 #include "Critical.h"
 #include "Punkt.h"
+#include <functional>
 
 namespace Framework
 {
@@ -168,6 +169,12 @@ namespace Framework
 		//  schriftSize: Die Schriftgröße, in der der Text passend dargestellt werden soll
         __declspec( dllexport ) void textFormatieren( Text *zText, int maxBreite, int schriftSize );
         // Zeichnet einen Bestimmten Text auf ein Bild
+        // Nutze (setDrawPosition) und (setSchriftGröße) um die Position und die Größe zu verändern
+        //  zText: Der Text, der gezeichnet werden soll
+        //  zRObj: Das Bild, auf das gezeichnet werden soll
+        //  f: Eine Funktion die für jeden Buchstaben aufgerufen wird und seine Farbe zurückgibt
+        __declspec( dllexport ) void render( Text *zTxt, Bild &zRObj, std::function< int( int, int, int ) > f ) const;
+        // Zeichnet einen Bestimmten Text auf ein Bild
         // Nutze (setDrawPosition) und (setDrawSchriftGröße) um die Position und die Größe zu verändern
         //  zText: Der Text, der gezeichnet werden soll
         //  zRObj: Das Bild, auf das gezeichnet werden soll
@@ -181,6 +188,16 @@ namespace Framework
         //  cf: Die Farbe des Cursors
         //  fbeg: Die Position des Zeichens im Text, wo die Einfärbung beginnen soll. Der Text wird von dort bis zur Cursorposition eingefärbt
         //  ff: Die Hintergrund Farbe des eingefärbten Textes
+        //  f: Eine Funktion die für jeden Buchstaben aufgerufen wird und seine Farbe zurückgibt
+        __declspec( dllexport ) void render( Text *zTxt, Bild &zRObj, int cpos, int cf, int fbeg, int ff, std::function< int( int, int, int ) > f ) const;
+        // Zeichnet einen Bestimmten Text mit Cursor und einfärbung auf ein Bild
+        // Nutze (setPosition) und (setDrawSchriftGröße) um die Position und die Größe zu verändern
+        //  zText: Der Text, der gezeichnet werden soll
+        //  zRObj: Das Bild, auf das gezeichnet werden soll
+        //  cpos: Die position des Cursors im Text
+        //  cf: Die Farbe des Cursors
+        //  fbeg: Die Position des Zeichens im Text, wo die Einfärbung beginnen soll. Der Text wird von dort bis zur Cursorposition eingefärbt
+        //  ff: Die Hintergrund Farbe des eingefärbten Textes
         //  f: Die Farbe, in der der Text gezeichnet werden soll
         __declspec( dllexport ) void render( Text *zTxt, Bild &zRObj, int cpos, int cf, int fbeg, int ff, int f ) const;
 
@@ -300,6 +317,12 @@ namespace Framework
         // Nutze (setDrawPosition) und (setSchriftGröße) um die Position und die Größe zu verändern
         //  zText: Der Text, der gezeichnet werden soll
         //  zRObj: Das Bild, auf das gezeichnet werden soll
+        //  f: Eine Funktion die für jeden Buchstaben aufgerufen wird und seine Farbe zurückgibt
+        __declspec( dllexport ) void renderText( Text *zTxt, Bild &zRObj, std::function< int( int, int, int ) > f );
+        // Zeichnet einen Bestimmten Text auf ein Bild
+        // Nutze (setDrawPosition) und (setSchriftGröße) um die Position und die Größe zu verändern
+        //  zText: Der Text, der gezeichnet werden soll
+        //  zRObj: Das Bild, auf das gezeichnet werden soll
         //  f: Die Farbe, in der der Text gezeichnet werden soll
         __declspec( dllexport ) void renderText( Text *zTxt, Bild &zRObj, int f );
         // Zeichnet einen Bestimmten Text mit Cursor und einfärbung auf ein Bild
@@ -310,6 +333,16 @@ namespace Framework
         //  cf: Die Farbe des Cursors
         //  fbeg: Die Position des Zeichens im Text, wo die Einfärbung beginnen soll. Der Text wird von dort bis zur Cursorposition eingefärbt
         //  ff: Die Hintergrund Farbe des eingefärbten Textes
+        //  f: Eine Funktion die für jeden Buchstaben aufgerufen wird und seine Farbe zurückgibt
+        __declspec( dllexport ) void renderText( Text *zTxt, Bild &zRObj, int cpos, int cf, int fbeg, int ff, std::function< int( int, int, int ) > f );
+        // Zeichnet einen Bestimmten Text mit Cursor und einfärbung auf ein Bild
+        // Nutze (setPosition) und (setDrawSchriftGröße) um die Position und die Größe zu verändern
+        //  zText: Der Text, der gezeichnet werden soll
+        //  zRObj: Das Bild, auf das gezeichnet werden soll
+        //  cpos: Die position des Cursors im Text
+        //  cf: Die Farbe des Cursors
+        //  fbeg: Die Position des Zeichens im Text, wo die Einfärbung beginnen soll. Der Text wird von dort bis zur Cursorposition eingefärbt
+        //  ff: Die Hintergrund Farbe des eingefärbten Textes
         //  f: Die Farbe, in der der Text gezeichnet werden soll
         __declspec( dllexport ) void renderText( Text *zTxt, Bild &zRObj, int cpos, int cf, int fbeg, int ff, int f );
         // Gibt ein bestimmtes Alphabet mit erhöhtem Reference Counter zurück

+ 2 - 1
Text.cpp

@@ -1134,7 +1134,7 @@ TextReader::~TextReader()
 void TextReader::setLPosition( __int64 pos, bool ende )
 {
     int l = txt->getLength();
-    lPos = ende ? l - pos : lPos;
+    lPos = ende ? l - pos : pos;
     if( lPos < 0 )
         lPos = 0;
     if( lPos > l )
@@ -1150,6 +1150,7 @@ void TextReader::lese( char *bytes, int len )
     len = (int)MIN( l - lPos, len );
     for( __int64 i = lPos; i < lPos + len; i++ )
         bytes[ i - lPos ] = txt->getText()[ i ];
+    lPos += len;
 }
 
 // Ließt die nächste zeile des Textes ein