Simplify font-chaining (fallbacks) to have fonthost just return the next
logical fontID.
Extend ImageRef to accept an imagedecoder factory, to replace calling the std
one.



git-svn-id: http://skia.googlecode.com/svn/trunk@125 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkFontHost.h b/include/core/SkFontHost.h
index d98c55f..942350f 100644
--- a/include/core/SkFontHost.h
+++ b/include/core/SkFontHost.h
@@ -117,11 +117,14 @@
     */
     static SkScalerContext* CreateScalerContext(const SkDescriptor* desc);
 
-    /** Return a scalercontext using the "fallback" font. If there is no
-        designated fallback, return null.
+    /** Given a "current" fontID, return the next logical fontID to use
+        when searching fonts for a given unicode value. Typically the caller
+        will query a given font, and if a unicode value is not supported, they
+        will call this, and if 0 is not returned, will search that font, and so
+        on. This process must be finite, and when the fonthost sees a
+        font with no logical successor, it must return 0.
     */
-    static SkScalerContext* CreateFallbackScalerContext(
-                                                const SkScalerContext::Rec&);
+    static uint32_t NextLogicalFont(uint32_t fontID);
 
     ///////////////////////////////////////////////////////////////////////////
     
diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h
index 583833e..b06a443 100644
--- a/include/core/SkScalerContext.h
+++ b/include/core/SkScalerContext.h
@@ -169,10 +169,16 @@
     SkScalerContext(const SkDescriptor* desc);
     virtual ~SkScalerContext();
 
+    // remember our glyph offset/base
     void setBaseGlyphCount(unsigned baseGlyphCount) {
         fBaseGlyphCount = baseGlyphCount;
     }
 
+    /** Return the corresponding glyph for the specified unichar. Since contexts
+        may be chained (under the hood), the glyphID that is returned may in
+        fact correspond to a different font/context. In that case, we use the
+        base-glyph-count to know how to translate back into local glyph space.
+     */
     uint16_t    charToGlyphID(SkUnichar uni);
 
     unsigned    getGlyphCount() const { return this->generateGlyphCount(); }
@@ -208,12 +214,15 @@
     void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
                          SkPath* devPath, SkMatrix* fillToDevMatrix);
 
-    mutable SkScalerContext* fAuxScalerContext;
+    // return the next context, treating fNextContext as a cache of the answer
+    SkScalerContext* getNextContext();
 
-    SkScalerContext* getGlyphContext(const SkGlyph& glyph) const;
-    
-    // return loaded fAuxScalerContext or NULL
-    SkScalerContext* loadAuxContext() const;
+    // returns the right context from our link-list for this glyph. If no match
+    // is found, just returns the original context (this)
+    SkScalerContext* getGlyphContext(const SkGlyph& glyph);
+
+    // link-list of context, to handle missing chars. null-terminated.
+    SkScalerContext* fNextContext;
 };
 
 #define kRec_SkDescriptorTag            SkSetFourByteTag('s', 'r', 'e', 'c')
diff --git a/include/images/SkImageDecoder.h b/include/images/SkImageDecoder.h
index 3ea6198..c85a7cd 100644
--- a/include/images/SkImageDecoder.h
+++ b/include/images/SkImageDecoder.h
@@ -147,7 +147,7 @@
         If none is found, the method returns NULL.
     */
     static SkImageDecoder* Factory(SkStream*);
-    
+
     /** Decode the image stored in the specified file, and store the result
         in bitmap. Return true for success or false on failure.
 
@@ -260,4 +260,24 @@
     SkImageDecoder& operator=(const SkImageDecoder&);
 };
 
+/** Calling newDecoder with a stream returns a new matching imagedecoder
+    instance, or NULL if none can be found. The caller must manage its ownership
+    of the stream as usual, calling unref() when it is done, as the returned
+    decoder may have called ref() (and if so, the decoder is responsible for
+    balancing its ownership when it is destroyed).
+ */
+class SkImageDecoderFactory : public SkRefCnt {
+public:
+    virtual SkImageDecoder* newDecoder(SkStream*) = 0;
+};
+
+class SkDefaultImageDecoderFactory : SkImageDecoderFactory {
+public:
+    // calls SkImageDecoder::Factory(stream)
+    virtual SkImageDecoder* newDecoder(SkStream* stream) {
+        return SkImageDecoder::Factory(stream);
+    }
+};
+
+
 #endif
diff --git a/include/images/SkImageRef.h b/include/images/SkImageRef.h
index 26ade5e..6ab6e52 100644
--- a/include/images/SkImageRef.h
+++ b/include/images/SkImageRef.h
@@ -52,6 +52,10 @@
         and ignore the bitmap parameter.
     */
     bool getInfo(SkBitmap* bm);
+    
+    SkImageDecoderFactory* getDecoderFactory() const { return fFactory; }
+    // returns the factory parameter
+    SkImageDecoderFactory* setDecoderFactory(SkImageDecoderFactory*);
 
     // overrides
     virtual void flatten(SkFlattenableWriteBuffer&) const;
@@ -81,10 +85,11 @@
     // requested state (or further, i.e. has pixels)
     bool prepareBitmap(SkImageDecoder::Mode);
 
-    SkStream*           fStream;
-    SkBitmap::Config    fConfig;
-    int                 fSampleSize;
-    bool                fErrorInDecoding;
+    SkImageDecoderFactory*  fFactory;    // may be null
+    SkStream*               fStream;
+    SkBitmap::Config        fConfig;
+    int                     fSampleSize;
+    bool                    fErrorInDecoding;
     
     friend class SkImageRefPool;