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