• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright 2014 Google Inc.
3   *
4   * Use of this source code is governed by a BSD-style license that can be
5   * found in the LICENSE file.
6   */
7  
8  #include "include/core/SkTypeface.h"
9  #include "include/private/SkTo.h"
10  #include "src/core/SkFontPriv.h"
11  #include "src/core/SkReadBuffer.h"
12  #include "src/core/SkWriteBuffer.h"
13  
14  // packed int at the beginning of the serialized font:
15  //
16  //  control_bits:8 size_as_byte:8 flags:12 edging:2 hinting:2
17  
18  enum {
19      kSize_Is_Byte_Bit   = 1 << 31,
20      kHas_ScaleX_Bit     = 1 << 30,
21      kHas_SkewX_Bit      = 1 << 29,
22      kHas_Typeface_Bit   = 1 << 28,
23  
24      kShift_for_Size     = 16,
25      kMask_For_Size      = 0xFF,
26  
27      kShift_For_Flags    = 4,
28      kMask_For_Flags     = 0xFFF,
29  
30      kShift_For_Edging   = 2,
31      kMask_For_Edging    = 0x3,
32  
33      kShift_For_Hinting  = 0,
34      kMask_For_Hinting   = 0x3
35  };
36  
scalar_is_byte(SkScalar x)37  static bool scalar_is_byte(SkScalar x) {
38      int ix = (int)x;
39      return ix == x && ix >= 0 && ix <= kMask_For_Size;
40  }
41  
Flatten(const SkFont & font,SkWriteBuffer & buffer)42  void SkFontPriv::Flatten(const SkFont& font, SkWriteBuffer& buffer) {
43      SkASSERT(font.fFlags <= SkFont::kAllFlags);
44      SkASSERT((font.fFlags & ~kMask_For_Flags) == 0);
45      SkASSERT((font.fEdging & ~kMask_For_Edging) == 0);
46      SkASSERT((font.fHinting & ~kMask_For_Hinting) == 0);
47  
48      uint32_t packed = 0;
49      packed |= font.fFlags << kShift_For_Flags;
50      packed |= font.fEdging << kShift_For_Edging;
51      packed |= font.fHinting << kShift_For_Hinting;
52  
53      if (scalar_is_byte(font.fSize)) {
54          packed |= kSize_Is_Byte_Bit;
55          packed |= (int)font.fSize << kShift_for_Size;
56      }
57      if (font.fScaleX != 1) {
58          packed |= kHas_ScaleX_Bit;
59      }
60      if (font.fSkewX != 0) {
61          packed |= kHas_SkewX_Bit;
62      }
63      if (font.fTypeface) {
64          packed |= kHas_Typeface_Bit;
65      }
66  
67      buffer.write32(packed);
68      if (!(packed & kSize_Is_Byte_Bit)) {
69          buffer.writeScalar(font.fSize);
70      }
71      if (packed & kHas_ScaleX_Bit) {
72          buffer.writeScalar(font.fScaleX);
73      }
74      if (packed & kHas_SkewX_Bit) {
75          buffer.writeScalar(font.fSkewX);
76      }
77      if (packed & kHas_Typeface_Bit) {
78          buffer.writeTypeface(font.fTypeface.get());
79      }
80  }
81  
Unflatten(SkFont * font,SkReadBuffer & buffer)82  bool SkFontPriv::Unflatten(SkFont* font, SkReadBuffer& buffer) {
83      const uint32_t packed = buffer.read32();
84  
85      if (packed & kSize_Is_Byte_Bit) {
86          font->fSize = (packed >> kShift_for_Size) & kMask_For_Size;
87      } else {
88          font->fSize = buffer.readScalar();
89      }
90      if (packed & kHas_ScaleX_Bit) {
91          font->fScaleX = buffer.readScalar();
92      }
93      if (packed & kHas_SkewX_Bit) {
94          font->fSkewX = buffer.readScalar();
95      }
96      if (packed & kHas_Typeface_Bit) {
97          font->fTypeface = buffer.readTypeface();
98      }
99  
100      SkASSERT(SkFont::kAllFlags <= kMask_For_Flags);
101      // we & with kAllFlags, to clear out any unknown flag bits
102      font->fFlags = SkToU8((packed >> kShift_For_Flags) & SkFont::kAllFlags);
103  
104      unsigned edging = (packed >> kShift_For_Edging) & kMask_For_Edging;
105      if (edging > (unsigned)SkFont::Edging::kSubpixelAntiAlias) {
106          edging = 0;
107      }
108      font->fEdging = SkToU8(edging);
109  
110      unsigned hinting = (packed >> kShift_For_Hinting) & kMask_For_Hinting;
111      if (hinting > (unsigned)SkFontHinting::kFull) {
112          hinting = 0;
113      }
114      font->fHinting = SkToU8(hinting);
115  
116      return buffer.isValid();
117  }
118