xref: /aosp_15_r20/external/skia/src/core/SkFont_serial.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/SkFont.h"
9 #include "include/core/SkFontTypes.h"
10 #include "include/core/SkRefCnt.h"
11 #include "include/core/SkScalar.h"
12 #include "include/private/base/SkAssert.h"
13 #include "include/private/base/SkTo.h"
14 #include "src/core/SkFontPriv.h"
15 #include "src/core/SkReadBuffer.h"
16 #include "src/core/SkWriteBuffer.h"
17 
18 #include <cstdint>
19 
20 // packed int at the beginning of the serialized font:
21 //
22 //  control_bits:8 size_as_byte:8 flags:12 edging:2 hinting:2
23 
24 enum {
25     kSize_Is_Byte_Bit   = 1 << 31,
26     kHas_ScaleX_Bit     = 1 << 30,
27     kHas_SkewX_Bit      = 1 << 29,
28     kHas_Typeface_Bit   = 1 << 28,
29 
30     kShift_for_Size     = 16,
31     kMask_For_Size      = 0xFF,
32 
33     kShift_For_Flags    = 4,
34     kMask_For_Flags     = 0xFFF,
35 
36     kShift_For_Edging   = 2,
37     kMask_For_Edging    = 0x3,
38 
39     kShift_For_Hinting  = 0,
40     kMask_For_Hinting   = 0x3
41 };
42 
scalar_is_byte(SkScalar x)43 static bool scalar_is_byte(SkScalar x) {
44     int ix = (int)x;
45     return ix == x && ix >= 0 && ix <= kMask_For_Size;
46 }
47 
Flatten(const SkFont & font,SkWriteBuffer & buffer)48 void SkFontPriv::Flatten(const SkFont& font, SkWriteBuffer& buffer) {
49     SkASSERT(font.fFlags <= SkFont::kAllFlags);
50     SkASSERT((font.fFlags & ~kMask_For_Flags) == 0);
51     SkASSERT((font.fEdging & ~kMask_For_Edging) == 0);
52     SkASSERT((font.fHinting & ~kMask_For_Hinting) == 0);
53 
54     uint32_t packed = 0;
55     packed |= font.fFlags << kShift_For_Flags;
56     packed |= font.fEdging << kShift_For_Edging;
57     packed |= font.fHinting << kShift_For_Hinting;
58 
59     if (scalar_is_byte(font.fSize)) {
60         packed |= kSize_Is_Byte_Bit;
61         packed |= (int)font.fSize << kShift_for_Size;
62     }
63     if (font.fScaleX != 1) {
64         packed |= kHas_ScaleX_Bit;
65     }
66     if (font.fSkewX != 0) {
67         packed |= kHas_SkewX_Bit;
68     }
69     if (font.fTypeface) {
70         packed |= kHas_Typeface_Bit;
71     }
72 
73     buffer.write32(packed);
74     if (!(packed & kSize_Is_Byte_Bit)) {
75         buffer.writeScalar(font.fSize);
76     }
77     if (packed & kHas_ScaleX_Bit) {
78         buffer.writeScalar(font.fScaleX);
79     }
80     if (packed & kHas_SkewX_Bit) {
81         buffer.writeScalar(font.fSkewX);
82     }
83     if (packed & kHas_Typeface_Bit) {
84         buffer.writeTypeface(font.fTypeface.get());
85     }
86 }
87 
Unflatten(SkFont * font,SkReadBuffer & buffer)88 bool SkFontPriv::Unflatten(SkFont* font, SkReadBuffer& buffer) {
89     const uint32_t packed = buffer.read32();
90 
91     if (packed & kSize_Is_Byte_Bit) {
92         font->fSize = (packed >> kShift_for_Size) & kMask_For_Size;
93     } else {
94         font->fSize = buffer.readScalar();
95     }
96     if (packed & kHas_ScaleX_Bit) {
97         font->fScaleX = buffer.readScalar();
98     }
99     if (packed & kHas_SkewX_Bit) {
100         font->fSkewX = buffer.readScalar();
101     }
102     if (packed & kHas_Typeface_Bit) {
103         font->setTypeface(buffer.readTypeface());
104     }
105 
106     SkASSERT(SkFont::kAllFlags <= kMask_For_Flags);
107     // we & with kAllFlags, to clear out any unknown flag bits
108     font->fFlags = SkToU8((packed >> kShift_For_Flags) & SkFont::kAllFlags);
109 
110     unsigned edging = (packed >> kShift_For_Edging) & kMask_For_Edging;
111     if (edging > (unsigned)SkFont::Edging::kSubpixelAntiAlias) {
112         edging = 0;
113     }
114     font->fEdging = SkToU8(edging);
115 
116     unsigned hinting = (packed >> kShift_For_Hinting) & kMask_For_Hinting;
117     if (hinting > (unsigned)SkFontHinting::kFull) {
118         hinting = 0;
119     }
120     font->fHinting = SkToU8(hinting);
121 
122     return buffer.isValid();
123 }
124