diff options
Diffstat (limited to 'gfx/skia/skia/src/core/SkFont_serial.cpp')
-rw-r--r-- | gfx/skia/skia/src/core/SkFont_serial.cpp | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/core/SkFont_serial.cpp b/gfx/skia/skia/src/core/SkFont_serial.cpp new file mode 100644 index 0000000000..0ed5c16756 --- /dev/null +++ b/gfx/skia/skia/src/core/SkFont_serial.cpp @@ -0,0 +1,117 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/core/SkTypeface.h" +#include "include/private/base/SkTo.h" +#include "src/core/SkFontPriv.h" +#include "src/core/SkReadBuffer.h" +#include "src/core/SkWriteBuffer.h" + +// packed int at the beginning of the serialized font: +// +// control_bits:8 size_as_byte:8 flags:12 edging:2 hinting:2 + +enum { + kSize_Is_Byte_Bit = 1 << 31, + kHas_ScaleX_Bit = 1 << 30, + kHas_SkewX_Bit = 1 << 29, + kHas_Typeface_Bit = 1 << 28, + + kShift_for_Size = 16, + kMask_For_Size = 0xFF, + + kShift_For_Flags = 4, + kMask_For_Flags = 0xFFF, + + kShift_For_Edging = 2, + kMask_For_Edging = 0x3, + + kShift_For_Hinting = 0, + kMask_For_Hinting = 0x3 +}; + +static bool scalar_is_byte(SkScalar x) { + int ix = (int)x; + return ix == x && ix >= 0 && ix <= kMask_For_Size; +} + +void SkFontPriv::Flatten(const SkFont& font, SkWriteBuffer& buffer) { + SkASSERT(font.fFlags <= SkFont::kAllFlags); + SkASSERT((font.fFlags & ~kMask_For_Flags) == 0); + SkASSERT((font.fEdging & ~kMask_For_Edging) == 0); + SkASSERT((font.fHinting & ~kMask_For_Hinting) == 0); + + uint32_t packed = 0; + packed |= font.fFlags << kShift_For_Flags; + packed |= font.fEdging << kShift_For_Edging; + packed |= font.fHinting << kShift_For_Hinting; + + if (scalar_is_byte(font.fSize)) { + packed |= kSize_Is_Byte_Bit; + packed |= (int)font.fSize << kShift_for_Size; + } + if (font.fScaleX != 1) { + packed |= kHas_ScaleX_Bit; + } + if (font.fSkewX != 0) { + packed |= kHas_SkewX_Bit; + } + if (font.fTypeface) { + packed |= kHas_Typeface_Bit; + } + + buffer.write32(packed); + if (!(packed & kSize_Is_Byte_Bit)) { + buffer.writeScalar(font.fSize); + } + if (packed & kHas_ScaleX_Bit) { + buffer.writeScalar(font.fScaleX); + } + if (packed & kHas_SkewX_Bit) { + buffer.writeScalar(font.fSkewX); + } + if (packed & kHas_Typeface_Bit) { + buffer.writeTypeface(font.fTypeface.get()); + } +} + +bool SkFontPriv::Unflatten(SkFont* font, SkReadBuffer& buffer) { + const uint32_t packed = buffer.read32(); + + if (packed & kSize_Is_Byte_Bit) { + font->fSize = (packed >> kShift_for_Size) & kMask_For_Size; + } else { + font->fSize = buffer.readScalar(); + } + if (packed & kHas_ScaleX_Bit) { + font->fScaleX = buffer.readScalar(); + } + if (packed & kHas_SkewX_Bit) { + font->fSkewX = buffer.readScalar(); + } + if (packed & kHas_Typeface_Bit) { + font->fTypeface = buffer.readTypeface(); + } + + SkASSERT(SkFont::kAllFlags <= kMask_For_Flags); + // we & with kAllFlags, to clear out any unknown flag bits + font->fFlags = SkToU8((packed >> kShift_For_Flags) & SkFont::kAllFlags); + + unsigned edging = (packed >> kShift_For_Edging) & kMask_For_Edging; + if (edging > (unsigned)SkFont::Edging::kSubpixelAntiAlias) { + edging = 0; + } + font->fEdging = SkToU8(edging); + + unsigned hinting = (packed >> kShift_For_Hinting) & kMask_For_Hinting; + if (hinting > (unsigned)SkFontHinting::kFull) { + hinting = 0; + } + font->fHinting = SkToU8(hinting); + + return buffer.isValid(); +} |