freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2-demos] master c1c0c3f 1/4: [ftinspect] Another try to impleme


From: Werner LEMBERG
Subject: [freetype2-demos] master c1c0c3f 1/4: [ftinspect] Another try to implement `faceRequester'.
Date: Sat, 7 May 2016 15:36:10 +0000 (UTC)

branch: master
commit c1c0c3fd87a63f819260802a3ba0231f43dd535b
Author: Werner Lemberg <address@hidden>
Commit: Werner Lemberg <address@hidden>

    [ftinspect] Another try to implement `faceRequester'.
    
    * src/ftinspect.h (FaceID): Extend structure to make it suitable as
    key to Qt's `QHash' class.
    (qHash): Also needed for `QHash'.
    (MainGUI): Provide running ID number in `maxFaces'.
    New `faceIDHash' to map between (font,face,instance) index triplets
    and IDs.
    
    * src/ftinspect.cpp (FaceID::FaceID, FaceID::operator==, qHash):
    Implement.
    (faceRequester): Use `faceIDHash'.
    (MainGUI::showFont): Fill `faceIDHash'.
    (MainGUI::setDefaults): Updated.
---
 ChangeLog         |   17 ++++++++++++++
 src/ftinspect.cpp |   65 +++++++++++++++++++++++++++++++++++++++++++++++------
 src/ftinspect.h   |   28 +++++++++++++++++++++++
 3 files changed, 103 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f2da01a..76e8f52 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2016-05-07  Werner Lemberg  <address@hidden>
+
+       [ftinspect] Another try to implement `faceRequester'.
+
+       * src/ftinspect.h (FaceID): Extend structure to make it suitable as
+       key to Qt's `QHash' class.
+       (qHash): Also needed for `QHash'.
+       (MainGUI): Provide running ID number in `maxFaces'.
+       New `faceIDHash' to map between (font,face,instance) index triplets
+       and IDs.
+
+       * src/ftinspect.cpp (FaceID::FaceID, FaceID::operator==, qHash):
+       Implement.
+       (faceRequester): Use `faceIDHash'.
+       (MainGUI::showFont): Fill `faceIDHash'.
+       (MainGUI::setDefaults): Updated.
+
 2016-05-06  Werner Lemberg  <address@hidden>
 
        * src/ftinspect.cpp (MainGUI::showFont): Fix logic.
diff --git a/src/ftinspect.cpp b/src/ftinspect.cpp
index 4f8a914..1e16fd4 100644
--- a/src/ftinspect.cpp
+++ b/src/ftinspect.cpp
@@ -8,11 +8,51 @@
 #define VERSION "X.Y.Z"
 
 
+FaceID::FaceID()
+: fontIndex(0),
+  faceIndex(0),
+  instanceIndex(0)
+{
+  // empty
+}
+
+
+FaceID::FaceID(int fontIdx,
+               int faceIdx,
+               int instanceIdx)
+: fontIndex(fontIdx),
+  faceIndex(faceIdx),
+  instanceIndex(instanceIdx)
+{
+  // empty
+}
+
+
+bool
+FaceID::operator==(const FaceID& other) const
+{
+  return (fontIndex == other.fontIndex
+          && faceIndex == other.faceIndex
+          && instanceIndex == other.instanceIndex);
+}
+
+
+uint
+qHash(FaceID key)
+{
+  return ((uint)key.fontIndex << 20)
+         | ((uint)key.faceIndex << 10)
+         | (uint)key.instanceIndex;
+}
+
+
 // The face requester is a function provided by the client application to
 // the cache manager to translate an `abstract' face ID into a real
 // `FT_Face' object.
 //
-// Here, the face IDs are simply pointers to `Font' objects.
+// We use a hash: `faceID' is the value, and its associated key gives the
+// font, face, and instance indices.  Getting a key from a value is slow,
+// but this must be done only once.
 
 FT_Error
 faceRequester(FTC_FaceID faceID,
@@ -21,13 +61,16 @@ faceRequester(FTC_FaceID faceID,
               FT_Face* faceP)
 {
   MainGUI* gui = static_cast<MainGUI*>(requestData);
-  FaceID* id = static_cast<FaceID*>(faceID);
+  // in C++ it's tricky to convert a void pointer back to an integer
+  // without warnings related to 32bit vs. 64bit pointer size
+  int val = static_cast<int>((char*)faceID - (char*)0);
+  const FaceID& id = gui->faceIDHash.key(val);
 
-  Font& font = gui->fonts[id->fontIndex];
-  int faceIndex = id->faceIndex;
+  Font& font = gui->fonts[id.fontIndex];
+  int faceIndex = id.faceIndex;
 
-  if (id->instanceIndex >= 0)
-    faceIndex += id->instanceIndex << 16;
+  if (id.instanceIndex >= 0)
+    faceIndex += id.instanceIndex << 16;
 
   return FT_New_Face(library,
                      qPrintable(font.filePathname),
@@ -468,7 +511,7 @@ MainGUI::showFont()
 {
   if (currentFontIndex >= 0)
   {
-    // we do lazy evaluation as much as possible
+    // we do lazy computation of FT_Face objects
 
     Font& font = fonts[currentFontIndex];
 
@@ -510,6 +553,12 @@ MainGUI::showFont()
 
       font.numInstancesList[currentFaceIndex] = numInstances;
 
+      // assign the (font,face,instance) triplet to a running ID;
+      // we need this for the `faceRequester' function
+      for (int i = 0; i < numInstances; i++)
+        faceIDHash.insert(FaceID(currentFontIndex, currentFaceIndex, i),
+                          maxFaces++);
+
       // instance index 0 represents a face without an instance;
       // consequently, `n' instances are enumerated from 1 to `n'
       // (instead of having indices 0 to `n-1')
@@ -1214,6 +1263,8 @@ MainGUI::clearStatusBar()
 void
 MainGUI::setDefaults()
 {
+  maxFaces = 0;
+
   // set up mappings between property values and combo box indices
   hintingModesTrueTypeHash[TT_INTERPRETER_VERSION_35] = 
HintingMode_TrueType_v35;
   hintingModesTrueTypeHash[TT_INTERPRETER_VERSION_38] = 
HintingMode_TrueType_v38;
diff --git a/src/ftinspect.h b/src/ftinspect.h
index 0767dce..5682d8f 100644
--- a/src/ftinspect.h
+++ b/src/ftinspect.h
@@ -48,22 +48,47 @@
 class MainGUI;
 
 
+// A structure to hold a physical font.
+//
+// A valid font contains one or more multiple faces.
+// A valid face contains one or more instances.
+// A valid instance gets assigned an entry in MainGUI's `faceIDHash'.
+//
+// An invalid font is marked as having one face but zero instances.
+// An invalid face is marked as having -1 instances.
+
 struct Font
 {
   QString filePathname;
+
   // the number of instances per face;
   // the size of the list gives the number of faces
   QList<int> numInstancesList;
 };
 
 
+// This structure is used to map the (font,face,instance) index triplet to
+// abstract IDs (generated by a running number stored in MainGUI's
+// `maxFaces' member).
+//
+// Qt's `QHash' class needs an implementation of `==' and a global,
+// overloaded `qHash' function.
+
 struct FaceID
 {
   int fontIndex;
   int faceIndex;
   int instanceIndex;
+
+  FaceID();
+  FaceID(int, int, int);
+  bool operator==(const FaceID& other) const;
 };
 
+uint qHash(FaceID key);
+
+
+// FreeType specific data.
 
 class Engine
 {
@@ -192,6 +217,9 @@ private:
   int currentFaceIndex;
   int currentInstanceIndex;
 
+  int maxFaces; // a running number used to initialize `faceIDHash'
+  QHash<FaceID, int> faceIDHash;
+
   // layout related stuff
   QAction *aboutAct;
   QAction *aboutQtAct;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]