Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / ports / SkFontHost_win.cpp
index d0af011..47a29c0 100755 (executable)
@@ -16,6 +16,7 @@
 #include "SkGlyph.h"
 #include "SkHRESULT.h"
 #include "SkMaskGamma.h"
+#include "SkMatrix22.h"
 #include "SkOTTable_maxp.h"
 #include "SkOTTable_name.h"
 #include "SkOTUtils.h"
@@ -152,6 +153,10 @@ static inline FIXED SkScalarToFIXED(SkScalar x) {
     return SkFixedToFIXED(SkScalarToFixed(x));
 }
 
+static inline SkScalar SkFIXEDToScalar(FIXED x) {
+    return SkFixedToScalar(SkFIXEDToFixed(x));
+}
+
 static unsigned calculateGlyphCount(HDC hdc, const LOGFONT& lf) {
     TEXTMETRIC textMetric;
     if (0 == GetTextMetrics(hdc, &textMetric)) {
@@ -275,21 +280,11 @@ protected:
     virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
     virtual size_t onGetTableData(SkFontTableTag, size_t offset,
                                   size_t length, void* data) const SK_OVERRIDE;
-    virtual SkTypeface* onRefMatchingStyle(Style) const SK_OVERRIDE;
 };
 
 class FontMemResourceTypeface : public LogFontTypeface {
 public:
     /**
-     *  Takes ownership of fontMemResource.
-     */
-    FontMemResourceTypeface(SkTypeface::Style style, SkFontID fontID, const LOGFONT& lf, HANDLE fontMemResource) :
-        LogFontTypeface(style, fontID, lf, true), fFontMemResource(fontMemResource) {
-    }
-
-    HANDLE fFontMemResource;
-
-    /**
      *  The created FontMemResourceTypeface takes ownership of fontMemResource.
      */
     static FontMemResourceTypeface* Create(const LOGFONT& lf, HANDLE fontMemResource) {
@@ -306,6 +301,15 @@ protected:
     }
 
 private:
+    /**
+     *  Takes ownership of fontMemResource.
+     */
+    FontMemResourceTypeface(SkTypeface::Style style, SkFontID fontID, const LOGFONT& lf, HANDLE fontMemResource) :
+        LogFontTypeface(style, fontID, lf, true), fFontMemResource(fontMemResource) {
+    }
+
+    HANDLE fFontMemResource;
+
     typedef LogFontTypeface INHERITED;
 };
 
@@ -584,7 +588,7 @@ private:
      */
     SkMatrix     fG_inv;
     enum Type {
-        kTrueType_Type, kBitmap_Type,
+        kTrueType_Type, kBitmap_Type, kLine_Type
     } fType;
     TEXTMETRIC fTM;
 };
@@ -633,34 +637,9 @@ SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
     fRec.getSingleMatrix(&A);
     A.mapPoints(&h, 1);
 
-    // Find the Given's matrix [[c, -s],[s, c]] which rotates the baseline vector h
-    // (where the baseline is mapped to) to the positive horizontal axis.
-    const SkScalar& a = h.fX;
-    const SkScalar& b = h.fY;
-    SkScalar c, s;
-    if (0 == b) {
-        c = SkDoubleToScalar(_copysign(SK_Scalar1, a));
-        s = 0;
-    } else if (0 == a) {
-        c = 0;
-        s = SkDoubleToScalar(-_copysign(SK_Scalar1, b));
-    } else if (SkScalarAbs(b) > SkScalarAbs(a)) {
-        SkScalar t = a / b;
-        SkScalar u = SkDoubleToScalar(_copysign(SkScalarSqrt(SK_Scalar1 + t*t), b));
-        s = -1 / u;
-        c = -s * t;
-    } else {
-        SkScalar t = b / a;
-        SkScalar u = SkDoubleToScalar(_copysign(SkScalarSqrt(SK_Scalar1 + t*t), a));
-        c = 1 / u;
-        s = -c * t;
-    }
-
-    // G is the Given's Matrix for A (rotational matrix such that GA[0][1] == 0).
+    // G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0).
     SkMatrix G;
-    G.setAll(c, -s, 0,
-             s,  c, 0,
-             0,  0, SkScalarToPersp(SK_Scalar1));
+    SkComputeGivensRotation(h, &G);
 
     // GA is the matrix A with rotation removed.
     SkMatrix GA(G);
@@ -718,21 +697,24 @@ SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
             fTM.tmPitchAndFamily = TMPF_TRUETYPE;
         }
     }
-    // Used a logfont on a memory context, should never get a device font.
-    // Therefore all TMPF_DEVICE will be PostScript fonts.
-
-    // If TMPF_VECTOR is set, one of TMPF_TRUETYPE or TMPF_DEVICE must be set,
-    // otherwise we have a vector FON, which we don't support.
-    // This was determined by testing with Type1 PFM/PFB and OpenTypeCFF OTF,
-    // as well as looking at Wine bugs and sources.
-    SkASSERT(!(fTM.tmPitchAndFamily & TMPF_VECTOR) ||
-              (fTM.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_DEVICE)));
 
     XFORM xform;
     if (fTM.tmPitchAndFamily & TMPF_VECTOR) {
-        // Truetype or PostScript.
-        // Stroked FON also gets here (TMPF_VECTOR), but we don't handle it.
-        fType = SkScalerContext_GDI::kTrueType_Type;
+        // Used a logfont on a memory context, should never get a device font.
+        // Therefore all TMPF_DEVICE will be PostScript fonts.
+
+        // If TMPF_VECTOR is set, one of TMPF_TRUETYPE or TMPF_DEVICE means that
+        // we have an outline font. Otherwise we have a vector FON, which is
+        // scalable, but not an outline font.
+        // This was determined by testing with Type1 PFM/PFB and
+        // OpenTypeCFF OTF, as well as looking at Wine bugs and sources.
+        if (fTM.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_DEVICE)) {
+            // Truetype or PostScript.
+            fType = SkScalerContext_GDI::kTrueType_Type;
+        } else {
+            // Stroked FON.
+            fType = SkScalerContext_GDI::kLine_Type;
+        }
 
         // fPost2x2 is column-major, left handed (y down).
         // XFORM 2x2 is row-major, left handed (y down).
@@ -834,8 +816,8 @@ uint16_t SkScalerContext_GDI::generateCharToGlyph(SkUnichar utf32) {
          *
          *  When GGI_MARK_NONEXISTING_GLYPHS is not specified and a character does not map to a
          *  glyph, then the 'default character's glyph is returned instead. The 'default character'
-         *  is available in fTM.tmDefaultChar. FON fonts have adefault character, and there exists a
-         *  usDefaultChar in the 'OS/2' table, version 2 and later. If there is no
+         *  is available in fTM.tmDefaultChar. FON fonts have a default character, and there exists
+         *  usDefaultChar in the 'OS/2' table, version 2 and later. If there is no
          *  'default character' specified by the font, then often the first character found is used.
          *
          *  When GGI_MARK_NONEXISTING_GLYPHS is specified and a character does not map to a glyph,
@@ -846,7 +828,11 @@ uint16_t SkScalerContext_GDI::generateCharToGlyph(SkUnichar utf32) {
         DWORD result = GetGlyphIndicesW(fDDC, utf16, 1, &index, GGI_MARK_NONEXISTING_GLYPHS);
         if (result == GDI_ERROR
             || 0xFFFF == index
-            || (0x1F == index && fType == SkScalerContext_GDI::kBitmap_Type /*&& winVer < Vista */))
+            || (0x1F == index &&
+               (fType == SkScalerContext_GDI::kBitmap_Type ||
+                fType == SkScalerContext_GDI::kLine_Type)
+               /*&& winVer < Vista */)
+           )
         {
             index = 0;
         }
@@ -886,7 +872,7 @@ void SkScalerContext_GDI::generateAdvance(SkGlyph* glyph) {
 void SkScalerContext_GDI::generateMetrics(SkGlyph* glyph) {
     SkASSERT(fDDC);
 
-    if (fType == SkScalerContext_GDI::kBitmap_Type) {
+    if (fType == SkScalerContext_GDI::kBitmap_Type || fType == SkScalerContext_GDI::kLine_Type) {
         SIZE size;
         WORD glyphs = glyph->getGlyphID(0);
         if (0 == GetTextExtentPointI(fDDC, &glyphs, 1, &size)) {
@@ -897,12 +883,30 @@ void SkScalerContext_GDI::generateMetrics(SkGlyph* glyph) {
         glyph->fHeight = SkToS16(size.cy);
 
         glyph->fTop = SkToS16(-fTM.tmAscent);
+        // Bitmap FON cannot underhang, but vector FON may.
+        // There appears no means of determining underhang of vector FON.
         glyph->fLeft = SkToS16(0);
         glyph->fAdvanceX = SkIntToFixed(glyph->fWidth);
         glyph->fAdvanceY = 0;
 
+        // Vector FON will transform nicely, but bitmap FON do not.
+        if (fType == SkScalerContext_GDI::kLine_Type) {
+            SkRect bounds = SkRect::MakeXYWH(glyph->fLeft, glyph->fTop,
+                                             glyph->fWidth, glyph->fHeight);
+            SkMatrix m;
+            m.setAll(SkFIXEDToScalar(fMat22.eM11), -SkFIXEDToScalar(fMat22.eM21), 0,
+                     -SkFIXEDToScalar(fMat22.eM12), SkFIXEDToScalar(fMat22.eM22), 0,
+                     0,  0, SkScalarToPersp(SK_Scalar1));
+            m.mapRect(&bounds);
+            bounds.roundOut();
+            glyph->fLeft = SkScalarTruncToInt(bounds.fLeft);
+            glyph->fTop = SkScalarTruncToInt(bounds.fTop);
+            glyph->fWidth = SkScalarTruncToInt(bounds.width());
+            glyph->fHeight = SkScalarTruncToInt(bounds.height());
+        }
+
         // Apply matrix to advance.
-        glyph->fAdvanceY = SkFixedMul(SkFIXEDToFixed(fMat22.eM21), glyph->fAdvanceX);
+        glyph->fAdvanceY = SkFixedMul(-SkFIXEDToFixed(fMat22.eM12), glyph->fAdvanceX);
         glyph->fAdvanceX = SkFixedMul(SkFIXEDToFixed(fMat22.eM11), glyph->fAdvanceX);
 
         return;
@@ -989,7 +993,7 @@ void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint:
     SkASSERT(fDDC);
 
 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
-    if (fType == SkScalerContext_GDI::kBitmap_Type) {
+    if (fType == SkScalerContext_GDI::kBitmap_Type || fType == SkScalerContext_GDI::kLine_Type) {
 #endif
         if (mx) {
             mx->fTop = SkIntToScalar(-fTM.tmAscent);
@@ -1033,6 +1037,11 @@ void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint:
         mx->fDescent = SkIntToScalar(-otm.otmDescent);
         mx->fBottom = SkIntToScalar(otm.otmrcFontBox.right);
         mx->fLeading = SkIntToScalar(otm.otmLineGap);
+        mx->fUnderlineThickness = SkIntToScalar(otm.otmsUnderscoreSize);
+        mx->fUnderlinePosition = -SkIntToScalar(otm.otmsUnderscorePosition);
+
+        mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+        mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
     }
 
     if (my) {
@@ -1046,6 +1055,11 @@ void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint:
         my->fMaxCharWidth = SkIntToScalar(otm.otmTextMetrics.tmMaxCharWidth);
         my->fXMin = SkIntToScalar(otm.otmrcFontBox.left);
         my->fXMax = SkIntToScalar(otm.otmrcFontBox.right);
+        my->fUnderlineThickness = SkIntToScalar(otm.otmsUnderscoreSize);
+        my->fUnderlinePosition = -SkIntToScalar(otm.otmsUnderscorePosition);
+
+        my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+        my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
 #endif
         my->fXHeight = SkIntToScalar(otm.otmsXHeight);
 
@@ -1066,7 +1080,7 @@ static void build_power_table(uint8_t table[], float ee) {
     for (int i = 0; i < 256; i++) {
         float x = i / 255.f;
         x = sk_float_pow(x, ee);
-        int xx = SkScalarRound(SkFloatToScalar(x * 255));
+        int xx = SkScalarRoundToInt(x * 255);
         table[i] = SkToU8(xx);
     }
 }
@@ -2154,6 +2168,7 @@ private:
     HFONT fFont;
     HFONT fSavefont;
 };
+#define SkAutoHDC(...) SK_REQUIRE_LOCAL_VAR(SkAutoHDC)
 
 int LogFontTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
                                      uint16_t userGlyphs[], int glyphCount) const
@@ -2391,7 +2406,7 @@ void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const {
     }
 
     unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
-                                  SkScalerContext::kAutohinting_Flag |
+                                  SkScalerContext::kForceAutohinting_Flag |
                                   SkScalerContext::kEmbeddedBitmapText_Flag |
                                   SkScalerContext::kEmbolden_Flag |
                                   SkScalerContext::kLCD_BGROrder_Flag |
@@ -2436,26 +2451,6 @@ void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const {
     }
 }
 
-static SkTypeface* create_typeface(const SkTypeface* familyFace,
-                                   const char familyName[],
-                                   unsigned styleBits) {
-    LOGFONT lf;
-    if (NULL == familyFace && NULL == familyName) {
-        lf = get_default_font();
-    } else if (familyFace) {
-        LogFontTypeface* face = (LogFontTypeface*)familyFace;
-        lf = face->fLogFont;
-    } else {
-        logfont_for_name(familyName, &lf);
-    }
-    setStyle(&lf, (SkTypeface::Style)styleBits);
-    return SkCreateTypefaceFromLOGFONT(lf);
-}
-
-SkTypeface* LogFontTypeface::onRefMatchingStyle(Style style) const {
-    return create_typeface(this, NULL, style);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "SkFontMgr.h"
@@ -2552,21 +2547,21 @@ public:
     }
 
 protected:
-    virtual int onCountFamilies() SK_OVERRIDE {
+    virtual int onCountFamilies() const SK_OVERRIDE {
         return fLogFontArray.count();
     }
 
-    virtual void onGetFamilyName(int index, SkString* familyName) SK_OVERRIDE {
+    virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERRIDE {
         SkASSERT((unsigned)index < (unsigned)fLogFontArray.count());
         tchar_to_skstring(fLogFontArray[index].elfLogFont.lfFaceName, familyName);
     }
 
-    virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE {
+    virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE {
         SkASSERT((unsigned)index < (unsigned)fLogFontArray.count());
         return SkNEW_ARGS(SkFontStyleSetGDI, (fLogFontArray[index].elfLogFont.lfFaceName));
     }
 
-    virtual SkFontStyleSet* onMatchFamily(const char familyName[]) SK_OVERRIDE {
+    virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE {
         if (NULL == familyName) {
             familyName = "";    // do we need this check???
         }
@@ -2576,39 +2571,46 @@ protected:
     }
 
     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
-                                           const SkFontStyle& fontstyle) SK_OVERRIDE {
+                                           const SkFontStyle& fontstyle) const SK_OVERRIDE {
         // could be in base impl
         SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
         return sset->matchStyle(fontstyle);
     }
 
     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
-                                         const SkFontStyle& fontstyle) SK_OVERRIDE {
+                                         const SkFontStyle& fontstyle) const SK_OVERRIDE {
         // could be in base impl
         SkString familyName;
         ((LogFontTypeface*)familyMember)->getFamilyName(&familyName);
         return this->matchFamilyStyle(familyName.c_str(), fontstyle);
     }
 
-    virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) SK_OVERRIDE {
+    virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
         return create_from_stream(stream);
     }
 
-    virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) SK_OVERRIDE {
+    virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
         // could be in base impl
         SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
         return this->createFromStream(stream);
     }
 
-    virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) SK_OVERRIDE {
+    virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
         // could be in base impl
         SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
         return this->createFromStream(stream);
     }
 
     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
-                                               unsigned styleBits) SK_OVERRIDE {
-        return create_typeface(NULL, familyName, styleBits);
+                                               unsigned styleBits) const SK_OVERRIDE {
+        LOGFONT lf;
+        if (NULL == familyName) {
+            lf = get_default_font();
+        } else {
+            logfont_for_name(familyName, &lf);
+        }
+        setStyle(&lf, (SkTypeface::Style)styleBits);
+        return SkCreateTypefaceFromLOGFONT(lf);
     }
 
 private:
@@ -2617,25 +2619,6 @@ private:
 
 ///////////////////////////////////////////////////////////////////////////////
 
-#ifndef SK_FONTHOST_USES_FONTMGR
-
-SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
-                                       const char familyName[],
-                                       SkTypeface::Style styleBits) {
-    return create_typeface(familyFace, familyName, styleBits);
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
-    SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
-    return stream.get() ? CreateTypefaceFromStream(stream) : NULL;
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
-    return create_from_stream(stream);
-}
-
-#endif
-
 SkFontMgr* SkFontMgr_New_GDI() {
     return SkNEW(SkFontMgrGDI);
 }