PDF: Add text support with a font framework (font embedding to come).

Supports fakeBold, underline, strikethrough, mode (fill, stroke, both), size, skew, alignment (left, center, right).
Missing is drawFontOnPath and font lookup and embedding.
Changed SkPDFString to support how it is used from drawText methods.
Moved compile assert into SkTypes.
Moved constants and utility function used to support fakeBold, underline, and strikethrough into higher level locations.

Review URL: http://codereview.appspot.com/2946041

git-svn-id: http://skia.googlecode.com/svn/trunk@624 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index ada2791..b92dc3d 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -26,6 +26,7 @@
 class SkPDFArray;
 class SkPDFDevice;
 class SkPDFDict;
+class SkPDFFont;
 class SkPDFGraphicState;
 class SkPDFObject;
 class SkPDFStream;
@@ -124,6 +125,7 @@
 
     SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
     SkTDArray<SkPDFObject*> fXObjectResources;
+    SkTDArray<SkPDFFont*> fFontResources;
 
     // In PDF, transforms and clips can only be undone by popping the graphic
     // state to before the transform or clip was applied.  Because it can be
@@ -138,7 +140,10 @@
     // two entries: a clip and then a transform
     struct GraphicStackEntry {
         SkColor fColor;
+        SkScalar fTextSize;
         SkScalar fTextScaleX;
+        SkPaint::Style fTextFill;
+        SkRefPtr<SkPDFFont> fFont;
         SkRefPtr<SkPDFGraphicState> fGraphicState;
         SkRegion fClip;
         SkMatrix fTransform;
@@ -148,7 +153,8 @@
 
     SkString fContent;
 
-    void updateGSFromPaint(const SkPaint& newPaint, SkString* textStaetUpdate);
+    void updateGSFromPaint(const SkPaint& newPaint, bool forText);
+    int getFontResourceIndex(uint32_t fontID);
 
     void moveTo(SkScalar x, SkScalar y);
     void appendLine(SkScalar x, SkScalar y);
@@ -162,6 +168,7 @@
     void strokePath();
     void pushGS();
     void popGS();
+    void setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX);
     void internalDrawBitmap(const SkMatrix& matrix, const SkBitmap& bitmap,
                             const SkPaint& paint);
 
diff --git a/include/pdf/SkPDFFont.h b/include/pdf/SkPDFFont.h
new file mode 100644
index 0000000..82357ef
--- /dev/null
+++ b/include/pdf/SkPDFFont.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFFont_DEFINED
+#define SkPDFFont_DEFINED
+
+#include "SkPDFTypes.h"
+#include "SkTDArray.h"
+#include "SkThread.h"
+
+class SkPaint;
+
+/** \class SkPDFFont
+    A PDF Object class representing a font.  The font may have resources
+    attached to it in order to embed the font.  SkPDFFonts are canonicalized
+    so that resource deduplication will only include one copy of a font.
+    This class uses the same pattern as SkPDFGraphicState, a static weak
+    reference to each instantiated class.
+*/
+class SkPDFFont : public SkPDFDict {
+public:
+    virtual ~SkPDFFont();
+
+    virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+    /* Returns the font ID represented by this class.
+     */
+    uint32_t fontID();
+
+    /** Returns true if this font supports glyph IDs above 255.
+     */
+    bool multiByteGlyphs();
+
+    /** Covert the specified text to glyph IDs, taking into consideration
+     *  PDF encodings and return the number of glyphs IDs written.
+     */
+    int textToPDFGlyphs(const void* text, size_t byteLength,
+                        const SkPaint& paint, uint16_t* glyphs,
+                        size_t glyphsLength) const;
+
+    /** Get the font resource for the passed font ID. The reference count of
+     *  the object is incremented and it is the caller's responsibility to
+     *  unreference it when done.  This is needed to accommodate the weak
+     *  reference pattern used when the returned object is new and has no
+     *  other references.
+     *  @param paint  The SkPaint to emulate.
+     */
+    static SkPDFFont* getFontResouceByID(uint32_t fontID);
+
+private:
+    uint32_t fFontID;
+    bool fMultiByteGlyphs;
+
+    SkTDArray<SkPDFObject*> fResources;
+
+    class FontRec {
+    public:
+        SkPDFFont* fFont;
+        uint32_t fFontID;
+
+        bool operator==(const FontRec& b) const;
+        FontRec(SkPDFFont* font, uint32_t fontID);
+    };
+
+    // This should be made a hash table if performance is a problem.
+    static SkTDArray<FontRec>& canonicalFonts();
+    static SkMutex& canonicalFontsMutex();
+
+    SkPDFFont(uint32_t fontID, bool multiByteGlyphs);
+
+    void populateBuiltinFont(const char fontName[]);
+    void populateFont(const char subType[], const char fontName[],
+                      int firstChar, int lastChar, int widths[],
+                      SkPDFObject* fontDescriptor);
+
+    static int find(uint32_t fontID);
+};
+
+#endif
diff --git a/include/pdf/SkPDFTypes.h b/include/pdf/SkPDFTypes.h
index a281628..fc9b62c 100644
--- a/include/pdf/SkPDFTypes.h
+++ b/include/pdf/SkPDFTypes.h
@@ -21,6 +21,7 @@
 #include "SkScalar.h"
 #include "SkString.h"
 #include "SkTDArray.h"
+#include "SkTypes.h"
 
 class SkPDFCatalog;
 class SkWStream;
@@ -169,6 +170,14 @@
      */
     explicit SkPDFString(const char value[]);
     explicit SkPDFString(const SkString& value);
+
+    /** Create a PDF string. Maximum length (in bytes) is 65,535.
+     *  @param value     A string value.
+     *  @param len       The length of value.
+     *  @param wideChars Indicates if the top byte in value is significant and
+     *                   should be encoded (true) or not (false).
+     */
+    SkPDFString(const uint16_t* value, size_t len, bool wideChars);
     virtual ~SkPDFString();
 
     // The SkPDFObject interface.
@@ -176,12 +185,16 @@
                             bool indirect);
     virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
 
+    static SkString formatString(const char* input, size_t len);
+    static SkString formatString(const uint16_t* input, size_t len,
+                                 bool wideChars);
 private:
     static const size_t kMaxLen = 65535;
 
     const SkString fValue;
 
-    SkString formatString(const SkString& input);
+    static SkString doFormatString(const void* input, size_t len,
+                                 bool wideInput, bool wideOutput);
 };
 
 /** \class SkPDFName