Commit 90e3be9c24f18e5e236179ca333bdc09f313dfe9

patrick 2003-04-06T19:16:39

- Changed the FTFont::BBox to accept a range of indicies. Only characters with the range are checked. The previous funcitonality is preserved via inline methods that call the new implementation. - Kluged a fix for a bug where FTFont::BBox was returning bounding volumes where min > max. I don't know where the problem is originating, I just force the bounds to be correct. - Changed the FTFong::DoRener methods to accept an external FTPoint for the pen position. This enables FTLayout classes to use their own pen for rendering. - Added the FTLayout class as a friend of FTFont to allow layout managers to call private rendering functions and access private font information.

diff --git a/include/FTFont.h b/include/FTFont.h
index 3f36839..ed6f425 100755
--- a/include/FTFont.h
+++ b/include/FTFont.h
@@ -9,7 +9,7 @@
 
 class FTGlyphContainer;
 class FTGlyph;
-
+class FTLayout;
 
 /**
  * FTFont is the public interface for the FTGL library.
@@ -124,6 +124,44 @@ class FTGL_EXPORT FTFont
         /**
          * Get the bounding box for a string.
          *
+         * @param String    a char buffer
+         * @param StartIdx  The index of the first character of String
+         *                  to check.
+         * @param EndIdx    The index of the last character of String to
+         *                  check.  If < 0 then characters will be parsed
+         *                  until a '\0' is encountered.
+         * @param llx       lower left near x coord
+         * @param lly       lower left near y coord
+         * @param llz       lower left near z coord
+         * @param urx       upper right far x coord
+         * @param ury       upper right far y coord
+         * @param urz       upper right far z coord
+         */
+        void BBox(const char *String,const int StartIdx,const int EndIdx,
+                  float& llx, float& lly, float& llz, float& urx, float& ury, float& urz);
+                  
+        /**
+         * Get the bounding box for a string.
+         *
+         * @param String    a wchar_t buffer
+         * @param StartIdx  The index of the first character of String
+         *                  to check.
+         * @param EndIdx    The index of the last character of String
+         *                  to check.    If < 0 then characters will
+         *                  be parsed until a '\0' is encountered.
+         * @param llx       lower left near x coord
+         * @param lly       lower left near y coord
+         * @param llz       lower left near z coord
+         * @param urx       upper right far x coord
+         * @param ury       upper right far y coord
+         * @param urz       upper right far z coord
+         */
+        void BBox(const wchar_t *String,const int StartIdx,const int EndIdx,
+                  float& llx, float& lly, float& llz, float& urx, float& ury, float& urz);
+        
+        /**
+         * Get the bounding box for a string.
+         *
          * @param string    a char string
          * @param llx       lower left near x coord
          * @param lly       lower left near y coord
@@ -132,7 +170,8 @@ class FTGL_EXPORT FTFont
          * @param ury       upper right far y coord
          * @param urz       upper right far z coord
          */
-        void BBox( const char* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz);
+        void BBox( const char* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz)
+            { BBox(string,0,-1,llx,lly,llz,urx,ury,urz); }
 
         /**
          * Get the bounding box for a string.
@@ -145,8 +184,9 @@ class FTGL_EXPORT FTFont
          * @param ury       upper right far y coord
          * @param urz       upper right far z coord
          */
-        void BBox( const wchar_t* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz);
-
+        void BBox( const wchar_t* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz)
+            { BBox(string,0,-1,llx,lly,llz,urx,ury,urz); }
+            
         /**
          * Get the advance width for a string.
          *
@@ -183,7 +223,6 @@ class FTGL_EXPORT FTFont
          * @return  The current error code.
          */
         FT_Error Error() const { return err;}
-
     protected:
         /**
          * Construct a glyph of the correct type.
@@ -213,13 +252,17 @@ class FTGL_EXPORT FTFont
         
     private:        
         /**
-         * Render a character
+         * Render a character.
          * This function does an implicit conversion on it's arguments.
          * 
          * @param chr       current character
          * @param nextChr   next character
+         * @param origin	 The position of the origin of the character.
+         *                  After rendering the point referenced by origin 
+         *                  will be incremented by the kerning advance of 
+         *                  char and nextChr.
          */
-        inline void DoRender( const unsigned int chr, const unsigned int nextChr);
+        inline void DoRender( const unsigned int chr, const unsigned int nextChr, FTPoint &origin);
         
         /**
          * Check that the glyph at <code>chr</code> exist. If not load it.
@@ -237,6 +280,9 @@ class FTGL_EXPORT FTFont
          * Current pen or cursor position;
          */
         FTPoint pen;
+        
+        /* Allow FTLayout classes to access DoRender and CheckGlyph */
+        friend class FTLayout;
 };
 
 
diff --git a/src/FTFont.cpp b/src/FTFont.cpp
index 438105a..46684b8 100755
--- a/src/FTFont.cpp
+++ b/src/FTFont.cpp
@@ -100,76 +100,63 @@ float FTFont::Descender() const
     return charSize.Descender();
 }
 
-
-void FTFont::BBox( const char* string,
-                   float& llx, float& lly, float& llz, float& urx, float& ury, float& urz)
-{
+void FTFont::BBox(const char *String,const int StartIdx,const int EndIdx,
+                  float& llx, float& lly, float& llz, float& urx, float& ury, float& urz) {
     FTBBox totalBBox;
 
-    if((NULL != string) && ('\0' != *string))
-    {
-        const unsigned char* c = (unsigned char*)string;
-
-        CheckGlyph( *c);
+    if (String && ('\0' != String[StartIdx])) {
+        CheckGlyph(String[StartIdx]);
 
-        totalBBox = glyphList->BBox( *c);
-        float advance = glyphList->Advance( *c, *(c + 1));
-        ++c;
+        totalBBox = glyphList->BBox(String[StartIdx]);
+        float advance = glyphList->Advance(String[StartIdx],String[StartIdx + 1]);
             
-        while( *c)
-        {
-            CheckGlyph( *c);
-            FTBBox tempBBox = glyphList->BBox( *c);
-            tempBBox.Move( FTPoint( advance, 0.0f, 0.0f));
-            totalBBox += tempBBox;
-            advance += glyphList->Advance( *c, *(c + 1));
-            ++c;
-        }
-    }
-
-    llx = totalBBox.lowerX;
-    lly = totalBBox.lowerY;
-    llz = totalBBox.lowerZ;
-    urx = totalBBox.upperX;
-    ury = totalBBox.upperY;
-    urz = totalBBox.upperZ;
-}
-
+        for (int idx = StartIdx + 1;((EndIdx < 0) && String[idx]) || ((EndIdx >= 0) && (idx <= EndIdx));idx++) {
+            CheckGlyph(String[idx]);
+            FTBBox tempBBox = glyphList->BBox(String[idx]);
+            tempBBox.Move(FTPoint(advance,0.0f,0.0f));
 
-void FTFont::BBox( const wchar_t* string,
-                   float& llx, float& lly, float& llz, float& urx, float& ury, float& urz)
-{
+            totalBBox += tempBBox;
+            advance += glyphList->Advance(String[idx],String[idx + 1]);
+        } /* Expand totalBox by each glyph in String (for idx) */
+    } /* Only compute the bounds if String is non-empty (if String) */
+
+    // TODO: The Z values do not follow the proper ordering.  I'm not sure why.
+    llx = totalBBox.lowerX < totalBBox.upperX ? totalBBox.lowerX : totalBBox.upperX;
+    lly = totalBBox.lowerY < totalBBox.upperY ? totalBBox.lowerY : totalBBox.upperY;
+    llz = totalBBox.lowerZ < totalBBox.upperZ ? totalBBox.lowerZ : totalBBox.upperZ;
+    urx = totalBBox.lowerX > totalBBox.upperX ? totalBBox.lowerX : totalBBox.upperX;
+    ury = totalBBox.lowerY > totalBBox.upperY ? totalBBox.lowerY : totalBBox.upperY;
+    urz = totalBBox.lowerZ > totalBBox.upperZ ? totalBBox.lowerZ : totalBBox.upperZ;
+} /* FTFont::BBox() */
+
+void FTFont::BBox(const wchar_t *String,const int StartIdx,const int EndIdx,
+                  float& llx, float& lly, float& llz, float& urx, float& ury, float& urz) {
     FTBBox totalBBox;
 
-    if((NULL != string) && ('\0' != *string))
-    {
-        const wchar_t* c = string;
-
-        CheckGlyph( *c);
+    if (String && ('\0' != String[StartIdx])) {
+        CheckGlyph(String[StartIdx]);
 
-        totalBBox = glyphList->BBox( *c);
-        float advance = glyphList->Advance( *c, *(c + 1));
-        ++c;
+        totalBBox = glyphList->BBox(String[StartIdx]);
+        float advance = glyphList->Advance(String[StartIdx],String[StartIdx + 1]);
+            
+        for (int idx = StartIdx + 1;((EndIdx < 0) && String[idx]) || ((EndIdx >= 0) && (idx <= EndIdx));idx++) {
+            CheckGlyph(String[idx]);
+            FTBBox tempBBox = glyphList->BBox(String[idx]);
+            tempBBox.Move(FTPoint(advance,0.0f,0.0f));
 
-        while( *c)
-        {
-            CheckGlyph( *c);
-            FTBBox tempBBox = glyphList->BBox( *c);
-            tempBBox.Move( FTPoint( advance, 0.0f, 0.0f));
             totalBBox += tempBBox;
-            advance += glyphList->Advance( *c, *(c + 1));
-            ++c;
-        }
-    }
-
-    llx = totalBBox.lowerX;
-    lly = totalBBox.lowerY;
-    llz = totalBBox.lowerZ;
-    urx = totalBBox.upperX;
-    ury = totalBBox.upperY;
-    urz = totalBBox.upperZ;
-}
-
+            advance += glyphList->Advance(String[idx],String[idx + 1]);
+        } /* Expand totalBox by each glyph in String (for idx) */
+    } /* Only compute the bounds if String is non-empty (if String) */
+
+    // TODO: The Z values do not follow the proper ordering.  I'm not sure why.
+    llx = totalBBox.lowerX < totalBBox.upperX ? totalBBox.lowerX : totalBBox.upperX;
+    lly = totalBBox.lowerY < totalBBox.upperY ? totalBBox.lowerY : totalBBox.upperY;
+    llz = totalBBox.lowerZ < totalBBox.upperZ ? totalBBox.lowerZ : totalBBox.upperZ;
+    urx = totalBBox.lowerX > totalBBox.upperX ? totalBBox.lowerX : totalBBox.upperX;
+    ury = totalBBox.lowerY > totalBBox.upperY ? totalBBox.lowerY : totalBBox.upperY;
+    urz = totalBBox.lowerZ > totalBBox.upperZ ? totalBBox.lowerZ : totalBBox.upperZ;
+} /* FTFont::BBox() */
 
 float FTFont::Advance( const wchar_t* string)
 {
@@ -202,7 +189,6 @@ float FTFont::Advance( const char* string)
     return width;
 }
 
-
 void FTFont::Render( const char* string )
 {
     const unsigned char* c = (unsigned char*)string;
@@ -210,7 +196,7 @@ void FTFont::Render( const char* string )
 
     while( *c)
     {
-        DoRender( *c, *(c + 1));
+        DoRender( *c, *(c + 1),pen);
         ++c;
     }
 }
@@ -223,20 +209,20 @@ void FTFont::Render( const wchar_t* string )
 
     while( *c)
     {
-        DoRender( *c, *(c + 1));
+        DoRender( *c, *(c + 1),pen);
         ++c;
     }
 }
 
 
-void FTFont::DoRender( const unsigned int chr, const unsigned int nextChr)
+void FTFont::DoRender( const unsigned int chr, const unsigned int nextChr, FTPoint &origin)
 {
     CheckGlyph( chr);
 
-    FTPoint kernAdvance = glyphList->Render( chr, nextChr, pen);
+    FTPoint kernAdvance = glyphList->Render( chr, nextChr, origin);
     
-    pen.x += kernAdvance.x;
-    pen.y += kernAdvance.y;
+    origin.x += kernAdvance.x;
+    origin.y += kernAdvance.y;
 }