19714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com/* 29714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com * Copyright 2012 Google Inc. 39714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com * 49714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com * Use of this source code is governed by a BSD-style license that can be 59714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com * found in the LICENSE file. 69714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com */ 79714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com 89714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com#include "SkFontDescriptor.h" 99714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com#include "SkStream.h" 10d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman#include <SkData.h> 119714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com 129714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.comenum { 133b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com // these must match the sfnt 'name' enums 149714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com kFontFamilyName = 0x01, 153b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com kFullName = 0x04, 163b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com kPostscriptName = 0x06, 17d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 183b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com // These count backwards from 0xFF, so as not to collide with the SFNT 193b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com // defines for names in its 'name' table. 20d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman kFontIndex = 0xFD, 213b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com kFontFileName = 0xFE, 223b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com kSentinel = 0xFF, 239714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com}; 249714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com 25d71b75757335393d9643a5b7a0f2769b6ba52fb6bungemanSkFontDescriptor::SkFontDescriptor(SkTypeface::Style style) : fFontIndex(0), fStyle(style) { } 269714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com 273b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.comstatic void read_string(SkStream* stream, SkString* string) { 28a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org const uint32_t length = SkToU32(stream->readPackedUInt()); 299714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com if (length > 0) { 303b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com string->resize(length); 313b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com stream->read(string->writable_str(), length); 329714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com } 339714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com} 349714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com 353b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.comstatic void write_string(SkWStream* stream, const SkString& string, 363b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com uint32_t id) { 379714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com if (!string.isEmpty()) { 389714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com stream->writePackedUInt(id); 399714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com stream->writePackedUInt(string.size()); 409714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com stream->write(string.c_str(), string.size()); 419714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com } 429714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com} 439714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com 44d71b75757335393d9643a5b7a0f2769b6ba52fb6bungemanstatic size_t read_uint(SkStream* stream) { 45d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman return stream->readPackedUInt(); 46d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman} 47d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman 48d71b75757335393d9643a5b7a0f2769b6ba52fb6bungemanstatic void write_uint(SkWStream* stream, size_t n, uint32_t id) { 49d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman stream->writePackedUInt(id); 50d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman stream->writePackedUInt(n); 51d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman} 52d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman 53d71b75757335393d9643a5b7a0f2769b6ba52fb6bungemanSkFontDescriptor::SkFontDescriptor(SkStream* stream) : fFontIndex(0) { 543b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com fStyle = (SkTypeface::Style)stream->readPackedUInt(); 559714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com 56d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman for (size_t id; (id = stream->readPackedUInt()) != kSentinel;) { 57d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman switch (id) { 583b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com case kFontFamilyName: 593b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com read_string(stream, &fFamilyName); 603b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com break; 613b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com case kFullName: 623b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com read_string(stream, &fFullName); 633b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com break; 643b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com case kPostscriptName: 653b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com read_string(stream, &fPostscriptName); 663b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com break; 67d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman case kFontIndex: 68d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman fFontIndex = read_uint(stream); 69d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman break; 703b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com case kFontFileName: 713b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com read_string(stream, &fFontFileName); 723b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com break; 739714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com default: 749714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com SkDEBUGFAIL("Unknown id used by a font descriptor"); 753b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com return; 769714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com } 779714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com } 78d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman 79d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman size_t length = stream->readPackedUInt(); 80d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman if (length > 0) { 81d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman SkAutoTUnref<SkData> data(SkData::NewUninitialized(length)); 82d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman if (stream->read(data->writable_data(), length) == length) { 83d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman fFontData.reset(SkNEW_ARGS(SkMemoryStream, (data))); 84d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman } 85d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman } 869714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com} 879714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com 889714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.comvoid SkFontDescriptor::serialize(SkWStream* stream) { 893b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com stream->writePackedUInt(fStyle); 909714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com 913b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com write_string(stream, fFamilyName, kFontFamilyName); 923b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com write_string(stream, fFullName, kFullName); 933b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com write_string(stream, fPostscriptName, kPostscriptName); 943b700f6929e093cb14cc0e4ef569e6f697c5a816reed@google.com write_string(stream, fFontFileName, kFontFileName); 95d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman if (fFontIndex) { 96d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman write_uint(stream, fFontIndex, kFontIndex); 97d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman } 989714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com 999714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com stream->writePackedUInt(kSentinel); 100d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman 101d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman if (fFontData) { 102d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman size_t length = fFontData->getLength(); 103d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman stream->writePackedUInt(length); 104d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman stream->writeStream(fFontData, length); 105d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman } else { 106d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman stream->writePackedUInt(0); 107d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman } 1089714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com} 109